@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 +52 -1
- package/index-cjs.js +125 -105
- package/index-cjs.js.map +1 -1
- package/index.js +125 -105
- package/index.js.map +1 -1
- package/med_editor/framework/doc-layout/document-arrange.d.ts +6 -0
- package/med_editor/framework/document-context.d.ts +3 -6
- package/med_editor/framework/document-paginator.d.ts +5 -0
- package/med_editor/framework/element-props.d.ts +0 -1
- package/package.json +1 -1
package/editor.css
CHANGED
@@ -17,7 +17,20 @@
|
|
17
17
|
}
|
18
18
|
|
19
19
|
.data-list > div {
|
20
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
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 ? '
|
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.
|
21442
|
+
ckbVNode.sel += '.checked';
|
21443
|
+
//ckbVNode.data.attrs['checked'] = true;
|
21467
21444
|
}
|
21468
21445
|
return {
|
21469
|
-
sel: 'div', data: {
|
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.
|
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>
|