@hailin-zheng/editor-core 2.2.19 → 2.2.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index-cjs.js CHANGED
@@ -365,7 +365,9 @@ class BranchRenderObject extends RenderObject {
365
365
  if (index < 0) {
366
366
  throw new Error('为查找到当前元素');
367
367
  }
368
- if (child.parent === this) ;
368
+ if (child.parent === this) {
369
+ child.parent = null;
370
+ }
369
371
  this.children.splice(index, 1);
370
372
  }
371
373
  removeChildByIndex(index) {
@@ -800,6 +802,14 @@ class CommonUtil {
800
802
  }
801
803
  return val;
802
804
  }
805
+ static getKeyCombination(event) {
806
+ // 构建键盘组合字符串,包括修饰键
807
+ const modifiers = [event.ctrlKey ? "Ctrl" : "", event.shiftKey ? "Shift" : "", event.altKey ? "Alt" : "", event.metaKey ? "Meta" : ""].filter(Boolean).join("+");
808
+ // 根据修饰键的存在构建最终的键盘组合字符串
809
+ const key = event.key; // 直接使用 event.key 来获取按键实际字符
810
+ const keyCombination = modifiers.length > 0 ? `${modifiers}+${key}` : key;
811
+ return keyCombination;
812
+ }
803
813
  }
804
814
 
805
815
  const docOpsMap = new Map();
