@hailin-zheng/editor-core 2.2.1 → 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
package/editor.css CHANGED
@@ -17,7 +17,20 @@
17
17
  }
18
18
 
19
19
  .data-list > div {
20
- margin: 15px 10px;
20
+ padding: 10px 6px;
21
+ display: flex;
22
+ align-items: center;
23
+ gap: 10px;
24
+ border-bottom: 1px solid #ccc;
25
+ cursor: default;
26
+ }
27
+
28
+ .data-list > div:hover {
29
+ background-color: #ccc;
30
+ }
31
+
32
+ .data-list > div:last-child {
33
+ border-bottom: none; /* 去掉最后一个列表项的底部边框线 */
21
34
  }
22
35
 
23
36
  @keyframes hover-color {
@@ -163,6 +176,44 @@
163
176
  border: #c9e2f9;
164
177
  background: #c9e2f9;
165
178
  }
179
+ /* 样式化 radio box 的外观 */
180
+ .editor-list-radiobox {
181
+ width: 16px;
182
+ height: 16px;
183
+ border: 1px solid #000;
184
+ border-radius: 50%;
185
+ cursor: pointer;
186
+ display: inline-block;
187
+ position: relative;
188
+ }
189
+ /* 选中状态的样式 */
190
+ .editor-list-radiobox.checked::after {
191
+ content: "";
192
+ width: 8px;
193
+ height: 8px;
194
+ background-color: #007bff;
195
+ border-radius: 50%;
196
+ position: absolute;
197
+ top: 50%;
198
+ left: 50%;
199
+ transform: translate(-50%, -50%);
200
+ }
201
+ /* 样式化 checkbox 的外观 */
202
+ .editor-list-checkbox {
203
+ width: 16px;
204
+ height: 16px;
205
+ border: 1px solid #000;
206
+ cursor: pointer;
207
+ }
208
+ /* 选中状态的样式 */
209
+ .editor-list-checkbox.checked::after {
210
+ content: "✔";
211
+ font-size: 14px;
212
+ color: #007bff;
213
+ display: block;
214
+ text-align: center;
215
+ line-height: 16px;
216
+ }
166
217
 
167
218
  .decorate-container {
168
219
  position: absolute;
package/index-cjs.js CHANGED
@@ -2135,7 +2135,6 @@ class DocumentProps extends INotifyPropertyChanged {
2135
2135
  createUserId;
2136
2136
  createUserName;
2137
2137
  createDate;
2138
- scripts;
2139
2138
  columns = 1;
2140
2139
  version;
2141
2140
  clone(dest) {
@@ -2146,7 +2145,6 @@ class DocumentProps extends INotifyPropertyChanged {
2146
2145
  clone.padding = this.padding.clone();
2147
2146
  clone.headerLine = this.headerLine;
2148
2147
  clone.footerLine = this.footerLine;
2149
- clone.scripts = this.scripts;
2150
2148
  clone.createUserId = this.createUserId;
2151
2149
  clone.createUserName = this.createUserName;
2152
2150
  clone.createDate = this.createDate;
@@ -2166,9 +2164,6 @@ class DocumentProps extends INotifyPropertyChanged {
2166
2164
  createUserName: this.createUserName,
2167
2165
  createUserId: this.createUserId,
2168
2166
  };
2169
- if (this.scripts) {
2170
- props['scripts'] = this.scripts;
2171
- }
2172
2167
  if (this.orient && this.orient !== 'portrait') {
2173
2168
  props['orient'] = this.orient;
2174
2169
  }
@@ -3720,7 +3715,6 @@ class DocumentFactory extends ElementFactory {
3720
3715
  docProps.padding = new PaddingProps(props.padding.top, props.padding.bottom, props.padding.left, props.padding.right);
3721
3716
  docProps.headerLine = props.headerLine ?? 12;
3722
3717
  docProps.footerLine = props.footerLine ?? 12;
3723
- docProps.scripts = props.scripts;
3724
3718
  docProps.createUserId = props.createUserId;
3725
3719
  docProps.createUserName = props.createUserName;
3726
3720
  docProps.createDate = props.createDate;
@@ -6931,7 +6925,7 @@ class CommentElement extends LeafElement {
6931
6925
  constructor() {
6932
6926
  super('comm');
6933
6927
  //this.isDecorate = true;
6934
- this.disableClick = true;
6928
+ //this.disableClick = true;
6935
6929
  this.props = new CommProps();
6936
6930
  this.color = CommonUtil.randomRgbColor(0.5);
6937
6931
  }
@@ -12939,54 +12933,6 @@ class PaintContent {
12939
12933
  }
12940
12934
  }
12941
12935
 
12942
- class DocumentEvalFunc {
12943
- docCtx;
12944
- constructor(docCtx) {
12945
- this.docCtx = docCtx;
12946
- }
12947
- scriptsFunc;
12948
- /**
12949
- * 实例化动态脚本
12950
- */
12951
- initScripts(scripts) {
12952
- this.destroyScripts();
12953
- if (scripts) {
12954
- try {
12955
- const func = new Function("docCtx", scripts);
12956
- this.scriptsFunc = func(this.docCtx);
12957
- }
12958
- catch (e) {
12959
- console.error("自定义标本解析错误", e);
12960
- }
12961
- }
12962
- // const func = (docCtx: DocumentContext) => {
12963
- // const sexELe = docCtx.getControlById('NqoYI')
12964
- // const dyEle = docCtx.getControlById('gTuBI');
12965
- // return () => {
12966
- // if (sexELe && dyEle) {
12967
- // const sexValue = sexELe.getValue();
12968
- // const dyValue = sexValue === '1' ? '男的吗' : sexValue === '2' ? '女的吗' : '难道是人妖吗';
12969
- // dyEle.setValue(dyValue);
12970
- // }
12971
- // };
12972
- // };
12973
- }
12974
- /**
12975
- * 销毁动态脚本实例
12976
- */
12977
- destroyScripts() {
12978
- if (this.scriptsFunc) {
12979
- this.scriptsFunc = null;
12980
- }
12981
- }
12982
- /**
12983
- * 触发动态脚本
12984
- */
12985
- invokedScripts() {
12986
- this.scriptsFunc?.();
12987
- }
12988
- }
12989
-
12990
12936
  /**
12991
12937
  * 当前打开的文档的上下文信息,当前文档所有的属性设置都暴露在上下文中
12992
12938
  */
@@ -12997,16 +12943,17 @@ class EditorContext {
12997
12943
  cursorRect;
12998
12944
  _document;
12999
12945
  syncRefresh;
13000
- dynamicFunc;
13001
12946
  docChange;
13002
12947
  clearPrevDocCb;
13003
12948
  //绘制结束之后回调函数
13004
- //nextViewFn!: (() => void) | null;
13005
12949
  nextViewFns = [];
12950
+ //批注元素存在的标志,用于判断文档空间进行布局
12951
+ commentFlag = false;
12952
+ //留痕元素存在的标志,用于判断文档空间进行布局
12953
+ trackFlag = false;
13006
12954
  constructor(selectionState, viewOptions) {
13007
12955
  this.selectionState = selectionState;
13008
12956
  this.viewOptions = viewOptions;
13009
- this.dynamicFunc = new DocumentEvalFunc(this);
13010
12957
  //this.imageLoader = new DocumentImagesLoader();
13011
12958
  this.selectionState.onChangedEvent.subscribe(() => {
13012
12959
  this.syncRefresh?.();
@@ -13026,7 +12973,6 @@ class EditorContext {
13026
12973
  set document(value) {
13027
12974
  this.clearPrevDocCb?.();
13028
12975
  this._document = value;
13029
- this.initScripts();
13030
12976
  // this.refSub = this._document.refreshSubject.subscribe((data) => {
13031
12977
  // data = data ?? 'content';
13032
12978
  // this.isDirty = this.isDirty || data === 'content';
@@ -13054,8 +13000,6 @@ class EditorContext {
13054
13000
  }
13055
13001
  clear() {
13056
13002
  this.selectionState.clear();
13057
- //this.imageLoader.clear();
13058
- this.dynamicFunc.destroyScripts();
13059
13003
  this.isDirty = false;
13060
13004
  //this.clearEleDepMaps();
13061
13005
  }
@@ -13107,12 +13051,6 @@ class EditorContext {
13107
13051
  this.document.viewOptions.textRowLineMode = !this.document.viewOptions.textRowLineMode;
13108
13052
  this.syncRefresh();
13109
13053
  }
13110
- /**
13111
- * 实例化动态脚本
13112
- */
13113
- initScripts() {
13114
- this.dynamicFunc.initScripts(this.document.props.scripts);
13115
- }
13116
13054
  /**
13117
13055
  * 替换数据元
13118
13056
  */
@@ -13131,6 +13069,15 @@ class EditorContext {
13131
13069
  }
13132
13070
  return this._document.modifyFlag === exports.ModifyFlag.None ? 'appearance' : 'content';
13133
13071
  }
13072
+ adaptiveScale() {
13073
+ if (this.viewOptions.pageLayoutMode !== 'fit-page') {
13074
+ return this.viewOptions.scale;
13075
+ }
13076
+ const docWidth = this.viewOptions.contentWidth;
13077
+ const viewWidth = this.viewOptions.viewSettings.width;
13078
+ const availableWidth = viewWidth * 0.9;
13079
+ return Math.round(availableWidth * 100 / docWidth) / 100;
13080
+ }
13134
13081
  }
13135
13082
  /**
13136
13083
  * 文档上下文
@@ -14296,9 +14243,7 @@ class DocumentArrange {
14296
14243
  execute: this.execute,
14297
14244
  createParaFn: () => this.createDefaultPara()
14298
14245
  };
14299
- doc.clearMarkItems();
14300
- this.clearPaintCache(doc, data);
14301
- //this.docCtx.viewOptions.showReviewWindow = this.docCtx.document.commentsContainerElement.markPairs.length > 0;
14246
+ this.reset(data);
14302
14247
  const docRenders = this.arrangeDoc();
14303
14248
  this.setMeasureCompletedModifyFlag(doc);
14304
14249
  this.cacheDocRenders(docRenders);
@@ -14306,7 +14251,17 @@ class DocumentArrange {
14306
14251
  return docRenders;
14307
14252
  });
14308
14253
  }
14309
- //commentsRender!: CommsContainerRenderObject;
14254
+ /**
14255
+ * 重置文档测量的相关信息
14256
+ * @param data
14257
+ * @private
14258
+ */
14259
+ reset(data) {
14260
+ this.docCtx.document.clearMarkItems();
14261
+ this.docCtx.trackFlag = false;
14262
+ this.docCtx.commentFlag = false;
14263
+ this.clearPaintCache(data.doc, data);
14264
+ }
14310
14265
  arrangeDoc() {
14311
14266
  const doc = this.docCtx.document;
14312
14267
  const docRender = doc.createRenderObject();
@@ -14850,8 +14805,12 @@ class DocumentArrange {
14850
14805
  }
14851
14806
  identifyComment(ele) {
14852
14807
  if (ele instanceof CommentElement) {
14808
+ this.docCtx.commentFlag = true;
14853
14809
  this.docCtx.document.identifyCommMark(ele);
14854
14810
  }
14811
+ else if (ele instanceof TrackRunElement) {
14812
+ this.docCtx.trackFlag = true;
14813
+ }
14855
14814
  }
14856
14815
  cacheDoc;
14857
14816
  cacheDocRenders(docs) {
@@ -14932,8 +14891,31 @@ class DocumentPaginator {
14932
14891
  this.docContainer.rect.width = this.viewOptions.docPageSettings.width;
14933
14892
  const newMeasure = new DocumentArrange(this.docCtx, this.renderContext, this.seo);
14934
14893
  this.docPages = newMeasure.measureDoc();
14894
+ this.adjustTipLayoutWidth();
14935
14895
  this.layoutPages();
14936
14896
  }
14897
+ /**
14898
+ * 处理计算提示框布局宽度
14899
+ * @private
14900
+ */
14901
+ adjustTipLayoutWidth() {
14902
+ let layoutFlag = false;
14903
+ if (this.docCtx.trackFlag && this.docCtx.viewOptions.showTrackChangesTip || this.docCtx.commentFlag) {
14904
+ layoutFlag = true;
14905
+ }
14906
+ if (layoutFlag) {
14907
+ if (this.viewOptions.reviewWindowWidth === 0) {
14908
+ this.viewOptions.reviewWindowWidth = 250;
14909
+ this.viewOptions.scale = this.docCtx.adaptiveScale();
14910
+ }
14911
+ }
14912
+ else {
14913
+ if (this.viewOptions.reviewWindowWidth > 0) {
14914
+ this.viewOptions.reviewWindowWidth = 0;
14915
+ this.viewOptions.scale = this.docCtx.adaptiveScale();
14916
+ }
14917
+ }
14918
+ }
14937
14919
  /**
14938
14920
  * 文档页面显示布局
14939
14921
  */
@@ -16941,7 +16923,7 @@ class DocumentChange {
16941
16923
  if (res && res.isCancel) {
16942
16924
  return;
16943
16925
  }
16944
- this.docComment.syncUpdateComments();
16926
+ //this.docComment.syncUpdateComments();
16945
16927
  if (collapsed) {
16946
16928
  this.onBackspaceElement(startControl, startOffset);
16947
16929
  }
@@ -20361,8 +20343,6 @@ class DocEditor {
20361
20343
  trackChangeState = true;
20362
20344
  flushToSchedule() {
20363
20345
  if (this.docCtx.refreshType === 'content') {
20364
- //触发动态脚本
20365
- this.docCtx.dynamicFunc.invokedScripts();
20366
20346
  this.triggerDocChange();
20367
20347
  }
20368
20348
  if (this.flushTask) {
@@ -20721,14 +20701,7 @@ class DocEditor {
20721
20701
  * @private
20722
20702
  */
20723
20703
  adaptiveScale() {
20724
- if (this.viewOptions.pageLayoutMode !== 'fit-page') {
20725
- return;
20726
- }
20727
- const docWidth = this.docCtx.viewOptions.docPageSettings.width;
20728
- const viewWidth = this.docCtx.viewOptions.viewSettings.width;
20729
- const availableWidth = viewWidth * 0.9;
20730
- const scale = Math.round(availableWidth * 100 / docWidth) / 100;
20731
- this.viewOptions.scale = scale;
20704
+ this.viewOptions.scale = this.docCtx.adaptiveScale();
20732
20705
  }
20733
20706
  /**
20734
20707
  * 缩放视图
@@ -21327,12 +21300,20 @@ class DocEditor {
21327
21300
  },
21328
21301
  children: []
21329
21302
  };
21303
+ const scaleFitContainer = {
21304
+ sel: 'div#scale-fit-container',
21305
+ data: {
21306
+ style: { overflow: 'hidden', height: '0px', }
21307
+ },
21308
+ children: [docContent]
21309
+ };
21330
21310
  if (!this.documentPaginator?.docContainer) {
21331
- return docContent;
21311
+ return scaleFitContainer;
21332
21312
  }
21333
21313
  const tipsContainer = this.createChangeTipContainer();
21334
21314
  this.tipContainer = tipsContainer;
21335
21315
  docContent.data.style.height = this.documentPaginator.getDocumentContainerHeight().height + 'px';
21316
+ scaleFitContainer.data.style['height'] = this.documentPaginator.getDocumentContainerHeight().height * this.viewOptions.scale + 'px';
21336
21317
  const docRenders = this.documentPaginator.docContainer.getItems();
21337
21318
  const svgGenerator = new DocumentSvg(this.viewOptions, this.selectionOverlays, this.renderContext);
21338
21319
  const vNode = svgGenerator.getHTMLVNode(docRenders);
@@ -21340,12 +21321,12 @@ class DocEditor {
21340
21321
  children.push(tipsContainer);
21341
21322
  children.push(...vNode);
21342
21323
  tipsContainer.children?.push(...svgGenerator.changeTips);
21343
- this.updateTipLayoutWidth();
21324
+ //this.updateTipLayoutWidth();
21344
21325
  const sub = this.afterNodePatch.subscribe(() => {
21345
21326
  this.updateTipLayoutAfterPatch();
21346
21327
  sub.unsubscribe();
21347
21328
  });
21348
- return docContent;
21329
+ return scaleFitContainer;
21349
21330
  }
21350
21331
  };
21351
21332
  }
@@ -21454,30 +21435,21 @@ class DocEditor {
21454
21435
  };
21455
21436
  const itemsVNode = options.map(item => {
21456
21437
  const ckbVNode = {
21457
- sel: multiSelect ? 'input.magic-checkbox' : 'input.magic-radio',
21458
- data: {
21459
- attrs: {
21460
- type: 'checkbox',
21461
- name: 'data-list',
21462
- }
21463
- }
21438
+ sel: multiSelect ? 'div.editor-list-checkbox' : 'div.editor-list-radiobox',
21439
+ data: {}
21464
21440
  };
21465
21441
  if (item.checked) {
21466
- ckbVNode.data.attrs['checked'] = true;
21442
+ ckbVNode.sel += '.checked';
21443
+ //ckbVNode.data.attrs['checked'] = true;
21467
21444
  }
21468
21445
  return {
21469
- sel: 'div', data: {}, children: [ckbVNode, {
21446
+ sel: 'div', data: { on: {
21447
+ click: () => {
21448
+ onChangeHandler(item.code);
21449
+ }
21450
+ } }, children: [ckbVNode, {
21470
21451
  sel: 'label',
21471
- data: {
21472
- attrs: {
21473
- //for:"data-list-"+item.code,
21474
- },
21475
- on: {
21476
- click: (evt) => {
21477
- onChangeHandler(item.code);
21478
- }
21479
- }
21480
- },
21452
+ data: {},
21481
21453
  text: item.value
21482
21454
  }]
21483
21455
  };
@@ -21641,7 +21613,7 @@ class DocEditor {
21641
21613
  rule.setRuleOptions({ width: this.viewOptions.docPageSettings.width, pagePL, pagePR, docLeft });
21642
21614
  }
21643
21615
  version() {
21644
- return "2.2.1";
21616
+ return "2.2.2";
21645
21617
  }
21646
21618
  switchPageHeaderEditor() {
21647
21619
  this.docCtx.document.switchPageHeaderEditor(this.selectionState, null);
@@ -21791,6 +21763,54 @@ class DocumentCombine {
21791
21763
  }
21792
21764
  }
21793
21765
 
21766
+ class DocumentEvalFunc {
21767
+ docCtx;
21768
+ constructor(docCtx) {
21769
+ this.docCtx = docCtx;
21770
+ }
21771
+ scriptsFunc;
21772
+ /**
21773
+ * 实例化动态脚本
21774
+ */
21775
+ initScripts(scripts) {
21776
+ this.destroyScripts();
21777
+ if (scripts) {
21778
+ try {
21779
+ const func = new Function("docCtx", scripts);
21780
+ this.scriptsFunc = func(this.docCtx);
21781
+ }
21782
+ catch (e) {
21783
+ console.error("自定义标本解析错误", e);
21784
+ }
21785
+ }
21786
+ // const func = (docCtx: DocumentContext) => {
21787
+ // const sexELe = docCtx.getControlById('NqoYI')
21788
+ // const dyEle = docCtx.getControlById('gTuBI');
21789
+ // return () => {
21790
+ // if (sexELe && dyEle) {
21791
+ // const sexValue = sexELe.getValue();
21792
+ // const dyValue = sexValue === '1' ? '男的吗' : sexValue === '2' ? '女的吗' : '难道是人妖吗';
21793
+ // dyEle.setValue(dyValue);
21794
+ // }
21795
+ // };
21796
+ // };
21797
+ }
21798
+ /**
21799
+ * 销毁动态脚本实例
21800
+ */
21801
+ destroyScripts() {
21802
+ if (this.scriptsFunc) {
21803
+ this.scriptsFunc = null;
21804
+ }
21805
+ }
21806
+ /**
21807
+ * 触发动态脚本
21808
+ */
21809
+ invokedScripts() {
21810
+ this.scriptsFunc?.();
21811
+ }
21812
+ }
21813
+
21794
21814
  function createPrintTemplate({ width, height, orient }) {
21795
21815
  return `
21796
21816
  <!DOCTYPE html>