@@ -1278,6 +1288,7 @@ class Element {
1278
1288
  //加载完毕
1279
1289
  loaded;
1280
1290
  visibleExpr;
1291
+ effectExpr;
1281
1292
  attribute;
1282
1293
  _parent;
1283
1294
  get parent() {
@@ -1322,6 +1333,8 @@ class Element {
1322
1333
  this.cacheRender = null;
1323
1334
  this.unsubscribe(this);
1324
1335
  this.disposed = true;
1336
+ this.visibleExpr = null;
1337
+ this.effectExpr = null;
1325
1338
  }
1326
1339
  addEvent(event, handle, useCapture = false) {
1327
1340
  if (!this._eventMap) {
@@ -1413,24 +1426,41 @@ class LeafElement extends Element {
1413
1426
  return 1;
1414
1427
  }
1415
1428
  pubOnChange(selfChange) {
1416
- if (this.modifyFlag === exports.ModifyFlag.None) {
1417
- this.refreshView();
1418
- }
1419
- if (this.modifyFlag === exports.ModifyFlag.Track && selfChange === 'tracker') {
1420
- return;
1421
- }
1422
- if (this.modifyFlag === exports.ModifyFlag.Modify) {
1423
- return;
1424
- }
1425
- if (selfChange === 'tracker') {
1426
- if (this.modifyFlag === exports.ModifyFlag.None) {
1427
- this.modifyFlag = exports.ModifyFlag.Track;
1428
- }
1429
- }
1430
- else {
1431
- this.modifyFlag = exports.ModifyFlag.Modify;
1432
- }
1433
- this._onChangeEvent.next();
1429
+ invokeRefresh(this, selfChange);
1430
+ // if (this.modifyFlag === ModifyFlag.None) {
1431
+ // this.refreshView();
1432
+ // }
1433
+ // if (this.modifyFlag === ModifyFlag.Track && selfChange === 'tracker') {
1434
+ // return;
1435
+ // }
1436
+ // if (this.modifyFlag === ModifyFlag.Modify) {
1437
+ // return;
1438
+ // }
1439
+ // if (selfChange === 'tracker') {
1440
+ // if (this.modifyFlag === ModifyFlag.None) {
1441
+ // this.modifyFlag = ModifyFlag.Track;
1442
+ // }
1443
+ // } else {
1444
+ // this.modifyFlag = ModifyFlag.Modify;
1445
+ // }
1446
+ // this._onChangeEvent.next();
1447
+ }
1448
+ }
1449
+ function invokeRefresh(ele, type) {
1450
+ const doc = getParent(ele, (item) => item.type === 'doc');
1451
+ if (doc) {
1452
+ doc.invokeChange(ele, type);
1453
+ }
1454
+ }
1455
+ function getParent(child, predicate) {
1456
+ if (!child) {
1457
+ return null;
1458
+ }
1459
+ if (predicate(child)) {
1460
+ return child;
1461
+ }
1462
+ else {
1463
+ return getParent(child.parent, predicate);
1434
1464
  }
1435
1465
  }
1436
1466
  /**
@@ -1455,10 +1485,10 @@ class BranchElement extends Element {
1455
1485
  //const refSub = child.refreshSubject.subscribe((data) => {
1456
1486
  //this.refreshSubject.next(data);
1457
1487
  // });
1458
- const onChangeSub = child.onChangeSubject.subscribe((data) => {
1459
- this.pubOnChange('tracker');
1460
- });
1461
- this.addsubscribe(child, onChangeSub);
1488
+ // const onChangeSub = child.onChangeSubject.subscribe((data) => {
1489
+ // this.pubOnChange('tracker');
1490
+ // });
1491
+ //this.addsubscribe(child, onChangeSub);
1462
1492
  this.pubOnChange('self');
1463
1493
  }
1464
1494
  removeChild(child) {
@@ -1577,25 +1607,25 @@ class BranchElement extends Element {
1577
1607
  return null;
1578
1608
  }
1579
1609
  pubOnChange(selfChange) {
1580
- if (this.modifyFlag === exports.ModifyFlag.Track && selfChange === 'tracker') {
1581
- return;
1582
- }
1583
- if (this.modifyFlag === exports.ModifyFlag.Modify) {
1584
- return;
1585
- }
1586
- if (selfChange === 'tracker') {
1587
- if (this.modifyFlag === exports.ModifyFlag.None) {
1588
- this.modifyFlag = exports.ModifyFlag.Track;
1589
- }
1590
- }
1591
- else {
1592
- this.modifyFlag = exports.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();
1610
+ // if (this.modifyFlag === ModifyFlag.Track && selfChange === 'tracker') {
1611
+ // return;
1612
+ // }
1613
+ // if (this.modifyFlag === ModifyFlag.Modify) {
1614
+ // return;
1615
+ // }
1616
+ // if (selfChange === 'tracker') {
1617
+ // if (this.modifyFlag === ModifyFlag.None) {
1618
+ // this.modifyFlag = ModifyFlag.Track;
1619
+ // }
1620
+ // } else {
1621
+ // this.modifyFlag = ModifyFlag.Modify;
1622
+ // //clearChildrenRenderCache(this);
1623
+ // for (let i = 0; i < this.length; i++) {
1624
+ // this.getChild(i).pubOnChange('to-child')
1625
+ // }
1626
+ // }
1627
+ // this._onChangeEvent.next();
1628
+ invokeRefresh(this, selfChange);
1599
1629
  }
1600
1630
  }
1601
1631
  function clearChildrenRenderCache(ele) {
@@ -1787,8 +1817,6 @@ class ViewOptions {
1787
1817
  trackInsColor = '#ff4d4f';
1788
1818
  //删除-留痕块文本颜色
1789
1819
  trackDelColor = '#000';
1790
- showLineRect;
1791
- showCharRect;
1792
1820
  showTabChar;
1793
1821
  showSpaceChar;
1794
1822
  showLineBreak;
@@ -1796,7 +1824,6 @@ class ViewOptions {
1796
1824
  devMode = false;
1797
1825
  showParaSymbol = true;
1798
1826
  showDebug;
1799
- resourceMode = 'immediate';
1800
1827
  secretBrowse = false;
1801
1828
  //中文版式,处理中文换行;前置标点和后置标点
1802
1829
  chineseLayout = true;
@@ -1829,7 +1856,7 @@ class ViewOptions {
1829
1856
  return;
1830
1857
  }
1831
1858
  this._fullPageView = value;
1832
- this.onChange.next('force');
1859
+ this.onChange.next();
1833
1860
  }
1834
1861
  //毫米和像素的转换比
1835
1862
  mmToPixelsRatio = 3.7795001220703126;
@@ -1878,7 +1905,7 @@ class ViewOptions {
1878
1905
  return;
1879
1906
  }
1880
1907
  this._showTrackChanges = value;
1881
- this.onChange.next('force');
1908
+ this.onChange.next();
1882
1909
  }
1883
1910
  get showTrackChangesTip() {
1884
1911
  return this._showTrackChangesTip;
@@ -1888,7 +1915,7 @@ class ViewOptions {
1888
1915
  return;
1889
1916
  }
1890
1917
  this._showTrackChangesTip = value;
1891
- this.onChange.next('force');
1918
+ this.onChange.next();
1892
1919
  }
1893
1920
  //医嘱打印模式,文字行模式,将表格多行对象转换为多个表格行对象
1894
1921
  textRowLineMode = false;
@@ -2958,7 +2985,7 @@ class DataDecorateElement extends LeafElement {
2958
2985
  }
2959
2986
  }
2960
2987
  });
2961
- this.disableClick = !isPrefix;
2988
+ //this.disableClick = !isPrefix;
2962
2989
  this.isDecorate = true;
2963
2990
  }
2964
2991
  createRenderObject(data) {
@@ -3064,6 +3091,9 @@ function parser(code, objects) {
3064
3091
  if (child.type === 'Identifier') {
3065
3092
  const identifierName = child['name'];
3066
3093
  if (identifierName.startsWith('$')) {
3094
+ //获取对象为"CallExpression", "MemberExpression"获取属性,例如$1.value
3095
+ parent?.type;
3096
+ `getObject('${identifierName.slice(1)})`;
3067
3097
  child['name'] = `getObject('${identifierName.slice(1)}').value`;
3068
3098
  objects?.push(identifierName.slice(1));
3069
3099
  }
@@ -3090,6 +3120,11 @@ function parser(code, objects) {
3090
3120
  }
3091
3121
  }
3092
3122
  });
3123
+ if (objects) {
3124
+ const set = new Set(objects);
3125
+ objects.length = 0;
3126
+ objects.push(...set);
3127
+ }
3093
3128
  return astring.generate(node);
3094
3129
  }
3095
3130
  //判断代码的语句,如果最后一个语句不是return,那么加上return
@@ -3655,6 +3690,48 @@ class DocumentElement extends BlockContainerElement {
3655
3690
  }
3656
3691
  }
3657
3692
  }
3693
+ onRefreshEvent = new Subject();
3694
+ /**
3695
+ * 元素内容或者属性发生改变,需要根据当前节点所在的树路径,设置脏标记,同时触发渲染
3696
+ * @param ele
3697
+ */
3698
+ invokeChange(ele) {
3699
+ const parents = ElementUtil.getParentElements(ele);
3700
+ const pubLeafEle = (ele, eleChangeType) => {
3701
+ if (ele.modifyFlag === exports.ModifyFlag.Track && eleChangeType === 'tracker') {
3702
+ return;
3703
+ }
3704
+ if (ele.modifyFlag === exports.ModifyFlag.Modify) {
3705
+ return;
3706
+ }
3707
+ if (eleChangeType === 'tracker') {
3708
+ if (ele.modifyFlag === exports.ModifyFlag.None) {
3709
+ ele.modifyFlag = exports.ModifyFlag.Track;
3710
+ }
3711
+ }
3712
+ else {
3713
+ ele.modifyFlag = exports.ModifyFlag.Modify;
3714
+ if (ele instanceof BranchElement) {
3715
+ for (let i = 0; i < ele.length; i++) {
3716
+ const child = ele.getChild(i);
3717
+ if (child instanceof LeafElement) {
3718
+ pubLeafEle(child, 'to-child');
3719
+ }
3720
+ else if (child instanceof BranchElement) {
3721
+ pubLeafEle(child, 'to-child');
3722
+ }
3723
+ //this.getChild(i).pubOnChange('to-child')
3724
+ }
3725
+ }
3726
+ }
3727
+ };
3728
+ pubLeafEle(ele, 'self');
3729
+ for (let i = 1; i < parents.length; i++) {
3730
+ const parent = parents[i];
3731
+ pubLeafEle(parent, 'tracker');
3732
+ }
3733
+ this.onRefreshEvent.next();
3734
+ }
3658
3735
  }
3659
3736
  class DocumentRenderObject extends BlockContainerRenderObject {
3660
3737
  constructor(ele) {
@@ -4056,7 +4133,7 @@ class DataElementInlineGroup extends InlineGroupInputElement {
4056
4133
  }
4057
4134
  parserExpress;
4058
4135
  /**
4059
- * 解析可见性表达式
4136
+ * 解析表达式
4060
4137
  * @param ele
4061
4138
  * @param execute
4062
4139
  * @private
@@ -4075,6 +4152,11 @@ class DataElementInlineGroup extends InlineGroupInputElement {
4075
4152
  const depEleMap = new Map();
4076
4153
  let compliedCode = parser(this.props.expression, depIdItems);
4077
4154
  compliedCode = addReturn(compliedCode);
4155
+ this.parserExpress = {
4156
+ compliedCode,
4157
+ func: new Function(`with(this){ ${compliedCode} }`),
4158
+ depItems: depEleMap
4159
+ };
4078
4160
  if (depIdItems.length) {
4079
4161
  depIdItems.forEach(dep => {
4080
4162
  const refCtx = execute.getObject(dep);
@@ -4084,19 +4166,34 @@ class DataElementInlineGroup extends InlineGroupInputElement {
4084
4166
  //当前有可能是checkbox数组
4085
4167
  const refEles = Array.isArray(refEle) ? refEle : [refEle];
4086
4168
  reactiveMode && refEles.forEach(item => {
4169
+ //避免死循环调用
4170
+ if (item === this) {
4171
+ return;
4172
+ }
4087
4173
  //求值依赖元素更改的时候,发布当前元素重新计算的指令
4088
4174
  item.onChangeSubject.subscribe(() => {
4089
- this.pubOnChange('self');
4175
+ //this.pubOnChange('self');
4176
+ try {
4177
+ data.onNextView(() => {
4178
+ //当前元素可能被删除
4179
+ const func = this.parserExpress.func;
4180
+ if (!func) {
4181
+ return;
4182
+ }
4183
+ const tempExecuter = execute.create();
4184
+ tempExecuter.setCurrentCtx(this, this.parserExpress.depItems);
4185
+ const fn = func.bind(tempExecuter);
4186
+ fn();
4187
+ });
4188
+ }
4189
+ catch (e) {
4190
+ console.error(e, "表达式执行出错", this.parserExpress.compliedCode);
4191
+ }
4090
4192
  });
4091
4193
  });
4092
4194
  }
4093
4195
  });
4094
4196
  }
4095
- this.parserExpress = {
4096
- compliedCode,
4097
- func: new Function(`with(this){ ${compliedCode} }`),
4098
- depItems: depEleMap
4099
- };
4100
4197
  }
4101
4198
  catch (e) {
4102
4199
  console.error('解析表达式出错,parseEleExpression', this.props.expression);
@@ -4240,7 +4337,11 @@ function exportDataEleDecoratorSVG$1(event, r) {
4240
4337
  if (['all', 'outline'].includes(mode)) {
4241
4338
  color = event.options.dataEleOutlineColor;
4242
4339
  const verOffset = 0;
4243
- const renderPosMap = getCurrentParaGroupRenders(r).map(item => ({ pos: getRenderPosToDoc(item), render: item }));
4340
+ const currParaGroupRenders = getCurrentParaGroupRenders(r);
4341
+ if (currParaGroupRenders.indexOf(r) !== 0) {
4342
+ return;
4343
+ }
4344
+ const renderPosMap = currParaGroupRenders.map(item => ({ pos: getRenderPosToDoc(item), render: item }));
4244
4345
  if (renderPosMap.length > 1) {
4245
4346
  const secondGroupRenderPos = renderPosMap[1].pos;
4246
4347
  if (secondGroupRenderPos.x + renderPosMap[1].render.rect.width > event.relativePagePos.x) {
@@ -4547,20 +4648,25 @@ class PSymbolRenderObject extends LeafRenderObject {
4547
4648
  if (!event.options.showEnterSymbol || event.mode === 'print') {
4548
4649
  return null;
4549
4650
  }
4550
- const font = `14px 宋体`;
4551
- const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(font);
4651
+ // const font = `14px system-ui`
4652
+ // const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(font);
4552
4653
  let y = this.rect.y;
4553
- //基线处理
4554
- y += actualFontBoundingBoxAscent ?? 0;
4555
- //行高处理
4654
+ // //基线处理
4655
+ //y += actualFontBoundingBoxAscent ?? 0;
4656
+ // //行高处理
4556
4657
  y += (this.rect.height - 14) / 2;
4557
- return ElementUtil.createSvgText('↵', {
4558
- 'font-family': '宋体',
4559
- 'font-size': 14,
4560
- x: this.rect.x,
4561
- y: y,
4562
- fill: 'green'
4563
- });
4658
+ return {
4659
+ sel: 'image',
4660
+ data: {
4661
+ ns: 'http://www.w3.org/2000/svg',
4662
+ attrs: {
4663
+ translate: { x: this.rect.x, y: y },
4664
+ width: 7,
4665
+ height: 7,
4666
+ 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=",
4667
+ }
4668
+ }
4669
+ };
4564
4670
  }
4565
4671
  //绘制段落符号
4566
4672
  clone() {
@@ -8800,26 +8906,32 @@ class BreakRenderObject extends LeafRenderObject {
8800
8906
  if (!event.options.showEnterSymbol || event.mode === 'print') {
8801
8907
  return null;
8802
8908
  }
8803
- // return ElementUtil.createSvgText( '↓',{ 'dominant-baseline': 'hanging',
8804
- // 'font-family': 'Courier',
8805
- // 'font-size': this.rect.height,
8806
- // x: this.rect.x + 4,
8807
- // y: this.rect.y,
8808
- // fill: 'green'});
8809
- const font = `14px 宋体`;
8810
- const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(font);
8811
- let y = 0;
8812
- //基线处理
8813
- y += actualFontBoundingBoxAscent ?? 0;
8814
- //行高处理
8815
- y += (this.parent.rect.height - 14) / 2;
8816
- return ElementUtil.createSvgText('↓', {
8817
- 'font-family': '宋体',
8818
- 'font-size': 14,
8819
- x: this.rect.x,
8820
- y: y,
8821
- fill: 'green'
8822
- });
8909
+ // const font = `14px system-ui`
8910
+ // const actualFontBoundingBoxAscent = event.renderCtx.mainContext.getActualFontBoundingBoxAscent(font);
8911
+ let y = this.rect.y;
8912
+ // return {
8913
+ // sel: 'path',
8914
+ // data: {
8915
+ // ns: 'http://www.w3.org/2000/svg',
8916
+ // attrs: {
8917
+ // stroke: 'none',
8918
+ // fill: 'blue',
8919
+ // d: path,
8920
+ // translate: { x: this.rect.x, y: y }
8921
+ // }
8922
+ // }
8923
+ // }
8924
+ return {
8925
+ sel: 'image',
8926
+ data: {
8927
+ ns: 'http://www.w3.org/2000/svg',
8928
+ attrs: {
8929
+ translate: { x: this.rect.x, y: y + (this.rect.height - 10) / 2 },
8930
+ height: 10,
8931
+ href: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAA/CAYAAABqzXG5AAAAAXNSR0IArs4c6QAAAKdJREFUaEPt2LENhDAMQFHSMs4tiFiQcWg5XUGDcIQtoDg96gTC59vYbkPxGj/zFm1dl6lVblva9HuQw0S4kUEmG4qc4QxnDgT8myIlkEEmmy44wxnOHAnom3SUZwQU5ArybLbkDGc4o4m76ICCPCzIe5n0It3bljWHCVgiQ+BsmHWT3hOR1mvwHKY0EvGZKnVuNlL29f8hcO/t9U0Vn0yuTK7emlx9ARNg7GSAIh9+AAAAAElFTkSuQmCC",
8932
+ }
8933
+ }
8934
+ };
8823
8935
  }
8824
8936
  clone() {
8825
8937
  const render = new BreakRenderObject(this.element);
@@ -8883,7 +8995,7 @@ class DataElementGroupElement extends InlineGroupInputElement {
8883
8995
  }
8884
8996
  }
8885
8997
  getValue() {
8886
- return ElementSerialize.serializeString(this, { all: false });
8998
+ return ElementSerialize.serializeString(this);
8887
8999
  }
8888
9000
  clone(data) {
8889
9001
  return super.cloneSelf(data, DataElementGroupElement);
@@ -8988,15 +9100,29 @@ function exportDataEleDecoratorSVG(event, r) {
8988
9100
  return;
8989
9101
  }
8990
9102
  //绘制背景
8991
- if (['all', 'background'].includes(mode)) {
8992
- const bgX = event.relativePagePos.x;
8993
- const bgY = event.relativePagePos.y;
8994
- event.highlights.push(ElementUtil.getFillSvgRect(bgX, bgY, r.rect.width, r.rect.height, color));
8995
- }
8996
- if (['all', 'outline'].includes(mode)) {
8997
- color = event.options.dataGroupOutlineColor;
9103
+ // if (['all', 'background'].includes(mode)) {
9104
+ // const bgX = event.relativePagePos.x;
9105
+ // const bgY = event.relativePagePos.y;
9106
+ // event.highlights.push(ElementUtil.getFillSvgRect(bgX, bgY, r.rect.width, r.rect.height, color));
9107
+ // }
9108
+ if (['all', 'outline', 'background'].includes(mode)) {
9109
+ let outlineColor = ['all', 'outline'].includes(mode) ? event.options.dataGroupOutlineColor : 'none';
9110
+ let bgColor = ['all', 'background'].includes(mode) ? color : 'none';
8998
9111
  const verOffset = 0;
8999
- const renderPosMap = getCurrentParaGroupRenders(r).map(item => ({ pos: getRenderPosToDoc(item), render: item }));
9112
+ const currParaGroupRenders = getCurrentParaGroupRenders(r);
9113
+ if (currParaGroupRenders.indexOf(r) === 0) {
9114
+ outlineColor = 'none';
9115
+ }
9116
+ if (currParaGroupRenders.indexOf(r) === currParaGroupRenders.length - 1) {
9117
+ bgColor = 'none';
9118
+ }
9119
+ if (bgColor !== 'none' && currParaGroupRenders.indexOf(r) !== 0) {
9120
+ return;
9121
+ }
9122
+ if (outlineColor !== 'none' && currParaGroupRenders.indexOf(r) !== currParaGroupRenders.length - 1) {
9123
+ return;
9124
+ }
9125
+ const renderPosMap = currParaGroupRenders.map(item => ({ pos: getRenderPosToDoc(item), render: item }));
9000
9126
  if (renderPosMap.length > 1) {
9001
9127
  const secondGroupRenderPos = renderPosMap[1].pos;
9002
9128
  if (secondGroupRenderPos.x + renderPosMap[1].render.rect.width > event.relativePagePos.x) {
@@ -9024,8 +9150,8 @@ function exportDataEleDecoratorSVG(event, r) {
9024
9150
  const path = [...sharpPoints, ...sharpPoints1, sharpPoints[0]].map((item, index) => ((index === 0) ? 'M' : "L") + item.x + " " + item.y).join(" ");
9025
9151
  event.highlights.push(ElementUtil.createSvgPath({
9026
9152
  d: path,
9027
- stroke: color,
9028
- fill: 'none',
9153
+ stroke: outlineColor,
9154
+ fill: bgColor,
9029
9155
  'stroke-width': 1
9030
9156
  }));
9031
9157
  return;
@@ -9035,8 +9161,8 @@ function exportDataEleDecoratorSVG(event, r) {
9035
9161
  const currRen = renderPosMap[i];
9036
9162
  event.highlights.push(ElementUtil.createSvgPath({
9037
9163
  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`,
9038
- stroke: color,
9039
- fill: 'none',
9164
+ stroke: outlineColor,
9165
+ fill: bgColor,
9040
9166
  'stroke-width': 1
9041
9167
  }));
9042
9168
  }
@@ -9291,7 +9417,7 @@ class DataElementText extends DataElementInlineGroup {
9291
9417
  createRenderObject(data) {
9292
9418
  if (data.options.enableDyExpression) {
9293
9419
  this.parseEleExpression(data);
9294
- this.evalEleExpr(data.execute);
9420
+ //this.evalEleExpr(data.execute)
9295
9421
  }
9296
9422
  return new DataElementTextRenderObject(this);
9297
9423
  }
@@ -9341,7 +9467,7 @@ class DataElementText extends DataElementInlineGroup {
9341
9467
  this.onChangedValidate();
9342
9468
  }
9343
9469
  getValue() {
9344
- return ElementSerialize.serializeString(this, { all: false });
9470
+ return ElementSerialize.serializeString(this);
9345
9471
  }
9346
9472
  validate() {
9347
9473
  let error = super.validate();
@@ -10944,8 +11070,8 @@ class ElementSerialize {
10944
11070
  }
10945
11071
  return result;
10946
11072
  }
10947
- static serializeString(element, options = { all: false }) {
10948
- if (!options.all && element instanceof TrackRunElement && element.type === exports.TrackRunTypeEnum.Deleted) {
11073
+ static serializeString(element, options = { includeRunDel: false }) {
11074
+ if (!options.includeRunDel && element instanceof TrackRunElement && element.type === exports.TrackRunTypeEnum.Deleted) {
10949
11075
  return '';
10950
11076
  }
10951
11077
  if (element instanceof TextGroupElement && !element.isDecorate) {
@@ -11082,7 +11208,7 @@ class TrackRunElement extends InlineGroupElement {
11082
11208
  trackRunType: this.type,
11083
11209
  name: this.props.userName,
11084
11210
  date: this.props.date,
11085
- content: ElementSerialize.serializeString(this, { all: true })
11211
+ content: ElementSerialize.serializeString(this, { includeRunDel: true })
11086
11212
  };
11087
11213
  console.log(evt.trackTips.content);
11088
11214
  evt.isCancel = true;
@@ -11182,7 +11308,7 @@ class TrackRunRenderObject extends InlineGroupRenderObject {
11182
11308
  const { x, y } = event.globalPos;
11183
11309
  const docRender = ElementUtil.getParentRender(this, DocumentRenderObject);
11184
11310
  const opType = this.element.type === 'ins-run' ? '插入:' : '删除:';
11185
- const content = ElementSerialize.serializeString(this.element, { all: true });
11311
+ const content = ElementSerialize.serializeString(this.element, { includeRunDel: true });
11186
11312
  let left = this.element.gotFocus ? -10 : 5;
11187
11313
  //显示在文档的右测
11188
11314
  left += docRender.rect.x + docRender.rect.width + 20;
@@ -12322,54 +12448,87 @@ class ElementUtil {
12322
12448
  /**
12323
12449
  * 递归向前寻找最近的元素
12324
12450
  * @param currElement
12325
- * @param inPara 是否在同一段落中寻找
12326
- * @param forCursor 查找结果是否用于光标定位
12327
12451
  * @param viewOptions
12328
12452
  * @returns
12329
12453
  */
12330
- static getRecursionPrevSiblingElement(currElement, inPara = false, forCursor = false, viewOptions) {
12454
+ static getRecursionPrevSiblingElement(currElement, viewOptions) {
12331
12455
  const parent = currElement?.parent;
12332
12456
  //删除留痕块的measureRender在不显示留痕模式下,不生成render
12333
- if (!currElement || !parent || (!currElement.paintRenders.length && !(currElement instanceof TrackRunElement))) {
12457
+ if (!currElement || !parent || !currElement.paintRenders.length) {
12334
12458
  return null;
12335
12459
  }
12336
12460
  //如果当前数据元不可编辑,则直接跳过
12337
- if (parent instanceof DataElementInlineGroup && !parent.props.editable && viewOptions.docMode === exports.DocMode.FormEdit) {
12338
- return this.getRecursionPrevSiblingElement(parent, inPara, forCursor, viewOptions);
12339
- }
12340
- if (forCursor && parent.disableClick) {
12341
- return this.getRecursionPrevSiblingElement(parent, inPara, forCursor, viewOptions);
12342
- }
12461
+ //不存在这种情况
12462
+ // if (parent instanceof DataElementInlineGroup && !parent.props.editable && viewOptions.docMode === DocMode.FormEdit) {
12463
+ // return this.getRecursionPrevSiblingElement(parent, inPara, viewOptions);
12464
+ // }
12465
+ //不存在这种情况
12466
+ // if (parent.disableClick) {
12467
+ // return this.getRecursionPrevSiblingElement(parent, inPara, viewOptions);
12468
+ // }
12343
12469
  const index = parent.getChildIndex(currElement);
12344
- if (!index) {
12345
- if (inPara && parent.type === 'p') {
12346
- return null;
12470
+ // if (!index) {
12471
+ // if (inPara && parent.type === 'p') {
12472
+ // return null;
12473
+ // }
12474
+ // return this.getRecursionPrevSiblingElement(parent, inPara, viewOptions);
12475
+ // } else {
12476
+ let prevElement = null;
12477
+ for (let i = index - 1; i >= 0; i--) {
12478
+ prevElement = parent.getChild(i);
12479
+ const res = this.getRecursionSiblingElementCursorPosition(prevElement, viewOptions, 'left');
12480
+ if (res) {
12481
+ return res;
12347
12482
  }
12348
- return this.getRecursionPrevSiblingElement(parent, inPara, forCursor, viewOptions);
12349
12483
  }
12350
- else {
12351
- let prevElement = null;
12352
- for (let i = index - 1; i >= 0; i--) {
12353
- prevElement = parent.getChild(i);
12354
- if (prevElement && !prevElement.disableClick) {
12355
- break;
12484
+ //表单模式需要判断当前父级是否已经超出数据元或者数据组的范围
12485
+ if (viewOptions.docMode === exports.DocMode.FormEdit && !ElementUtil.getDataGroupElement(parent)) {
12486
+ return null;
12487
+ }
12488
+ return this.getRecursionPrevSiblingElement(parent, viewOptions);
12489
+ //}
12490
+ }
12491
+ /**
12492
+ * 递归元素里面向前寻找可以定位的元素
12493
+ */
12494
+ static getRecursionSiblingElementCursorPosition(ele, viewOptions, direction) {
12495
+ if (ele instanceof LeafElement) {
12496
+ return this.getElementPositionCursor(ele, viewOptions, direction);
12497
+ }
12498
+ if (ele instanceof BranchElement) {
12499
+ const startIndex = direction === 'left' ? ele.length - 1 : 0;
12500
+ const endIndex = direction === 'left' ? 0 : ele.length - 1;
12501
+ const increment = direction === 'left' ? -1 : 1;
12502
+ for (let i = startIndex; direction === 'left' ? i >= endIndex : i <= endIndex; i += increment) {
12503
+ const child = ele.getChild(i);
12504
+ if (child instanceof LeafElement) {
12505
+ const res = this.getElementPositionCursor(child, viewOptions, direction);
12506
+ if (res) {
12507
+ return res;
12508
+ }
12509
+ }
12510
+ else if (child instanceof BranchElement) {
12511
+ const res = this.getRecursionSiblingElementCursorPosition(child, viewOptions, direction);
12512
+ if (res) {
12513
+ return res;
12514
+ }
12356
12515
  }
12357
12516
  }
12358
- if (!prevElement || prevElement.disableClick) {
12359
- return this.getRecursionPrevSiblingElement(parent, inPara, forCursor, viewOptions);
12360
- }
12361
- const lastLeafElement = ElementUtil.getLastLeafElement(prevElement);
12362
- //用于光标定位
12363
- if (forCursor && lastLeafElement && !ElementUtil.canSetCursor(lastLeafElement, 0, true, viewOptions)) {
12364
- return this.getRecursionPrevSiblingElement(lastLeafElement, inPara, forCursor, viewOptions);
12365
- }
12366
- if (lastLeafElement) {
12367
- return lastLeafElement;
12368
- }
12369
- else {
12370
- return this.getRecursionPrevSiblingElement(prevElement.parent, inPara, forCursor, viewOptions);
12517
+ }
12518
+ return null;
12519
+ }
12520
+ static getElementPositionCursor(ele, viewOptions, direction) {
12521
+ const endOffset = ElementUtil.getElementEndOffset(ele);
12522
+ const offsets = direction === 'left' ? [endOffset, 0] : [0, endOffset];
12523
+ for (let i = 0; i < offsets.length; i++) {
12524
+ if (ElementUtil.canSetCursor(ele, offsets[i], true, viewOptions)) {
12525
+ return {
12526
+ ele: ele,
12527
+ offset: offsets[i]
12528
+ };
12371
12529
  }
12372
12530
  }
12531
+ return null;
12373
12532
  }
12374
12533
  /**
12375
12534
  * 循环向前寻找可定位的数据元
@@ -12434,55 +12593,56 @@ class ElementUtil {
12434
12593
  /**
12435
12594
  * 递归向后寻找最近的元素
12436
12595
  */
12437
- static getRecursionNextSiblingElement(currElement, inPara = false, forCursor = false, viewOptions) {
12596
+ static getRecursionNextSiblingElement(currElement, viewOptions) {
12438
12597
  const parent = currElement?.parent;
12439
12598
  if (!currElement || !parent) {
12440
12599
  return null;
12441
12600
  }
12442
- // if (!currElement.paintRenders.length) {
12443
- // return this.getRecursionNextSiblingElement(currElement, inPara, forCursor, viewOptions);
12601
+ // //如果当前数据元不可编辑,则直接跳过
12602
+ // if (parent instanceof DataElementInlineGroup && !parent.props.editable && viewOptions.docMode === DocMode.FormEdit) {
12603
+ // return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12604
+ // }
12605
+ // //如果当前为数据组,且数据组被隐藏,则直接跳过
12606
+ // if (parent instanceof DataElementGroupElement && parent.props.hidden) {
12607
+ // return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12608
+ // }
12609
+ // if (forCursor && parent.disableClick) {
12610
+ // return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12444
12611
  // }
12445
- //如果当前数据元不可编辑,则直接跳过
12446
- if (parent instanceof DataElementInlineGroup && !parent.props.editable && viewOptions.docMode === exports.DocMode.FormEdit) {
12447
- return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12448
- }
12449
- //如果当前为数据组,且数据组被隐藏,则直接跳过
12450
- if (parent instanceof DataElementGroupElement && parent.props.hidden) {
12451
- return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12452
- }
12453
- if (forCursor && parent.disableClick) {
12454
- return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12455
- }
12456
12612
  const index = parent.getChildIndex(currElement);
12457
- if (index === parent.length - 1) {
12458
- if (inPara && parent.type === 'p') {
12459
- return null;
12613
+ // if (index === parent.length - 1) {
12614
+ // if (inPara && parent.type === 'p') {
12615
+ // return null;
12616
+ // }
12617
+ // return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12618
+ // } else {
12619
+ let nextElement = null;
12620
+ for (let i = index + 1; i < parent.length; i++) {
12621
+ nextElement = parent.getChild(i);
12622
+ const res = this.getRecursionSiblingElementCursorPosition(nextElement, viewOptions, 'right');
12623
+ if (res) {
12624
+ return res;
12460
12625
  }
12461
- return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12462
12626
  }
12463
- else {
12464
- let nextElement = null;
12465
- for (let i = index + 1; i < parent.length; i++) {
12466
- nextElement = parent.getChild(i);
12467
- if (nextElement && !nextElement.disableClick) {
12468
- break;
12469
- }
12470
- }
12471
- if (!nextElement || nextElement.disableClick) {
12472
- return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12473
- }
12474
- const lastLeafElement = ElementUtil.getFirstLeafElement(nextElement);
12475
- //用于光标定位
12476
- if (forCursor && lastLeafElement && !ElementUtil.canSetCursor(lastLeafElement, ElementUtil.getElementEndOffset(lastLeafElement), true, viewOptions)) {
12477
- return this.getRecursionNextSiblingElement(lastLeafElement, inPara, forCursor, viewOptions);
12478
- }
12479
- if (lastLeafElement) {
12480
- return lastLeafElement;
12481
- }
12482
- else {
12483
- return this.getRecursionNextSiblingElement(nextElement.parent, inPara, forCursor, viewOptions);
12484
- }
12627
+ //表单模式需要判断当前父级是否已经超出数据元或者数据组的范围
12628
+ if (viewOptions.docMode === exports.DocMode.FormEdit && !ElementUtil.getDataGroupElement(parent)) {
12629
+ return null;
12485
12630
  }
12631
+ return this.getRecursionNextSiblingElement(parent, viewOptions);
12632
+ // if (!nextElement || nextElement.disableClick) {
12633
+ // return this.getRecursionNextSiblingElement(parent, inPara, forCursor, viewOptions);
12634
+ // }
12635
+ // const lastLeafElement = ElementUtil.getFirstLeafElement(nextElement);
12636
+ // //用于光标定位
12637
+ // if (forCursor && lastLeafElement && !ElementUtil.canSetCursor(lastLeafElement, ElementUtil.getElementEndOffset(lastLeafElement), true, viewOptions)) {
12638
+ // return this.getRecursionNextSiblingElement(lastLeafElement, inPara, forCursor, viewOptions);
12639
+ // }
12640
+ // if (lastLeafElement) {
12641
+ // return lastLeafElement;
12642
+ // } else {
12643
+ // return this.getRecursionNextSiblingElement(nextElement.parent, inPara, forCursor, viewOptions);
12644
+ // }
12645
+ //}
12486
12646
  }
12487
12647
  // /**
12488
12648
  // * 在同一段落中,递归向后寻找最近的元素
@@ -12799,10 +12959,10 @@ class ElementUtil {
12799
12959
  return this.getParent(ele, item => item instanceof DataElementInlineGroup);
12800
12960
  }
12801
12961
  /**
12802
- * 向上查找类型为数据元的父级
12803
- * @param ele
12804
- * @returns
12805
- */
12962
+ * 向上查找类型为数据元的父级
12963
+ * @param ele
12964
+ * @returns
12965
+ */
12806
12966
  static getDataGroupElement(ele) {
12807
12967
  return this.getParent(ele, item => item instanceof DataElementGroupElement);
12808
12968
  }
@@ -13041,6 +13201,9 @@ class ElementUtil {
13041
13201
  }
13042
13202
  return items;
13043
13203
  }
13204
+ static isDataEle(ele) {
13205
+ return validateDataEle(ele) || ele instanceof DataElementGroupElement;
13206
+ }
13044
13207
  }
13045
13208
 
13046
13209
  exports.TextUnitsHolder = void 0;
@@ -13562,7 +13725,7 @@ class EditorContext {
13562
13725
  // const docRefreshSub = this._document.refreshSubject.subscribe(() => {
13563
13726
  // this.syncRefresh?.();
13564
13727
  // });
13565
- const docChangedSub = this._document.onChangeSubject.subscribe(() => {
13728
+ const docChangedSub = this._document.onRefreshEvent.subscribe(() => {
13566
13729
  this.syncRefresh?.();
13567
13730
  });
13568
13731
  this.syncRefresh();
@@ -13679,20 +13842,17 @@ class DocumentContext {
13679
13842
  this.ss = ss;
13680
13843
  }
13681
13844
  getControlIDList() {
13682
- const dataEleList = this.ctx.treeFilter(item => this.isDataEle(item));
13845
+ const dataEleList = this.ctx.treeFilter(item => ElementUtil.isDataEle(item));
13683
13846
  return dataEleList.map(item => item.props.id);
13684
13847
  }
13685
13848
  getControlInstanceList(options) {
13686
- return this.ctx.treeFilter(item => this.isDataEle(item), options);
13849
+ return this.ctx.treeFilter(item => ElementUtil.isDataEle(item), options);
13687
13850
  }
13688
13851
  getControlById(id) {
13689
- return this.ctx.treeFind(item => this.isDataEle(item) && item['props']['id'] === id);
13690
- }
13691
- isDataEle(ele) {
13692
- return validateDataEle(ele) || ele instanceof DataElementGroupElement;
13852
+ return this.ctx.treeFind(item => ElementUtil.isDataEle(item) && item['props']['id'] === id);
13693
13853
  }
13694
13854
  getControlByName(name) {
13695
- return this.ctx.treeFind(item => this.isDataEle(item) && item['props']['name'] === name);
13855
+ return this.ctx.treeFind(item => ElementUtil.isDataEle(item) && item['props']['name'] === name);
13696
13856
  }
13697
13857
  /**
13698
13858
  * 获取数据元值集合
@@ -13710,9 +13870,9 @@ class DocumentContext {
13710
13870
  * @returns
13711
13871
  */
13712
13872
  getDataElementModelList(options) {
13713
- const dataEleList = this.ctx.treeFilter(item => this.isDataEle(item), options);
13873
+ const dataEleList = this.ctx.treeFilter(item => ElementUtil.isDataEle(item), options);
13714
13874
  //数据元、数据组
13715
- const dataInlineGroups = dataEleList.filter(item => item instanceof DataElementInlineGroup);
13875
+ const dataInlineGroups = dataEleList.filter(item => item instanceof DataElementInlineGroup || item instanceof DataElementGroupElement);
13716
13876
  const dataLeafs = dataEleList.filter(item => item instanceof DataElementLeaf);
13717
13877
  //复选框数据元
13718
13878
  const dataCheckList = dataLeafs.filter(item => item instanceof DataElementCheck);
@@ -13721,6 +13881,7 @@ class DocumentContext {
13721
13881
  id: item.props.id,
13722
13882
  name: item.props.name,
13723
13883
  fieldName: item.props.fieldName,
13884
+ caption: item.props.caption,
13724
13885
  item,
13725
13886
  getValue: () => {
13726
13887
  return item.getValue();
@@ -13730,7 +13891,7 @@ class DocumentContext {
13730
13891
  }
13731
13892
  }));
13732
13893
  const dataInlineStructList = dataInlineGroups.map(item => ({
13733
- id: item.props.id, name: item.props.name, fieldName: item.props.fieldName, item, getValue: () => {
13894
+ id: item.props.id, name: item.props.name, fieldName: item.props.fieldName, caption: item.props.caption, item, getValue: () => {
13734
13895
  return item.getValue();
13735
13896
  }, setValue: (val) => {
13736
13897
  item.setValue(val);
@@ -13757,6 +13918,7 @@ class DocumentContext {
13757
13918
  name: groupCheckItems[0].props.name,
13758
13919
  fieldName: groupCheckItems[0].props.fieldName,
13759
13920
  multiSelect: groupCheckItems[0].props.multiSelect,
13921
+ caption: groupCheckItems[0].props.caption,
13760
13922
  item: groupCheckItems,
13761
13923
  getValue: () => {
13762
13924
  let checkedValue = '';
@@ -13795,6 +13957,7 @@ class DocumentContext {
13795
13957
  id: item.props.id,
13796
13958
  name: item.props.name,
13797
13959
  fieldName: item.props.fieldName,
13960
+ caption: item.props.caption,
13798
13961
  item,
13799
13962
  getValue: () => {
13800
13963
  return item.getValue();
@@ -13821,7 +13984,7 @@ class DocumentContext {
13821
13984
  const trackElements = this.getTrackElements();
13822
13985
  return trackElements.map(item => {
13823
13986
  const trackRun = item;
13824
- const content = ElementSerialize.serializeString(trackRun, { all: true });
13987
+ const content = ElementSerialize.serializeString(trackRun, { includeRunDel: true });
13825
13988
  return {
13826
13989
  //用户id
13827
13990
  userId: trackRun.props.userId,
@@ -13955,6 +14118,9 @@ class DynamicExecute {
13955
14118
  this.doc = doc;
13956
14119
  this.ss = ss;
13957
14120
  }
14121
+ create() {
14122
+ return new DynamicExecute(this.doc, this.ss);
14123
+ }
13958
14124
  setCurrentCtx(ele, depItems) {
13959
14125
  this.current = ele;
13960
14126
  this.depItems = depItems;
@@ -14068,14 +14234,23 @@ class DynamicExecute {
14068
14234
  }
14069
14235
 
14070
14236
  class ParagraphMeasure {
14071
- options;
14237
+ docCtx;
14072
14238
  renderCtx;
14073
14239
  execute;
14074
- constructor(options, renderCtx, execute) {
14075
- this.options = options;
14240
+ options;
14241
+ createData;
14242
+ constructor(docCtx, renderCtx, execute) {
14243
+ this.docCtx = docCtx;
14076
14244
  this.renderCtx = renderCtx;
14077
14245
  this.execute = execute;
14246
+ this.options = this.docCtx.viewOptions;
14078
14247
  this.execute = execute;
14248
+ this.createData = {
14249
+ options: this.options,
14250
+ renderCtx: this.renderCtx,
14251
+ execute: this.execute,
14252
+ onNextView: (cb) => { docCtx.onNextView(cb); }
14253
+ };
14079
14254
  }
14080
14255
  /**
14081
14256
  * 段落排版:
@@ -14318,7 +14493,7 @@ class ParagraphMeasure {
14318
14493
  }
14319
14494
  }
14320
14495
  arrangeInlineGroupElement(parentLine, ele) {
14321
- const { options, renderCtx, execute } = this;
14496
+ const createData = this.createData;
14322
14497
  let render = this.createRenderObject(ele);
14323
14498
  //记录多行情况下的渲染对象,用于计算总长度,生成fill-null-space
14324
14499
  const inlineGroupRenders = [];
@@ -14359,7 +14534,7 @@ class ParagraphMeasure {
14359
14534
  render.rect.width += space;
14360
14535
  }
14361
14536
  parentLine.applyNewLine();
14362
- render = ele.createRenderObject({ options, renderCtx, execute });
14537
+ render = ele.createRenderObject(createData);
14363
14538
  parentLine.add(render);
14364
14539
  inlineGroupRenders.push(render);
14365
14540
  },
@@ -14645,6 +14820,10 @@ class ParagraphMeasure {
14645
14820
  const refCtx = execute.getObject(dep);
14646
14821
  if (refCtx.ref) {
14647
14822
  const refEle = refCtx.ref.item;
14823
+ //自己不能引用自己,避免死循环
14824
+ if (refEle === ele) {
14825
+ return;
14826
+ }
14648
14827
  depEleMap.set(dep, refCtx);
14649
14828
  //当前有可能是checkbox数组
14650
14829
  const refEles = Array.isArray(refEle) ? refEle : [refEle];
@@ -14663,6 +14842,62 @@ class ParagraphMeasure {
14663
14842
  console.error('解析表达式出错', ele.attribute?.visibleExpr);
14664
14843
  }
14665
14844
  }
14845
+ // /**
14846
+ // * 解析侦听表达式
14847
+ // * 当依赖性元素发生变化时,重新计算运行当前元素的表达式
14848
+ // * @param ele
14849
+ // * @param execute
14850
+ // * @private
14851
+ // */
14852
+ // parseEffectExpression(ele: Element, execute: DynamicExecute): void {
14853
+ // if (ele.effectExpr) return;
14854
+ // if (!ele.attribute?.effectExpr) return;
14855
+ // const reactiveMode = this.renderCtx.drawMode !== 'print';
14856
+ // try {
14857
+ // const depIdItems: Array<string> = [];
14858
+ // const depEleMap: Map<string, RefCtxValue> = new Map();
14859
+ // let compliedCode = parser(ele.attribute?.effectExpr, depIdItems);
14860
+ // compliedCode = addReturn(compliedCode);
14861
+ // ele.effectExpr = { compliedCode, func: new Function(`with(this){ ${compliedCode} }`), depItems: depEleMap };
14862
+ // if (depIdItems.length) {
14863
+ // depIdItems.forEach(dep => {
14864
+ // const refCtx = execute.getObject(dep);
14865
+ // if (refCtx.ref) {
14866
+ // const refEle = refCtx.ref.item as Element;
14867
+ // //自己不能引用自己,避免死循环
14868
+ // if (refEle === ele) {
14869
+ // return;
14870
+ // }
14871
+ // depEleMap.set(dep, refCtx);
14872
+ // //当前有可能是checkbox数组
14873
+ // const refEles = Array.isArray(refEle) ? refEle : [refEle];
14874
+ // reactiveMode && refEles.forEach(item => {
14875
+ // //求值依赖元素更改的时候,发布当前元素重新计算的指令
14876
+ // item.onChangeSubject.subscribe(() => {
14877
+ // try {
14878
+ // this.docCtx.onNextView(() => {
14879
+ // //当前元素可能被删除
14880
+ // const func = ele?.effectExpr?.func;
14881
+ // if (!func) {
14882
+ // return;
14883
+ // }
14884
+ // const tempExecuter = execute.create();
14885
+ // tempExecuter.setCurrentCtx(ele, ele.effectExpr.depItems);
14886
+ // const fn = func.bind(tempExecuter);
14887
+ // fn();
14888
+ // })
14889
+ // } catch (e) {
14890
+ // console.error(e, "表达式执行出错", ele.effectExpr.compliedCode);
14891
+ // }
14892
+ // });
14893
+ // });
14894
+ // }
14895
+ // });
14896
+ // }
14897
+ // } catch (e) {
14898
+ // console.error('解析表达式出错', ele.attribute?.effectExpr);
14899
+ // }
14900
+ // }
14666
14901
  /**
14667
14902
  * 元素可见行求值
14668
14903
  * @param ele
@@ -14692,11 +14927,10 @@ class ParagraphMeasure {
14692
14927
  return null;
14693
14928
  }
14694
14929
  }
14695
- return element.createRenderObject({
14696
- options: this.options,
14697
- renderCtx: this.renderCtx,
14698
- execute: this.execute
14699
- });
14930
+ // if (this.options.enableDyExpression) {
14931
+ // this.parseEffectExpression(element, this.execute);
14932
+ // }
14933
+ return element.createRenderObject(this.createData);
14700
14934
  }
14701
14935
  }
14702
14936
 
@@ -14710,6 +14944,8 @@ class SelectionOverlays {
14710
14944
  selectionEleSets = new Map();
14711
14945
  //批注对象集合
14712
14946
  commRangeSets = new Map();
14947
+ //其他对象集合,例如查找对象
14948
+ otherRangeSets = new Map();
14713
14949
  constructor(selectionState) {
14714
14950
  this.selectionState = selectionState;
14715
14951
  }
@@ -14759,6 +14995,18 @@ class SelectionOverlays {
14759
14995
  this.addToSets(range.selectedChildren[i], set);
14760
14996
  }
14761
14997
  }
14998
+ addToOtherRangeSets(range) {
14999
+ if (!this.otherRangeSets.has(range.target)) {
15000
+ this.otherRangeSets.set(range.target, []);
15001
+ }
15002
+ this.otherRangeSets.get(range.target)?.push(range);
15003
+ for (let i = 0; i < range.selectedChildren.length; i++) {
15004
+ this.addToOtherRangeSets(range.selectedChildren[i]);
15005
+ }
15006
+ }
15007
+ clearOtherRangeSets() {
15008
+ this.otherRangeSets.clear();
15009
+ }
14762
15010
  /**
14763
15011
  * 添加到批注集合
14764
15012
  * @param range
@@ -14851,7 +15099,7 @@ class DocumentArrange {
14851
15099
  return suppressTracking(() => {
14852
15100
  const doc = this.docCtx.document;
14853
15101
  this.execute = new DynamicExecute(doc, this.docCtx.selectionState);
14854
- this.pMeasure = new ParagraphMeasure(this.options, this.renderCtx, this.execute);
15102
+ this.pMeasure = new ParagraphMeasure(this.docCtx, this.renderCtx, this.execute);
14855
15103
  const data = {
14856
15104
  doc,
14857
15105
  options: this.options,
@@ -15059,7 +15307,7 @@ class DocumentArrange {
15059
15307
  if (this.options.textRowLineMode && ele instanceof TableElement && ele.cacheRender) {
15060
15308
  const cacheRender = ele.cacheRender;
15061
15309
  clearChildrenRenderCache(ele);
15062
- textLineRenderMode(cacheRender, { options: this.options, renderCtx: this.renderCtx, execute: this.execute });
15310
+ textLineRenderMode(cacheRender, { options: this.options, renderCtx: this.renderCtx, execute: this.execute, onNextView: (cb) => { this.docCtx.onNextView(cb); } });
15063
15311
  }
15064
15312
  }
15065
15313
  getDocInnerRect(documentRender) {
@@ -15412,6 +15660,9 @@ class DocumentArrange {
15412
15660
  clearPaintCache(ele, data) {
15413
15661
  ele.paintRenders.length = 0;
15414
15662
  ele.beginMeasure(data);
15663
+ if (ele.modifyFlag !== exports.ModifyFlag.None) {
15664
+ ele.onChangeSubject.next();
15665
+ }
15415
15666
  this.identifyComment(ele);
15416
15667
  if (ele instanceof BranchElement) {
15417
15668
  for (let i = 0; i < ele.length; i++) {
@@ -15483,7 +15734,7 @@ class DocumentArrange {
15483
15734
  if (!this.options.enableFastMeasure) {
15484
15735
  return false;
15485
15736
  }
15486
- this.pMeasure = new ParagraphMeasure(this.options, this.renderCtx, this.execute);
15737
+ this.pMeasure = new ParagraphMeasure(this.docCtx, this.renderCtx, this.execute);
15487
15738
  const ops = this.docCtx.currentOpsLog;
15488
15739
  if (!ops.length) {
15489
15740
  return false;
@@ -15542,7 +15793,7 @@ class DocumentArrange {
15542
15793
  return suppressTracking(() => {
15543
15794
  const doc = this.docCtx.document;
15544
15795
  this.execute = new DynamicExecute(doc, this.docCtx.selectionState);
15545
- this.pMeasure = new ParagraphMeasure(this.options, this.renderCtx, this.execute);
15796
+ this.pMeasure = new ParagraphMeasure(this.docCtx, this.renderCtx, this.execute);
15546
15797
  const data = {
15547
15798
  doc,
15548
15799
  options: this.options,
@@ -15580,6 +15831,7 @@ class DocumentPaginator {
15580
15831
  return;
15581
15832
  }
15582
15833
  this.docContainer = new DocumentContainerRender();
15834
+ //this.docContainer.padding.top = this.viewOptions.showRule ? 50 : 0;
15583
15835
  this.docCtx.selectionState.renderContainer = this.docContainer;
15584
15836
  this.docContainer.rect.width = this.viewOptions.docPageSettings.width;
15585
15837
  const newMeasure = new DocumentArrange(this.docCtx, this.renderContext, this.seo);
@@ -16900,13 +17152,14 @@ class DocumentEvent {
16900
17152
  moveCursorToLeftHandle(startControl, startOffset) {
16901
17153
  if (startOffset === 0) {
16902
17154
  const oldRegion = ElementUtil.getElementRegion(startControl);
16903
- const prevEle = ElementUtil.getRecursionPrevSiblingElement(startControl, false, true, this.viewOptions);
16904
- if (prevEle) {
16905
- const newRegion = ElementUtil.getElementRegion(prevEle);
17155
+ const cursorPosition = ElementUtil.getRecursionPrevSiblingElement(startControl, this.viewOptions);
17156
+ if (cursorPosition) {
17157
+ const { ele: prevEle, offset } = cursorPosition;
17158
+ const newRegion = ElementUtil.getElementRegion(cursorPosition.ele);
16906
17159
  if (newRegion !== oldRegion) {
16907
17160
  return;
16908
17161
  }
16909
- if (this.viewOptions.docMode === exports.DocMode.FormEdit && !ElementUtil.canSetCursor(prevEle, ElementUtil.fixedOffset(prevEle, -1), true, this.viewOptions)) {
17162
+ if (this.viewOptions.docMode === exports.DocMode.FormEdit && !ElementUtil.canSetCursor(prevEle, offset, true, this.viewOptions)) {
16910
17163
  this.moveCursorToLeftHandle(prevEle, 0);
16911
17164
  return;
16912
17165
  }
@@ -16954,17 +17207,18 @@ class DocumentEvent {
16954
17207
  moveCursorToRightHandle(startControl, startOffset) {
16955
17208
  if (this.isLeafEleEndOffset(startControl, startOffset)) {
16956
17209
  const oldRegion = ElementUtil.getElementRegion(startControl);
16957
- const nextEle = ElementUtil.getRecursionNextSiblingElement(startControl, false, true, this.viewOptions);
16958
- if (nextEle) {
16959
- const newRegion = ElementUtil.getElementRegion(nextEle);
17210
+ const cursorPosition = ElementUtil.getRecursionNextSiblingElement(startControl, this.viewOptions);
17211
+ if (cursorPosition) {
17212
+ const { ele, offset } = cursorPosition;
17213
+ const newRegion = ElementUtil.getElementRegion(ele);
16960
17214
  if (oldRegion !== newRegion) {
16961
17215
  return;
16962
17216
  }
16963
- if (this.viewOptions.docMode === exports.DocMode.FormEdit && !ElementUtil.canSetCursor(nextEle, ElementUtil.fixedOffset(nextEle, -1), true, this.viewOptions)) {
16964
- this.moveCursorToRightHandle(nextEle, ElementUtil.fixedOffset(nextEle, -1));
17217
+ if (this.viewOptions.docMode === exports.DocMode.FormEdit && !ElementUtil.canSetCursor(ele, offset, true, this.viewOptions)) {
17218
+ this.moveCursorToRightHandle(ele, offset);
16965
17219
  return;
16966
17220
  }
16967
- this.selectionState.resetRange(nextEle, 0);
17221
+ this.selectionState.resetRange(ele, 0);
16968
17222
  return;
16969
17223
  }
16970
17224
  }
@@ -17693,7 +17947,7 @@ class DocumentChange {
17693
17947
  }
17694
17948
  this.selectionState.clear();
17695
17949
  //用于刷新后定位光标
17696
- let startPointElement;
17950
+ let startPointElement = null;
17697
17951
  let startPointOffset = 0;
17698
17952
  if (selectedRange.isFullSelected) {
17699
17953
  //某个容器的内容被全部选中
@@ -17743,8 +17997,14 @@ class DocumentChange {
17743
17997
  startPointOffset = res.offset;
17744
17998
  }
17745
17999
  else {
17746
- startPointElement = ElementUtil.getRecursionPrevSiblingElement(startRange.target, false, true, this.viewOptions);
17747
- startPointOffset = -1;
18000
+ const cursorPosition = ElementUtil.getRecursionPrevSiblingElement(startRange.target, this.viewOptions);
18001
+ if (cursorPosition) {
18002
+ startPointElement = cursorPosition.ele;
18003
+ startPointOffset = cursorPosition.offset;
18004
+ }
18005
+ else {
18006
+ startPointElement = null;
18007
+ }
17748
18008
  //判断结束选区和开始选区是否在一个段落中,尽量落在同一段落中
17749
18009
  if (!startPointElement || ElementUtil.isInSameParagraph(startRange.target, endRange.target)) {
17750
18010
  if (!endRange.isFullSelected) {
@@ -17801,11 +18061,12 @@ class DocumentChange {
17801
18061
  onBackspaceElement(control, offset) {
17802
18062
  this.selectionState.clear();
17803
18063
  if (offset === 0) {
17804
- const prevEle = ElementUtil.getRecursionPrevSiblingElement(control, false, true, this.viewOptions);
17805
- if (!prevEle) {
18064
+ const cursorPosition = ElementUtil.getRecursionPrevSiblingElement(control, this.viewOptions);
18065
+ if (!cursorPosition) {
17806
18066
  this.selectionState.resetRange(control, 0);
17807
18067
  return;
17808
18068
  }
18069
+ const { ele: prevEle, offset } = cursorPosition;
17809
18070
  if (ElementUtil.isInSameParagraph(control, prevEle)) {
17810
18071
  if (ElementUtil.getPrevSiblingElement(control) === prevEle) {
17811
18072
  this.onBackspaceElement(prevEle, ElementUtil.getElementEndOffset(prevEle));
@@ -17891,18 +18152,24 @@ class DocumentChange {
17891
18152
  */
17892
18153
  onKeyDeleteElement(control, offset) {
17893
18154
  this.selectionState.clear();
18155
+ if (control instanceof PSymbolElement) {
18156
+ offset = 1;
18157
+ }
17894
18158
  if (offset === ElementUtil.getElementEndOffset(control)) {
17895
- const nextEle = ElementUtil.getRecursionNextSiblingElement(control, false, true, this.viewOptions);
17896
- if (!nextEle) {
18159
+ const cursorPosition = ElementUtil.getRecursionNextSiblingElement(control, this.viewOptions);
18160
+ if (!cursorPosition) {
17897
18161
  this.selectionState.resetRange(control, -1);
17898
18162
  return;
17899
18163
  }
18164
+ //const {ele: nextEle, offset} = cursorPosition;
18165
+ const nextEle = cursorPosition.ele;
18166
+ offset = cursorPosition.offset;
17900
18167
  if (ElementUtil.isInSameParagraph(control, nextEle)) {
17901
18168
  if (ElementUtil.getNextSiblingElement(control) === nextEle) {
17902
- this.onKeyDeleteElement(nextEle, 0);
18169
+ this.onKeyDeleteElement(nextEle, offset);
17903
18170
  }
17904
18171
  else {
17905
- this.selectionState.resetRange(nextEle, 0);
18172
+ this.selectionState.resetRange(nextEle, offset);
17906
18173
  }
17907
18174
  }
17908
18175
  else {
@@ -17915,7 +18182,7 @@ class DocumentChange {
17915
18182
  this.selectionState.resetRange(nextEle, 0);
17916
18183
  return;
17917
18184
  }
17918
- this.combineParagraph(nextPara, currPara, control);
18185
+ this.combineParagraph(currPara, nextPara, control);
17919
18186
  }
17920
18187
  else {
17921
18188
  //不是紧挨着的段落,则前一个段落是位于另一个容器里,例如:处于单元格内的段落
@@ -17935,21 +18202,29 @@ class DocumentChange {
17935
18202
  }
17936
18203
  }
17937
18204
  else {
17938
- if (control.parent instanceof DataElementInlineGroup && control instanceof DataDecorateElement) {
18205
+ //当前为数据修饰元素,需要做额外判定是否需要删除数据元素
18206
+ if (ElementUtil.isDataEle(control.parent) && control instanceof DataDecorateElement) {
17939
18207
  const dataEle = control.parent;
17940
18208
  //空数据元,并且当前光标处于数据元开始位置
17941
- if (control.isPrefix) {
18209
+ if (dataEle.length === 2) {
17942
18210
  if (this.canDeleteInlineGroup(dataEle)) {
17943
18211
  this.setCursorForDeleteAction(dataEle);
17944
18212
  dataEle.remove();
17945
18213
  }
17946
18214
  else {
17947
- this.selectionState.resetRange(control, -1);
18215
+ this.selectionState.resetRange(dataEle.startDecorate, 1);
17948
18216
  }
17949
18217
  return;
17950
18218
  }
17951
- else if (!control.isPrefix && dataEle.length === 2) {
17952
- this.selectionState.resetRange(dataEle.endDecorate, -1);
18219
+ else {
18220
+ //this.setCursorForDeleteAction(dataEle);
18221
+ const cursorInfo = ElementUtil.getRecursionNextSiblingElement(control, this.viewOptions);
18222
+ if (cursorInfo) {
18223
+ this.selectionState.resetRange(cursorInfo.ele, cursorInfo.offset);
18224
+ }
18225
+ else {
18226
+ this.selectionState.resetRange(control, 0);
18227
+ }
17953
18228
  return;
17954
18229
  }
17955
18230
  }
@@ -18021,14 +18296,14 @@ class DocumentChange {
18021
18296
  //当前用户增加的内容,内容直接删除不需要留痕
18022
18297
  if (this.isInCurrentUserTrack(target, exports.TrackRunTypeEnum.Inserted)) {
18023
18298
  target.remove();
18024
- this.removeEmtpyInlineBlock(parent);
18299
+ this.removeEmptyInlineBlock(parent);
18025
18300
  return;
18026
18301
  }
18027
18302
  //target.remove();
18028
18303
  const trackEle = this.getNextTrackElement(target, exports.TrackRunTypeEnum.Deleted);
18029
18304
  trackEle.addChild(target.clone(true), 0);
18030
18305
  target.remove();
18031
- this.removeEmtpyInlineBlock(parent);
18306
+ this.removeEmptyInlineBlock(parent);
18032
18307
  }
18033
18308
  /**
18034
18309
  * 更新文本删除留痕
@@ -18100,35 +18375,36 @@ class DocumentChange {
18100
18375
  * @returns
18101
18376
  */
18102
18377
  removeElement(control) {
18103
- const prevEle = ElementUtil.getRecursionPrevSiblingElement(control, false, true, this.viewOptions);
18104
- if (!prevEle) {
18105
- const nextEle = ElementUtil.getRecursionNextSiblingElement(control, true, true, this.viewOptions);
18106
- if (nextEle) {
18378
+ let cursorPosition = ElementUtil.getRecursionPrevSiblingElement(control, this.viewOptions);
18379
+ if (!cursorPosition) {
18380
+ cursorPosition = ElementUtil.getRecursionNextSiblingElement(control, this.viewOptions);
18381
+ if (cursorPosition) {
18107
18382
  //this.selectionState.resetRange(nextEle, 0);
18108
- this.setSelectionStateByDeleteEvent(nextEle, 0, control);
18383
+ this.setSelectionStateByDeleteEvent(cursorPosition.ele, cursorPosition.offset, control);
18109
18384
  control.remove();
18110
18385
  return;
18111
18386
  }
18112
18387
  this.selectionState.resetRange(control, 0);
18113
18388
  return;
18114
18389
  }
18115
- if (ElementUtil.isInSameParagraph(control, prevEle)) {
18390
+ if (ElementUtil.isInSameParagraph(control, cursorPosition.ele)) {
18116
18391
  //this.selectionState.resetRange(prevEle, -1);
18117
- this.setSelectionStateByDeleteEvent(prevEle, -1, control);
18392
+ this.setSelectionStateByDeleteEvent(cursorPosition.ele, -1, control);
18118
18393
  control.remove();
18119
18394
  return;
18120
18395
  }
18121
18396
  else {
18122
- const nextEle = ElementUtil.getRecursionNextSiblingElement(control, true, true, this.viewOptions);
18123
- if (nextEle && ElementUtil.getPrevSiblingElement(nextEle) === control) {
18397
+ const cursorPosition = ElementUtil.getRecursionNextSiblingElement(control, this.viewOptions);
18398
+ if (cursorPosition && ElementUtil.getPrevSiblingElement(cursorPosition.ele) === control) {
18124
18399
  //this.selectionState.resetRange(nextEle, 0);
18125
- this.setSelectionStateByDeleteEvent(nextEle, 0, control);
18400
+ this.setSelectionStateByDeleteEvent(cursorPosition.ele, cursorPosition.offset, control);
18126
18401
  control.remove();
18127
18402
  return;
18128
18403
  }
18129
18404
  else {
18130
18405
  //this.selectionState.resetRange(prevEle, -1);
18131
- this.setSelectionStateByDeleteEvent(prevEle, -1, control);
18406
+ //this.setSelectionStateByDeleteEvent(cursorPosition.ele, -1, control);
18407
+ //TODO: 需要检测下
18132
18408
  control.remove();
18133
18409
  return;
18134
18410
  }
@@ -18647,7 +18923,7 @@ class DocumentChange {
18647
18923
  }
18648
18924
  //表单模式:如果复制的是单格式的文本,需要序列化为纯文本处理
18649
18925
  if (this.viewOptions.docMode === exports.DocMode.FormEdit) {
18650
- const pasteString = pasteEles.map(item => ElementSerialize.serializeString(item, { all: false })).join('');
18926
+ const pasteString = pasteEles.map(item => ElementSerialize.serializeString(item)).join('');
18651
18927
  if (pasteString) {
18652
18928
  this.pastePlainText(pasteString);
18653
18929
  }
@@ -18884,7 +19160,10 @@ class DocumentChange {
18884
19160
  }
18885
19161
  validate() {
18886
19162
  const dataEleList = this.docCtx.document.treeFilter(item => item instanceof DataElementInlineGroup);
18887
- const errorEleList = dataEleList.map(item => ({ error: item.validate(), ele: item })).filter(item => item.error);
19163
+ const errorEleList = dataEleList.map(item => ({
19164
+ error: item.validate(),
19165
+ ele: item
19166
+ })).filter(item => item.error);
18888
19167
  if (!errorEleList.length) {
18889
19168
  return true;
18890
19169
  }
@@ -18918,7 +19197,7 @@ class DocumentChange {
18918
19197
  this.setCursorForDeleteAction(text);
18919
19198
  const parent = text.parent;
18920
19199
  text.remove();
18921
- this.removeEmtpyInlineBlock(parent);
19200
+ this.removeEmptyInlineBlock(parent);
18922
19201
  }
18923
19202
  setCursorForDeleteAction(control) {
18924
19203
  const cursorInfo = this.getCursorElementByDeleteAction(control);
@@ -18936,12 +19215,9 @@ class DocumentChange {
18936
19215
  return ele.parent instanceof DataElementInlineGroup || ele.parent instanceof DataElementGroupElement;
18937
19216
  };
18938
19217
  if (isInDataAre(control)) {
18939
- const prevLeafElementInPara = ElementUtil.getRecursionPrevSiblingElement(control, true, true, this.viewOptions);
18940
- if (prevLeafElementInPara && isInDataAre(prevLeafElementInPara)) {
18941
- return {
18942
- ele: prevLeafElementInPara,
18943
- offset: ElementUtil.getElementEndOffset(prevLeafElementInPara)
18944
- };
19218
+ const cursorPosition = ElementUtil.getRecursionPrevSiblingElement(control, this.viewOptions);
19219
+ if (cursorPosition && isInDataAre(cursorPosition.ele)) {
19220
+ return cursorPosition;
18945
19221
  }
18946
19222
  else {
18947
19223
  return {
@@ -18951,27 +19227,21 @@ class DocumentChange {
18951
19227
  }
18952
19228
  }
18953
19229
  }
18954
- const prevLeafElementInPara = ElementUtil.getRecursionPrevSiblingElement(control, false, true, this.viewOptions);
19230
+ const cursorPosition = ElementUtil.getRecursionPrevSiblingElement(control, this.viewOptions);
18955
19231
  //是否为同一段落
18956
- if (prevLeafElementInPara && ElementUtil.isInSameParagraph(prevLeafElementInPara, control)) {
18957
- return {
18958
- ele: prevLeafElementInPara,
18959
- offset: ElementUtil.getElementEndOffset(prevLeafElementInPara)
18960
- };
19232
+ if (cursorPosition && ElementUtil.isInSameParagraph(cursorPosition.ele, control)) {
19233
+ return cursorPosition;
18961
19234
  }
18962
19235
  //同一段落其他元素
18963
- const nextLeafElementInPara = ElementUtil.getRecursionNextSiblingElement(control, true, true, this.viewOptions);
18964
- if (nextLeafElementInPara) {
18965
- return {
18966
- ele: nextLeafElementInPara,
18967
- offset: 0
18968
- };
19236
+ const nextCursorPosition = ElementUtil.getRecursionNextSiblingElement(control, this.viewOptions);
19237
+ if (nextCursorPosition) {
19238
+ return nextCursorPosition;
18969
19239
  }
18970
19240
  //上一段落
18971
- if (prevLeafElementInPara) {
19241
+ if (cursorPosition) {
18972
19242
  return {
18973
- ele: prevLeafElementInPara,
18974
- offset: prevLeafElementInPara instanceof PSymbolElement ? 0 : ElementUtil.getElementEndOffset(prevLeafElementInPara)
19243
+ ele: cursorPosition.ele,
19244
+ offset: cursorPosition.ele instanceof PSymbolElement ? 0 : ElementUtil.getElementEndOffset(cursorPosition.ele)
18975
19245
  };
18976
19246
  }
18977
19247
  return null;
@@ -18980,11 +19250,12 @@ class DocumentChange {
18980
19250
  * 移除空行内标签
18981
19251
  * @param ele
18982
19252
  */
18983
- removeEmtpyInlineBlock(ele) {
19253
+ removeEmptyInlineBlock(ele) {
18984
19254
  if (ele instanceof InlineGroupElement && ele.length === 0) {
18985
19255
  const parent = ele.parent;
18986
19256
  ele.remove();
18987
- this.removeEmtpyInlineBlock(parent);
19257
+ //track-run 标签等
19258
+ this.removeEmptyInlineBlock(parent);
18988
19259
  }
18989
19260
  }
18990
19261
  /**
@@ -19798,6 +20069,12 @@ class DocumentSvg {
19798
20069
  const range = this.sso.commRangeSets.get(render.element);
19799
20070
  createMaskVNode(range, selectionMask.mask);
19800
20071
  }
20072
+ if (this.sso.otherRangeSets.has(render.element)) {
20073
+ const ranges = this.sso.otherRangeSets.get(render.element);
20074
+ ranges.forEach(range => {
20075
+ createMaskVNode(range, selectionMask.mask);
20076
+ });
20077
+ }
19801
20078
  }
19802
20079
  getHTMLVNode(docRenders) {
19803
20080
  this.counterMap = {};
@@ -20004,6 +20281,7 @@ class EditorCalendarVNode {
20004
20281
  if (parent) {
20005
20282
  const parentRect = parent.getBoundingClientRect();
20006
20283
  const elmRect = elm.getBoundingClientRect();
20284
+ const top = parseInt(elm.style.top);
20007
20285
  // elmRect.width /= scale;
20008
20286
  // elmRect.height /= scale;
20009
20287
  // parentRect.width /= scale;
@@ -20019,12 +20297,13 @@ class EditorCalendarVNode {
20019
20297
  //elm.style.left = parentRect.width - elmRect.width + 'px';
20020
20298
  }
20021
20299
  if (elmRect.top + elmRect.height > parentRect.top + parentRect.height) {
20022
- const newTop = position.y - position.height - elmRect.height;
20023
- const oldTop = position.y + 5 + position.height;
20300
+ const newTop = top - 5 - position.height - elmRect.height;
20301
+ position.y + 5 + position.height;
20024
20302
  //计算前后的高度的差距,然后判断新的值是否在父元素的范围内,如果不在则使用旧的值
20025
- if (newTop > 0 && oldTop - newTop < elmRect.top - parentRect.top) {
20026
- elm.style.top = (position.y - position.height - elmRect.height) + 'px';
20027
- }
20303
+ // if (newTop > 0 && oldTop - newTop < elmRect.top - parentRect.top) {
20304
+ // elm.style.top = (position.y - position.height - elmRect.height) + 'px';
20305
+ // }
20306
+ elm.style.top = newTop + 'px';
20028
20307
  //elm.style.top = (top - (elmRect.top + elmRect.height - (parentRect.top + parentRect.height))) + 'px';
20029
20308
  //elm.style.top = (position.y - position.height - elmRect.height) + 'px';
20030
20309
  }
@@ -20104,7 +20383,7 @@ class EditorCalendarVNode {
20104
20383
  const sel = 'div.editor-calendar-body-day-item'
20105
20384
  + (day.isCurrentMonth ? ".editor-calendar-body-day-item--current-month" : "")
20106
20385
  + (day.today ? ".editor-calendar-body-day-item--today" : "")
20107
- + (this.selectedDate.value === day.date ? ".editor-calendar-body-day-item--selected" : "");
20386
+ + (this.selectedDate.value === day.date ? ".editor-calendar-item--selected" : "");
20108
20387
  return {
20109
20388
  sel,
20110
20389
  data: {
@@ -20439,21 +20718,23 @@ class EditorCalendarVNode {
20439
20718
  }
20440
20719
  }
20441
20720
 
20721
+ const svgNS = "http://www.w3.org/2000/svg";
20442
20722
  class DocRule {
20443
20723
  docCtx;
20444
20724
  //private ctx!: CanvasRenderingContext2D;
20445
20725
  options;
20446
20726
  //标尺高度
20447
- ruleHeight = 30;
20727
+ ruleHeight = 28;
20728
+ thumbWidth = 12;
20448
20729
  //当前标尺的位置
20449
20730
  thumbX;
20450
20731
  mouseDownPos;
20451
- indentThumbPoints = [];
20452
- hangThumbPoints = [];
20732
+ //private indentThumbPoints: Array<Position> = [];
20733
+ //private hangThumbPoints: Array<Position> = [];
20453
20734
  mouseDownThumbType = 'none';
20454
20735
  viewOptions;
20455
20736
  ss;
20456
- nodes = [];
20737
+ //private nodes: Array<any> = [];
20457
20738
  constructor(docCtx) {
20458
20739
  this.docCtx = docCtx;
20459
20740
  this.viewOptions = this.docCtx.viewOptions;
@@ -20469,14 +20750,8 @@ class DocRule {
20469
20750
  indent: 0,
20470
20751
  hanging: 0
20471
20752
  };
20472
- // this.canvas.addEventListener("mousedown", (evt) => this.canvasMousedown(evt));
20473
- // this.canvas.addEventListener("mousemove", (evt) => this.canvasMousemove(evt));
20474
- // this.canvas.addEventListener("mouseup", (evt) => this.canvasMouseup(evt));
20475
20753
  }
20476
20754
  destroy() {
20477
- // this.canvas.removeEventListener("mousedown", this.canvasMousedown);
20478
- // this.canvas.removeEventListener("mousemove", this.canvasMousemove);
20479
- // this.canvas.removeEventListener("mouseup", this.canvasMouseup);
20480
20755
  }
20481
20756
  setRuleOptions(options) {
20482
20757
  this.options = options;
@@ -20487,208 +20762,91 @@ class DocRule {
20487
20762
  //ElementUtil.setCanvasProps(this.canvas, this.ctx, {width: this.getParentWidth(), height: this.ruleHeight});
20488
20763
  //this.canvas.style.left = this.options.docLeft + 'px';
20489
20764
  }
20490
- fillRectSvg(x, y, width, height, color) {
20491
- return ElementUtil.getFillSvgRect(x, y, width, height, color);
20492
- }
20493
- drawIndentThumbSvg(x, y) {
20494
- const points = [];
20495
- x -= 4;
20496
- points.push({ x: x, y });
20497
- points.push({ x: x, y: y + 3 });
20498
- points.push({ x: x + 4, y: y + 7 });
20499
- points.push({ x: x + 8, y: y + 3 });
20500
- points.push({ x: x + 8, y });
20501
- points.push({ x: x, y });
20502
- this.drawLineSvg(points);
20503
- return points;
20504
- }
20505
- drawHangThumbSvg(x, y) {
20506
- const points = [];
20507
- x -= 4;
20508
- points.push({ x: x, y });
20509
- points.push({ x: x, y: y - 3 });
20510
- points.push({ x: x + 4, y: y - 7 });
20511
- points.push({ x: x + 8, y: y - 3 });
20512
- points.push({ x: x + 8, y });
20513
- points.push({ x: x, y });
20514
- points.push({ x: x, y: y + 3 });
20515
- points.push({ x: x + 8, y: y + 3 });
20516
- points.push({ x: x + 8, y: y });
20517
- this.drawLineSvg(points);
20518
- return points;
20519
- }
20520
- drawLineSvg(points) {
20521
- this.nodes.push(ElementUtil.getStrokeSvgPath(points, "black", 0.5));
20522
- }
20523
- drawTextSvg(text, x, y) {
20524
- this.nodes.push({
20525
- sel: 'text',
20526
- text: text,
20527
- data: {
20528
- ns: "http://www.w3.org/2000/svg",
20529
- attrs: {
20530
- 'dominant-baseline': 'hanging',
20531
- 'font-family': "仿宋",
20532
- 'font-size': 8,
20533
- x,
20534
- y,
20535
- 'text-anchor': 'middle'
20536
- }
20537
- }
20538
- });
20539
- }
20540
20765
  refreshRuleSvg() {
20541
20766
  const editor = this;
20542
20767
  return {
20543
20768
  render() {
20544
- if (!editor.viewOptions.showRule) {
20545
- return null;
20546
- }
20547
- editor.nodes = [];
20548
- editor.drawRuleSvg();
20549
- const node = {
20550
- sel: 'g', data: {
20551
- ns: 'http://www.w3.org/2000/svg',
20552
- }, children: [...editor.nodes]
20553
- };
20554
- return {
20555
- sel: 'div.doc-rule',
20556
- data: {
20557
- style: {
20558
- left: `${editor.options.docLeft}px`,
20559
- },
20560
- on: {
20561
- mousedown: (evt) => editor.canvasMousedown(evt),
20562
- mousemove: (evt) => editor.canvasMousemove(evt),
20563
- mouseup: (evt) => editor.canvasMouseup(evt)
20564
- }
20565
- },
20566
- children: [
20567
- {
20568
- sel: 'svg',
20569
- data: {
20570
- ns: 'http://www.w3.org/2000/svg',
20571
- attrs: {
20572
- width: editor.options.width,
20573
- height: editor.ruleHeight
20574
- }
20575
- },
20576
- children: [node]
20577
- }
20578
- ]
20579
- };
20769
+ return editor.getRuleSVG();
20580
20770
  }
20581
20771
  };
20582
20772
  }
20583
- canvasMousedown(evt) {
20584
- const clickPos = this.getMousePos(evt);
20585
- if (this.pointInPoly(clickPos, this.indentThumbPoints)) {
20586
- this.mouseDownThumbType = 'indent';
20587
- this.mouseDownPos = clickPos;
20588
- }
20589
- else if (this.pointInPoly(clickPos, this.hangThumbPoints)) {
20590
- this.mouseDownThumbType = 'hang';
20591
- this.mouseDownPos = clickPos;
20592
- }
20593
- else {
20594
- console.log("未点击在里面");
20773
+ getRuleSVG() {
20774
+ if (!this.viewOptions.showRule) {
20775
+ return null;
20595
20776
  }
20596
- }
20597
- getMousePos(evt) {
20598
- return {
20599
- x: evt.offsetX,
20600
- y: evt.offsetY
20777
+ //editor.nodes = [];
20778
+ const paraRender = this.getRuleMarksPos();
20779
+ //editor.drawRuleSvg();
20780
+ const leftBg = ElementUtil.getFillSvgRect(0, 0, this.options.pagePL, this.ruleHeight, "rgb(198,198,198)");
20781
+ const rightBg = ElementUtil.getFillSvgRect(this.options.width - this.options.pagePR, 0, this.options.pagePR, this.ruleHeight, "rgb(198,198,198)");
20782
+ const svg = {
20783
+ sel: 'svg',
20784
+ data: {
20785
+ ns: svgNS,
20786
+ attrs: {
20787
+ width: this.options.width,
20788
+ height: this.ruleHeight
20789
+ }
20790
+ },
20791
+ children: [leftBg, rightBg]
20601
20792
  };
20602
- }
20603
- canvasMousemove(evt) {
20604
- if (['indent', 'hang'].indexOf(this.mouseDownThumbType) < 0) {
20605
- return;
20606
- }
20607
- if (!this.mouseDownPos) {
20608
- return;
20609
- }
20610
- const canvasPos = this.getMousePos(evt);
20611
- let moveX = canvasPos.x - this.mouseDownPos.x;
20612
- //至少移动5px再进行修改
20613
- const remainder = moveX % 5;
20614
- if (Math.abs(remainder) < 3) {
20615
- return;
20616
- }
20617
- else {
20618
- if (remainder < 0) {
20619
- moveX -= 5 + remainder;
20620
- }
20621
- else {
20622
- moveX += 5 - remainder;
20623
- }
20624
- }
20625
- if (moveX === 0) {
20626
- return;
20627
- }
20628
- canvasPos.x = this.mouseDownPos.x + moveX;
20629
- const para = this.getCurrPara();
20630
- if (!para) {
20631
- throw new Error('para is null');
20632
- }
20633
- if (this.mouseDownThumbType === 'indent') {
20634
- this.thumbX.indent += moveX;
20635
- this.thumbX.indent = this.thumbX.indent < 0 ? 0 : this.thumbX.indent;
20636
- this.thumbX.indent = this.thumbX.indent > this.options.width ? this.options.width : this.thumbX.indent;
20637
- this.mouseDownPos = canvasPos;
20638
- para.props.indent += moveX;
20639
- this.drawRuleSvg();
20640
- }
20641
- if (this.mouseDownThumbType === 'hang') {
20642
- this.thumbX.hanging += moveX;
20643
- this.thumbX.hanging = this.thumbX.hanging < 0 ? 0 : this.thumbX.hanging;
20644
- this.thumbX.hanging = this.thumbX.hanging > this.options.width ? this.options.width : this.thumbX.hanging;
20645
- this.mouseDownPos = canvasPos;
20646
- para.props.hanging += moveX;
20647
- this.drawRuleSvg();
20648
- }
20649
- }
20650
- canvasMouseup(evt) {
20651
- this.mouseDownThumbType = 'none';
20652
- this.mouseDownPos = null;
20653
- }
20654
- pointInPoly(pt, poly) {
20655
- let c = false;
20656
- for (let i = -1, l = poly.length, j = l - 1; ++i < l; j = i) {
20657
- 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) {
20658
- c = !c;
20659
- }
20660
- }
20661
- return c;
20662
- }
20663
- /**
20664
- * 绘制
20665
- */
20666
- drawRuleSvg() {
20667
- this.getRuleMarksPos();
20668
- this.nodes.push(ElementUtil.getFillSvgRect(0, 0, this.options.pagePL, this.ruleHeight, "rgb(198,198,198)"));
20669
- this.nodes.push(ElementUtil.getFillSvgRect(this.options.width - this.options.pagePR, 0, this.options.pagePR, this.ruleHeight, "rgb(198,198,198)"));
20670
20793
  for (let j = 0; j < 50; j++) {
20671
- const gantWidth = 20;
20672
- const points = [];
20794
+ const gantWidth = 38;
20795
+ //const points: Array<Position> = [];
20673
20796
  const x = j * gantWidth;
20674
20797
  if (x > this.options.width) {
20675
20798
  break;
20676
20799
  }
20677
20800
  const y = 10;
20678
- points.push({ x, y }, { x, y: y + 10 });
20679
- this.drawLineSvg(points);
20680
- this.drawTextSvg(j + '', x + Math.floor(gantWidth / 2), y + 1);
20801
+ svg.children.push(ElementUtil.getStrokeSvgPath([{ x, y }, { x, y: y + 10 }], "black", 0.5));
20802
+ svg.children.push({
20803
+ sel: 'text',
20804
+ text: j,
20805
+ data: {
20806
+ ns: svgNS,
20807
+ attrs: {
20808
+ 'dominant-baseline': 'hanging',
20809
+ 'font-family': "仿宋",
20810
+ 'font-size': 10,
20811
+ x: x + Math.floor(gantWidth / 2),
20812
+ y,
20813
+ 'text-anchor': 'middle'
20814
+ }
20815
+ }
20816
+ });
20681
20817
  }
20682
- this.indentThumbPoints = this.drawIndentThumbSvg(this.thumbX.indent, 6);
20683
- this.hangThumbPoints = this.drawHangThumbSvg(this.thumbX.hanging, 25);
20684
- //this.ctx.restore();
20818
+ const indentThumb = this.createTopThumb();
20819
+ const hangThumb = this.createLeftThumb();
20820
+ this.drawCellMark(svg.children, paraRender);
20821
+ return {
20822
+ sel: 'div.rule-wrapper',
20823
+ data: {
20824
+ style: {
20825
+ transform: 'scale(' + this.viewOptions.scale + ')',
20826
+ 'transform-origin': '0 0'
20827
+ }
20828
+ },
20829
+ children: [{
20830
+ sel: 'div.doc-rule',
20831
+ data: {
20832
+ style: {
20833
+ left: `${this.options.docLeft}px`,
20834
+ }
20835
+ },
20836
+ children: [
20837
+ svg,
20838
+ indentThumb,
20839
+ hangThumb
20840
+ ]
20841
+ }]
20842
+ };
20685
20843
  }
20686
20844
  getRuleMarksPos() {
20687
20845
  const { startControl, startOffset, startHitInfo } = this.ss;
20688
20846
  if (!startControl || !startHitInfo) {
20689
20847
  this.thumbX.indent = 0;
20690
20848
  this.thumbX.hanging = 0;
20691
- return;
20849
+ return null;
20692
20850
  }
20693
20851
  const para = ElementUtil.getParentByType(startControl, ParagraphElement);
20694
20852
  const indent = para.props.indent;
@@ -20706,7 +20864,8 @@ class DocRule {
20706
20864
  this.thumbX.indent = paraRenderPos.x - docRenderPos.x + indent;
20707
20865
  this.thumbX.hanging = paraRenderPos.x - docRenderPos.x + hanging;
20708
20866
  this.options.docLeft = docRender.rect.x + docRender.parent.rect.x;
20709
- this.setParentMarksPosSvg(paraRender);
20867
+ return paraRender;
20868
+ //this.setParentMarksPosSvg(paraRender);
20710
20869
  }
20711
20870
  getCurrPara() {
20712
20871
  const { startControl, startOffset } = this.ss;
@@ -20715,32 +20874,172 @@ class DocRule {
20715
20874
  }
20716
20875
  return ElementUtil.getParentByType(startControl, ParagraphElement);
20717
20876
  }
20718
- setParentMarksPosSvg(childRender) {
20719
- const items = [];
20720
- const parentRender = childRender.parent;
20721
- if (!parentRender || parentRender instanceof DocumentRenderObject) {
20722
- return items;
20877
+ drawCellMark(svgChildren, parentRender) {
20878
+ if (!parentRender) {
20879
+ return;
20723
20880
  }
20724
- if (parentRender instanceof TableRowRenderObject) {
20725
- const docRender = ElementUtil.getParentRender(parentRender, DocumentRenderObject);
20726
- const docRenderPos = ElementUtil.getRenderAbsolutePaintPos(docRender);
20727
- for (let i = 0; i < parentRender.length; i++) {
20728
- const cellRender = parentRender.getChild(i);
20729
- const pos = ElementUtil.getRenderAbsolutePaintPos(cellRender);
20730
- this.drawCellMarkSvg(pos.x - docRenderPos.x, 0, cellRender.padding.left);
20731
- }
20881
+ const tableRowRender = ElementUtil.getParentRender(parentRender, TableRowRenderObject);
20882
+ if (!tableRowRender) {
20883
+ return;
20884
+ }
20885
+ const docRender = ElementUtil.getParentRender(parentRender, DocumentRenderObject);
20886
+ const docRenderPos = ElementUtil.getRenderAbsolutePaintPos(docRender);
20887
+ for (let i = 0; i < tableRowRender.length; i++) {
20888
+ const cellRender = tableRowRender.getChild(i);
20889
+ const pos = ElementUtil.getRenderAbsolutePaintPos(cellRender);
20890
+ svgChildren.push(ElementUtil.getFillSvgRect(pos.x - docRenderPos.x - 1, 0, 2, this.ruleHeight, "#bbb"));
20732
20891
  }
20733
- items.push(...this.setParentMarksPosSvg(parentRender));
20734
- return items;
20735
20892
  }
20736
- drawCellMarkSvg(x, y, width) {
20737
- this.nodes.push(ElementUtil.getFillSvgRect(x, y, width, this.ruleHeight, 'rgb(198,198,198,0.2)'));
20738
- for (let i = 0; i < width; i++) {
20739
- const path = ElementUtil.getStrokeSvgPath(`M${x + i} ${y} L${x + i} ${y + this.ruleHeight}`, 'rgb(198,198,198,0.2)', 0.3);
20740
- path.data.attrs['stroke-dasharray'] = "0.5,0.5";
20741
- this.nodes.push(path);
20893
+ /**
20894
+ * 绘制首行缩进thumb
20895
+ * @returns
20896
+ */
20897
+ createTopThumb() {
20898
+ const para = this.getCurrPara();
20899
+ if (!para) {
20900
+ return null;
20742
20901
  }
20902
+ const onMousedown = (evt) => {
20903
+ evt.preventDefault();
20904
+ //const pos = this.getMousePos(evt);
20905
+ const oldX = evt.x;
20906
+ const para = this.getCurrPara();
20907
+ if (!para) {
20908
+ return;
20909
+ }
20910
+ const indent = para.props.indent;
20911
+ const mousemoveHandler = (e) => {
20912
+ //const pos = this.getMousePos(e);
20913
+ let x = e.x - oldX; // 计算相对于SVG的X坐标
20914
+ x /= this.viewOptions.scale;
20915
+ let snappedX = Math.round(x / 5) * 5; // 捕捉到最近的5像素倍数
20916
+ if (indent + snappedX >= 0) {
20917
+ para.props.indent = indent + snappedX;
20918
+ }
20919
+ };
20920
+ const mouseupHandler = () => {
20921
+ document.removeEventListener('mouseup', mouseupHandler);
20922
+ document.removeEventListener('mousemove', mousemoveHandler);
20923
+ };
20924
+ document.addEventListener('mousemove', mousemoveHandler);
20925
+ document.addEventListener('mouseup', mouseupHandler);
20926
+ };
20927
+ const svg = {
20928
+ sel: "svg",
20929
+ data: {
20930
+ ns: svgNS,
20931
+ attrs: {
20932
+ width: 12,
20933
+ height: 12,
20934
+ viewBox: "0 0 16 16",
20935
+ fill: "none",
20936
+ "stroke-width": 1.5,
20937
+ },
20938
+ },
20939
+ children: [
20940
+ {
20941
+ sel: "g#group-1",
20942
+ data: { ns: svgNS, attrs: { stroke: "white", fill: "white" } },
20943
+ children: [
20944
+ {
20945
+ sel: "path",
20946
+ 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" } },
20947
+ },
20948
+ ],
20949
+ },
20950
+ {
20951
+ sel: "g#group-0",
20952
+ data: { ns: svgNS, attrs: { stroke: "#757575", fill: "#757575" } },
20953
+ children: [
20954
+ {
20955
+ sel: "path",
20956
+ 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" } },
20957
+ },
20958
+ ],
20959
+ },
20960
+ ],
20961
+ };
20962
+ 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] }] };
20743
20963
  }
20964
+ ;
20965
+ /**
20966
+ * 绘制悬挂缩进thumb
20967
+ * @returns
20968
+ */
20969
+ createLeftThumb() {
20970
+ const para = this.getCurrPara();
20971
+ if (!para) {
20972
+ return null;
20973
+ }
20974
+ const onMousedown = (evt) => {
20975
+ evt.preventDefault();
20976
+ const oldX = evt.x;
20977
+ const para = this.getCurrPara();
20978
+ if (!para) {
20979
+ return;
20980
+ }
20981
+ const hanging = para.props.hanging;
20982
+ const mousemoveHandler = (e) => {
20983
+ let x = e.x - oldX; // 计算相对于SVG的X坐标
20984
+ x /= this.viewOptions.scale;
20985
+ let snappedX = Math.round(x / 5) * 5; // 捕捉到最近的5像素倍数
20986
+ if (hanging + snappedX >= 0) {
20987
+ para.props.hanging = hanging + snappedX;
20988
+ }
20989
+ };
20990
+ const mouseupHandler = () => {
20991
+ document.removeEventListener('mouseup', mouseupHandler);
20992
+ document.removeEventListener('mousemove', mousemoveHandler);
20993
+ };
20994
+ document.addEventListener('mousemove', mousemoveHandler);
20995
+ document.addEventListener('mouseup', mouseupHandler);
20996
+ };
20997
+ const svg = {
20998
+ sel: "svg",
20999
+ data: {
21000
+ ns: svgNS,
21001
+ attrs: {
21002
+ width: 12,
21003
+ height: 12,
21004
+ viewBox: "0 0 16 16",
21005
+ fill: "none",
21006
+ "stroke-width": 1.5,
21007
+ },
21008
+ },
21009
+ children: [
21010
+ {
21011
+ sel: "g#group-1",
21012
+ data: { ns: svgNS, attrs: { stroke: "white", fill: "white" } },
21013
+ children: [
21014
+ {
21015
+ sel: "path",
21016
+ 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" } },
21017
+ },
21018
+ ],
21019
+ },
21020
+ {
21021
+ sel: "g#group-0",
21022
+ data: { ns: svgNS, attrs: { stroke: "#757575", fill: "#757575" } },
21023
+ children: [
21024
+ {
21025
+ sel: "path",
21026
+ 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" } },
21027
+ },
21028
+ ],
21029
+ },
21030
+ ],
21031
+ };
21032
+ return {
21033
+ sel: "div.rule-thumb-container.rule-thumb-left",
21034
+ data: {
21035
+ on: {
21036
+ mousedown: (evt) => { onMousedown(evt); }
21037
+ }, style: { left: this.thumbX.hanging - this.thumbWidth / 2 + 'px' }
21038
+ },
21039
+ children: [{ sel: "i.icon-thumb", data: {}, children: [svg] }],
21040
+ };
21041
+ }
21042
+ ;
20744
21043
  }
20745
21044
 
20746
21045
  function calculateOverflow(rect, viewport) {
@@ -20891,6 +21190,250 @@ function calculateDistance(a, b) {
20891
21190
  return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
20892
21191
  }
20893
21192
 
21193
+ class SearchPanel {
21194
+ editor;
21195
+ searchQuery = '';
21196
+ currentIndex = -1;
21197
+ totalMatches = 0;
21198
+ searchResults = [];
21199
+ searchRangeColor = "#ffffb8";
21200
+ currentRangeColor = "#fadb14";
21201
+ inputRef;
21202
+ state = 'close';
21203
+ constructor(editor) {
21204
+ this.editor = editor;
21205
+ }
21206
+ render() {
21207
+ if (this.state === 'close') {
21208
+ return null;
21209
+ }
21210
+ return snabbdom.h('div.editor-search-box', [
21211
+ snabbdom.h('input.search-input', {
21212
+ props: {
21213
+ placeholder: 'Search'
21214
+ },
21215
+ on: {
21216
+ keydown: (evt) => this.onKeydown(evt)
21217
+ },
21218
+ hook: {
21219
+ insert: (vNode) => {
21220
+ this.inputRef = vNode.elm;
21221
+ }
21222
+ }
21223
+ }),
21224
+ snabbdom.h('span.search-count', `${this.currentIndex + 1} of ${this.totalMatches}`),
21225
+ snabbdom.h('button.icon-button', {
21226
+ on: {
21227
+ click: () => this.searchPrevious()
21228
+ }
21229
+ }, [
21230
+ snabbdom.h('span.material-icons', [
21231
+ snabbdom.h('svg', {
21232
+ attrs: {
21233
+ width: '18',
21234
+ height: '18',
21235
+ viewBox: '0 0 24 24',
21236
+ fill: 'none',
21237
+ xmlns: 'http://www.w3.org/2000/svg'
21238
+ }
21239
+ }, [
21240
+ snabbdom.h('path', {
21241
+ attrs: {
21242
+ 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',
21243
+ fill: '#212121'
21244
+ }
21245
+ })
21246
+ ])
21247
+ ])
21248
+ ]),
21249
+ snabbdom.h('button.icon-button', {
21250
+ on: {
21251
+ click: () => this.searchNext()
21252
+ }
21253
+ }, [
21254
+ snabbdom.h('span.material-icons', [
21255
+ snabbdom.h('svg', {
21256
+ attrs: {
21257
+ width: '18',
21258
+ height: '18',
21259
+ viewBox: '0 0 24 24',
21260
+ fill: 'none',
21261
+ xmlns: 'http://www.w3.org/2000/svg'
21262
+ }
21263
+ }, [
21264
+ snabbdom.h('path', {
21265
+ attrs: {
21266
+ 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',
21267
+ fill: '#212121'
21268
+ }
21269
+ })
21270
+ ])
21271
+ ])
21272
+ ]),
21273
+ snabbdom.h('button.icon-button', {
21274
+ on: {
21275
+ click: () => this.destroy()
21276
+ }
21277
+ }, [
21278
+ snabbdom.h('span.material-icons', [
21279
+ snabbdom.h('svg', {
21280
+ attrs: {
21281
+ width: '18',
21282
+ height: '18',
21283
+ viewBox: '0 0 24 24',
21284
+ fill: 'none',
21285
+ xmlns: 'http://www.w3.org/2000/svg'
21286
+ }
21287
+ }, [
21288
+ snabbdom.h('path', {
21289
+ attrs: {
21290
+ 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',
21291
+ fill: '#212121'
21292
+ }
21293
+ })
21294
+ ])
21295
+ ])
21296
+ ])
21297
+ ]);
21298
+ }
21299
+ searchNext() {
21300
+ const searchItem = this.searchResults[this.currentIndex];
21301
+ if (searchItem && searchItem.range) {
21302
+ searchItem.range.rangeColor = this.searchRangeColor;
21303
+ }
21304
+ if (this.totalMatches > 0) {
21305
+ this.currentIndex = this.currentIndex + 1;
21306
+ if (this.currentIndex === this.totalMatches) {
21307
+ this.currentIndex = 0;
21308
+ }
21309
+ this.nagivateToShow();
21310
+ }
21311
+ }
21312
+ ;
21313
+ searchPrevious() {
21314
+ const searchItem = this.searchResults[this.currentIndex];
21315
+ if (searchItem && searchItem.range) {
21316
+ searchItem.range.rangeColor = this.searchRangeColor;
21317
+ }
21318
+ if (this.totalMatches > 0) {
21319
+ this.currentIndex = this.currentIndex - 1;
21320
+ if (this.currentIndex === -1) {
21321
+ this.currentIndex = this.totalMatches - 1;
21322
+ }
21323
+ this.nagivateToShow();
21324
+ }
21325
+ }
21326
+ ;
21327
+ nagivateToShow() {
21328
+ Promise.resolve().then(() => {
21329
+ const searchItem = this.searchResults[this.currentIndex];
21330
+ const range = searchItem.range;
21331
+ //突出显示当前项颜色
21332
+ range["rangeColor"] = this.currentRangeColor;
21333
+ const editor = this.editor;
21334
+ editor.bringToView(searchItem.ele);
21335
+ editor.flushToSchedule();
21336
+ editor.docCtx.onNextView(() => {
21337
+ this.inputRef.focus();
21338
+ });
21339
+ });
21340
+ }
21341
+ onKeydown(e) {
21342
+ if (e.key === "Enter") {
21343
+ e.preventDefault();
21344
+ this.searchInDocument(e);
21345
+ }
21346
+ }
21347
+ ;
21348
+ searchInDocument(e) {
21349
+ // 这里应该是你的搜索逻辑,返回匹配的结果数组
21350
+ const target = e.target;
21351
+ const query = target.value;
21352
+ if (!query) {
21353
+ //清除搜索结果
21354
+ this.clear();
21355
+ return [];
21356
+ }
21357
+ //回车自动转到下一个输入
21358
+ if (this.searchQuery === target.value) {
21359
+ this.searchNext();
21360
+ return;
21361
+ }
21362
+ this.clear();
21363
+ this.searchQuery = target.value;
21364
+ const overlays = this.editor['selectionOverlays'];
21365
+ const textEles = this.editor.docCtx.document.treeFilter((item) => item.type === "text");
21366
+ textEles.forEach((ele) => {
21367
+ const matches = this.findMatches(ele.text, query);
21368
+ matches.forEach((index) => {
21369
+ this.searchResults.push({
21370
+ index,
21371
+ ele,
21372
+ });
21373
+ });
21374
+ });
21375
+ console.log(this.searchResults);
21376
+ overlays.clearOtherRangeSets();
21377
+ this.searchResults.forEach((item) => {
21378
+ const range = {
21379
+ target: item.ele,
21380
+ isFullSelected: false,
21381
+ selectedChildren: [],
21382
+ startOffset: item.index,
21383
+ endOffset: item.index + query.length,
21384
+ rangeColor: this.searchRangeColor,
21385
+ };
21386
+ item.range = range;
21387
+ overlays.addToOtherRangeSets(range);
21388
+ });
21389
+ this.totalMatches = this.searchResults.length;
21390
+ this.currentIndex = -1;
21391
+ this.searchNext();
21392
+ this.editor.docCtx.onNextView(() => {
21393
+ target.focus();
21394
+ });
21395
+ //editor['selectionOverlays']
21396
+ return [];
21397
+ }
21398
+ clear() {
21399
+ this.searchQuery = "";
21400
+ this.searchResults.length = 0;
21401
+ this.currentIndex = -1;
21402
+ this.totalMatches = 0;
21403
+ }
21404
+ destroy() {
21405
+ this.clear();
21406
+ this.state = 'close';
21407
+ const overlays = this.editor["selectionOverlays"];
21408
+ overlays.clearOtherRangeSets();
21409
+ this.editor.flushToSchedule();
21410
+ }
21411
+ findMatches(inputString, pattern) {
21412
+ // 创建一个正则表达式对象
21413
+ const regex = new RegExp(pattern, "g");
21414
+ const matches = [];
21415
+ let match;
21416
+ // 使用正则表达式的exec方法多次搜索字符串以找到所有匹配项
21417
+ while ((match = regex.exec(inputString)) !== null) {
21418
+ matches.push(match.index); // 将匹配的索引位置添加到数组中
21419
+ // 当匹配的模式长度为0时(如匹配空字符串),避免无限循环
21420
+ if (match[0].length === 0) {
21421
+ regex.lastIndex++;
21422
+ }
21423
+ }
21424
+ return matches;
21425
+ }
21426
+ switchVisible() {
21427
+ if (this.state === 'open') {
21428
+ this.state = 'close';
21429
+ }
21430
+ else {
21431
+ this.state = 'open';
21432
+ }
21433
+ this.clear();
21434
+ }
21435
+ }
21436
+
20894
21437
  class DocEditor {
20895
21438
  svgContainer;
20896
21439
  //设置vue 不允许代理
@@ -20939,15 +21482,17 @@ class DocEditor {
20939
21482
  // private suggestions: Array<ISuggestionData> = [];
20940
21483
  //光标keydown事件
20941
21484
  onKeyDownEvent = new Subject();
21485
+ //搜索框
21486
+ searchPanel;
20942
21487
  constructor(svgContainer) {
20943
21488
  this.svgContainer = svgContainer;
20944
21489
  this.createCanvasContext();
20945
21490
  this.viewOptions = new ViewOptions();
20946
21491
  this.documentSelection = new DocumentSelection();
20947
- this.docCtx = new EditorContext(this.documentSelection.selectionState, this.viewOptions);
21492
+ this.selectionState = this.documentSelection.selectionState;
21493
+ this.docCtx = new EditorContext(this.selectionState, this.viewOptions);
20948
21494
  this.viewOptions.copyRightInfo = '电子病历编辑器(XXX版权所有)';
20949
21495
  this.viewOptions.drawCharRectColor = 'green';
20950
- this.viewOptions.showLineRect = true;
20951
21496
  this.viewOptions.docSpace = 20;
20952
21497
  this.viewOptions.defaultFontName = '宋体';
20953
21498
  this.viewOptions.editorVersion = this.version();
@@ -20957,16 +21502,10 @@ class DocEditor {
20957
21502
  width: 1000,
20958
21503
  height: 200
20959
21504
  };
20960
- this.viewOptions.editUser = {
20961
- id: '6666',
20962
- name: '管理员'
20963
- };
20964
- this.viewOptions.fullPageView = false;
20965
21505
  this.createDocViewer();
20966
21506
  this.renderContext = new RenderContext(new PaintContent(this.contentCtx));
20967
21507
  this.renderContext.init({ width: 2, height: 2, scale: 1 });
20968
- this.selectionState = this.documentSelection.selectionState;
20969
- this.selectionOverlays = new SelectionOverlays(this.documentSelection.selectionState);
21508
+ this.selectionOverlays = new SelectionOverlays(this.selectionState);
20970
21509
  this.documentPaginator = new DocumentPaginator(this.renderContext, this.docCtx, this.selectionOverlays);
20971
21510
  this.documentInput = new DocumentInput(this.docCtx);
20972
21511
  this.docComment = new DocumentComment(this.docCtx);
@@ -20974,6 +21513,7 @@ class DocEditor {
20974
21513
  this.documentChange = new DocumentChange(this.elementReader, this.docCtx, this.docComment, this.documentInput);
20975
21514
  this.documentEvent = new DocumentEvent(this.documentPaginator, this.docCtx, this.documentInput);
20976
21515
  this.historyMange = new ElementTrackManage(this.docCtx);
21516
+ this.searchPanel = new SearchPanel(this);
20977
21517
  this.eventBus = new EventBus();
20978
21518
  this.createPatch();
20979
21519
  this.documentEvent.hitInfoChanged.subscribe((hitInfo) => {
@@ -21008,8 +21548,8 @@ class DocEditor {
21008
21548
  this.docCtx.syncRefresh = () => {
21009
21549
  this.flushToSchedule();
21010
21550
  };
21011
- this.viewOptions.onChange.subscribe((type) => {
21012
- this.resetViewer(type);
21551
+ this.viewOptions.onChange.subscribe(() => {
21552
+ this.resetViewer();
21013
21553
  });
21014
21554
  }
21015
21555
  createCanvasContext() {
@@ -21054,7 +21594,7 @@ class DocEditor {
21054
21594
  };
21055
21595
  const listVNode = this.renderDataListVNode();
21056
21596
  const dropContainer = {
21057
- sel: 'div.drop-container',
21597
+ sel: 'div.absolute-container',
21058
21598
  data: {
21059
21599
  style: {
21060
21600
  'transform-origin': '0 0',
@@ -21089,7 +21629,8 @@ class DocEditor {
21089
21629
  style: {
21090
21630
  overflow: 'auto',
21091
21631
  position: 'relative',
21092
- height: "100%"
21632
+ height: "100%",
21633
+ 'transform-origin': '0 0'
21093
21634
  },
21094
21635
  on: {
21095
21636
  scroll: (evt) => {
@@ -21111,8 +21652,9 @@ class DocEditor {
21111
21652
  }
21112
21653
  }
21113
21654
  },
21114
- children: [docContentVNode, dropContainer]
21115
- }, ruleFunc.refreshRuleSvg().render()
21655
+ children: [docContentVNode, dropContainer,]
21656
+ },
21657
+ ruleFunc.refreshRuleSvg().render(), this.searchPanel.render()
21116
21658
  ]
21117
21659
  };
21118
21660
  }
@@ -21511,9 +22053,8 @@ class DocEditor {
21511
22053
  };
21512
22054
  this.onChange();
21513
22055
  }
21514
- resetViewer(type = undefined) {
21515
- const refreshType = type === 'force' ? 'content' : 'appearance';
21516
- if (refreshType === 'content') {
22056
+ resetViewer() {
22057
+ if (this.docCtx.document) {
21517
22058
  this.docCtx.document.pubOnChange('self');
21518
22059
  }
21519
22060
  this.documentPaginator.layoutPages();
@@ -21866,7 +22407,7 @@ class DocEditor {
21866
22407
  setPaperOrient(orientation) {
21867
22408
  this.docCtx.document.props.orient = orientation;
21868
22409
  this.viewOptions.docPageSettings.orient = orientation;
21869
- this.resetViewer('force');
22410
+ this.resetViewer();
21870
22411
  this.selectionState.clear();
21871
22412
  }
21872
22413
  setPaperSize(width, height) {
@@ -21882,13 +22423,17 @@ class DocEditor {
21882
22423
  width = Math.floor(width * this.viewOptions.mmToPixelsRatio);
21883
22424
  height = Math.floor(height * this.viewOptions.mmToPixelsRatio);
21884
22425
  this.viewOptions.docPageSettings = new PageOptions(width, height, docProps.orient);
21885
- this.resetViewer('force');
22426
+ this.resetViewer();
21886
22427
  }
21887
22428
  /**
21888
22429
  * 显示当前元素到视图中
21889
22430
  * @param element
21890
22431
  */
21891
22432
  bringToView(element) {
22433
+ //元素被删除
22434
+ if (!element.parent || !element.paintRenders.length) {
22435
+ return;
22436
+ }
21892
22437
  const ele = element instanceof BranchElement ? ElementUtil.getFirstLeafElement(element) : element;
21893
22438
  if (ele) {
21894
22439
  const region = ElementUtil.getElementRegion(ele);
@@ -21906,10 +22451,16 @@ class DocEditor {
21906
22451
  //处理缩放
21907
22452
  pos.x = pos.x * scale;
21908
22453
  pos.y = pos.y * scale;
21909
- if (pos.y - this.viewOptions.pageOffset.y > 0 && pos.y - this.viewOptions.pageOffset.y < this.viewOptions.viewSettings.height) {
21910
- return;
22454
+ this.viewOptions.pageOffset.y;
22455
+ const scrollHeight = this.viewOptions.viewSettings.height;
22456
+ // 计算中心位置需要的scrollTop
22457
+ var newScrollTop = pos.y - scrollHeight / 2;
22458
+ // 检查newScrollTop是否小于0
22459
+ if (newScrollTop < 0) {
22460
+ newScrollTop = 0; // 保证滚动不会超出容器顶部
21911
22461
  }
21912
- this.scrollContainer.scrollTop = pos.y + 30;
22462
+ // 滚动到新的位置
22463
+ this.scrollContainer.scrollTop = newScrollTop;
21913
22464
  }
21914
22465
  /**
21915
22466
  * 设置当前文档页边距
@@ -22350,6 +22901,7 @@ class DocEditor {
22350
22901
  if (parent) {
22351
22902
  const parentRect = parent.getBoundingClientRect();
22352
22903
  const elmRect = elm.getBoundingClientRect();
22904
+ const top = parseInt(elm.style.top);
22353
22905
  // elmRect.width /= scale;
22354
22906
  // elmRect.height /= scale;
22355
22907
  // parentRect.width /= scale;
@@ -22365,12 +22917,13 @@ class DocEditor {
22365
22917
  //elm.style.left = parentRect.width - elmRect.width + 'px';
22366
22918
  }
22367
22919
  if (elmRect.top + elmRect.height > parentRect.top + parentRect.height) {
22368
- const newTop = position.y - position.height - elmRect.height;
22369
- const oldTop = position.y + 5 + position.height;
22920
+ const newTop = top - 5 - position.height - elmRect.height;
22921
+ position.y + 5 + position.height;
22370
22922
  //计算前后的高度的差距,然后判断新的值是否在父元素的范围内,如果不在则使用旧的值
22371
- if (newTop > 0 && oldTop - newTop < elmRect.top - parentRect.top) {
22372
- elm.style.top = (position.y - position.height - elmRect.height) + 'px';
22373
- }
22923
+ // if (newTop > 0 && oldTop - newTop < elmRect.top - parentRect.top) {
22924
+ // elm.style.top = (position.y - position.height - elmRect.height) + 'px';
22925
+ // }
22926
+ elm.style.top = newTop + 'px';
22374
22927
  //elm.style.top = (top - (elmRect.top + elmRect.height - (parentRect.top + parentRect.height))) + 'px';
22375
22928
  //elm.style.top = (position.y - position.height - elmRect.height) + 'px';
22376
22929
  }
@@ -22481,14 +23034,14 @@ class DocEditor {
22481
23034
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
22482
23035
  }
22483
23036
  version() {
22484
- return "2.2.19";
23037
+ return "2.2.21";
22485
23038
  }
22486
23039
  switchPageHeaderEditor() {
22487
23040
  this.docCtx.document.switchPageHeaderEditor(this.selectionState, null);
22488
23041
  }
22489
23042
  getTextContent() {
22490
23043
  const paras = this.docCtx.document.treeFilter(item => item instanceof ParagraphElement);
22491
- const paraTexts = paras.map(item => ElementSerialize.serializeString(item, { all: false }));
23044
+ const paraTexts = paras.map(item => ElementSerialize.serializeString(item));
22492
23045
  return paraTexts.join('');
22493
23046
  }
22494
23047
  emit(event, args) {
@@ -22653,24 +23206,25 @@ class DocEditor {
22653
23206
  }
22654
23207
  processKeyDownEvent(evt) {
22655
23208
  const keyEvent = new KeyboradElementEvent(this.docCtx);
23209
+ const keyStr = CommonUtil.getKeyCombination(evt);
22656
23210
  keyEvent.sourceEvent = evt;
22657
23211
  if (DocumentEvent.invokeEvent('ElementKeyDown', this.docCtx.selectionState.startControl, keyEvent, 'All')) {
22658
23212
  evt.preventDefault();
22659
23213
  return;
22660
23214
  }
22661
- if (evt.keyCode === 38 || evt.keyCode === 40) {
23215
+ if (['ArrowDown', 'ArrowUp']) {
22662
23216
  if (this.docCtx.suggestions.prepareSuggestions.length) {
22663
23217
  this.onSuggestionsKeydown(evt);
22664
23218
  }
22665
23219
  }
22666
- else if (evt.keyCode === 27) {
23220
+ else if (keyStr === 'Escape') {
22667
23221
  if (this.docCtx.suggestions.prepareSuggestions.length) {
22668
23222
  evt.preventDefault();
22669
23223
  this.docCtx.suggestions.clear();
22670
23224
  this.onPatchVNodeSubject.next();
22671
23225
  }
22672
23226
  }
22673
- else if (evt.keyCode === 13) {
23227
+ else if (keyStr === 'Enter') {
22674
23228
  if (this.docCtx.suggestions.prepareSuggestions.length) {
22675
23229
  evt.preventDefault();
22676
23230
  const suggestions = this.docCtx.suggestions;
@@ -22686,6 +23240,11 @@ class DocEditor {
22686
23240
  }
22687
23241
  }
22688
23242
  }
23243
+ else if (['Ctrl+f', 'Cmd+f'].indexOf(keyStr) > -1) {
23244
+ evt.preventDefault();
23245
+ this.searchPanel.switchVisible();
23246
+ this.onPatchVNodeSubject.next();
23247
+ }
22689
23248
  }
22690
23249
  /**
22691
23250
  * 处理候选词,键盘选择定位
@@ -22832,7 +23391,7 @@ class DocEditor {
22832
23391
  * 在光标处插入内容
22833
23392
  * @param data
22834
23393
  */
22835
- onInsertContent(data) {
23394
+ insertContent(data) {
22836
23395
  this.documentChange.onInsertContent(data);
22837
23396
  }
22838
23397
  }
@@ -27987,9 +28546,7 @@ class DocumentPrintOffscreenBase {
27987
28546
  constructor() {
27988
28547
  this.viewOptions = new ViewOptions();
27989
28548
  this.viewOptions.copyRightInfo = '';
27990
- this.viewOptions.showCharRect = true;
27991
28549
  this.viewOptions.drawCharRectColor = 'green';
27992
- this.viewOptions.showLineRect = true;
27993
28550
  this.viewOptions.docSpace = 20;
27994
28551
  this.viewOptions.reviewWindowWidth = 200;
27995
28552
  this.viewOptions.mmToPixelsRatio = 3.7795001220703126;
@@ -27998,17 +28555,14 @@ class DocumentPrintOffscreenBase {
27998
28555
  width: 1000,
27999
28556
  height: 800
28000
28557
  };
28001
- this.viewOptions.editUser = {
28002
- id: '6666',
28003
- name: '管理员'
28004
- };
28005
28558
  const { canvas, ctx } = this.createCanvas(200, 200);
28006
28559
  const ss = new SelectionState();
28007
28560
  this.docCtx = new EditorContext(ss, this.viewOptions);
28008
28561
  this.renderCtx = this.createRenderCtx(ctx, this.viewOptions, this.docCtx);
28009
28562
  this.documentPaginator = new DocumentPaginator(this.renderCtx, this.docCtx, {
28010
28563
  selectionEleSets: new Map(),
28011
- commRangeSets: new Map()
28564
+ commRangeSets: new Map(),
28565
+ otherRangeSets: new Map()
28012
28566
  });
28013
28567
  this.elementReader = new ElementReader(this.docCtx);
28014
28568
  this.docCtx.syncRefresh = () => {
@@ -28076,7 +28630,8 @@ class DocumentPrintOffscreenBase {
28076
28630
  getSvgNodes(docRenders, printRanges = null) {
28077
28631
  const docSvgHelper = new DocumentSvg(this.viewOptions, {
28078
28632
  selectionEleSets: new Map,
28079
- commRangeSets: new Map()
28633
+ commRangeSets: new Map(),
28634
+ otherRangeSets: new Map()
28080
28635
  }, this.renderCtx); //.getHTMLVNode(docRenders) as Array<EditorVNodeObject>;
28081
28636
  docSvgHelper.mode = 'print';
28082
28637
  const patch = init([
@@ -28148,11 +28703,11 @@ const deleteCurrentParagraph = (evt) => {
28148
28703
  caption: '删除段落', click: () => {
28149
28704
  selectionState.clear();
28150
28705
  const psymbol = ElementUtil.getLastLeafElement(currentElement);
28151
- const nextFocusableEle = ElementUtil.getRecursionNextSiblingElement(psymbol, false, true, viewOptions);
28706
+ const cursorPosition = ElementUtil.getRecursionNextSiblingElement(psymbol, viewOptions);
28152
28707
  const parentContainer = currentElement.parent;
28153
- if (nextFocusableEle) {
28154
- if (nextFocusableEle.parent === parentContainer) {
28155
- selectionState.resetRange(nextFocusableEle, 0);
28708
+ if (cursorPosition) {
28709
+ if (cursorPosition.ele.parent === parentContainer) {
28710
+ selectionState.resetRange(cursorPosition.ele, 0);
28156
28711
  }
28157
28712
  else {
28158
28713
  selectionState.resetRange(parentContainer, 0);
@@ -28193,9 +28748,9 @@ const onTableContextmenu = (evt) => {
28193
28748
  evt.menus.push({
28194
28749
  caption: '删除表格', click: () => {
28195
28750
  selectionState.clear();
28196
- const prevEle = ElementUtil.getRecursionPrevSiblingElement(currentElement, false, true, viewOptions);
28197
- if (prevEle) {
28198
- selectionState.resetRange(prevEle, -1);
28751
+ const cursorPosition = ElementUtil.getRecursionPrevSiblingElement(currentElement, viewOptions);
28752
+ if (cursorPosition) {
28753
+ selectionState.resetRange(cursorPosition.ele, cursorPosition.offset);
28199
28754
  }
28200
28755
  currentElement.remove();
28201
28756
  currentElement.destroy();