@univerjs/docs 1.0.0-rc.0 → 1.0.0
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/lib/cjs/facade.js +66 -20
- package/lib/cjs/index.js +347 -64
- package/lib/es/facade.js +66 -20
- package/lib/es/index.js +349 -66
- package/lib/facade.js +66 -20
- package/lib/index.js +349 -66
- package/lib/types/commands/mutations/core-editing.mutation.d.ts +2 -0
- package/lib/types/commands/mutations/doc-structure-mutation-validation.d.ts +2 -1
- package/lib/types/facade/f-document-section.d.ts +28 -0
- package/lib/types/facade/f-document-text-range.d.ts +4 -0
- package/lib/types/facade/f-document.d.ts +29 -13
- package/lib/types/facade/f-univer.d.ts +2 -2
- package/lib/types/layout-worker/config/config.d.ts +8 -0
- package/lib/types/layout-worker/font-loader.d.ts +26 -0
- package/lib/types/layout-worker/index.d.ts +5 -2
- package/lib/types/layout-worker/protocol.d.ts +2 -0
- package/lib/types/layout-worker/worker.d.ts +3 -1
- package/lib/types/plugin.d.ts +1 -0
- package/lib/types/services/doc-layout-executor.service.d.ts +6 -0
- package/lib/types/services/doc-state-change-manager.service.d.ts +2 -0
- package/lib/types/services/doc-state-emit.service.d.ts +1 -0
- package/lib/umd/facade.js +1 -1
- package/lib/umd/index.js +2 -2
- package/package.json +7 -7
package/lib/cjs/index.js
CHANGED
|
@@ -15,7 +15,7 @@ const SetTextSelectionsOperation = {
|
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
//#endregion
|
|
18
|
-
//#region \0@oxc-project+runtime@0.
|
|
18
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/typeof.js
|
|
19
19
|
function _typeof(o) {
|
|
20
20
|
"@babel/helpers - typeof";
|
|
21
21
|
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
@@ -26,7 +26,7 @@ function _typeof(o) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
//#endregion
|
|
29
|
-
//#region \0@oxc-project+runtime@0.
|
|
29
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPrimitive.js
|
|
30
30
|
function toPrimitive(t, r) {
|
|
31
31
|
if ("object" != _typeof(t) || !t) return t;
|
|
32
32
|
var e = t[Symbol.toPrimitive];
|
|
@@ -39,14 +39,14 @@ function toPrimitive(t, r) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
//#endregion
|
|
42
|
-
//#region \0@oxc-project+runtime@0.
|
|
42
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPropertyKey.js
|
|
43
43
|
function toPropertyKey(t) {
|
|
44
44
|
var i = toPrimitive(t, "string");
|
|
45
45
|
return "symbol" == _typeof(i) ? i : i + "";
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
//#endregion
|
|
49
|
-
//#region \0@oxc-project+runtime@0.
|
|
49
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/defineProperty.js
|
|
50
50
|
function _defineProperty(e, r, t) {
|
|
51
51
|
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
52
52
|
value: t,
|
|
@@ -57,7 +57,7 @@ function _defineProperty(e, r, t) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
//#endregion
|
|
60
|
-
//#region \0@oxc-project+runtime@0.
|
|
60
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorateParam.js
|
|
61
61
|
function __decorateParam(paramIndex, decorator) {
|
|
62
62
|
return function(target, key) {
|
|
63
63
|
decorator(target, key, paramIndex);
|
|
@@ -65,7 +65,7 @@ function __decorateParam(paramIndex, decorator) {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
//#endregion
|
|
68
|
-
//#region \0@oxc-project+runtime@0.
|
|
68
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorate.js
|
|
69
69
|
function __decorate(decorators, target, key, desc) {
|
|
70
70
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
71
71
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -292,9 +292,17 @@ function projectFooter(footer) {
|
|
|
292
292
|
* the structured-clone boundary because they do not affect document geometry.
|
|
293
293
|
*/
|
|
294
294
|
function createDocumentLayoutSnapshot(snapshot) {
|
|
295
|
-
const { resources: _resources, body, headers, footers, ...layoutSnapshot } = snapshot;
|
|
295
|
+
const { resources: _resources, body, headers, footers, footnotes, endnotes, ...layoutSnapshot } = snapshot;
|
|
296
296
|
return {
|
|
297
297
|
...layoutSnapshot,
|
|
298
|
+
...footnotes == null ? {} : { footnotes: Object.fromEntries(Object.entries(footnotes).map(([id, note]) => [id, {
|
|
299
|
+
...note,
|
|
300
|
+
body: projectDocumentBody(note.body)
|
|
301
|
+
}])) },
|
|
302
|
+
...endnotes == null ? {} : { endnotes: Object.fromEntries(Object.entries(endnotes).map(([id, note]) => [id, {
|
|
303
|
+
...note,
|
|
304
|
+
body: projectDocumentBody(note.body)
|
|
305
|
+
}])) },
|
|
298
306
|
...body == null ? {} : { body: projectDocumentBody(body) },
|
|
299
307
|
...headers == null ? {} : { headers: Object.fromEntries(Object.entries(headers).map(([headerId, header]) => [headerId, projectHeader(header)])) },
|
|
300
308
|
...footers == null ? {} : { footers: Object.fromEntries(Object.entries(footers).map(([footerId, footer]) => [footerId, projectFooter(footer)])) }
|
|
@@ -367,11 +375,15 @@ function isRichTextEditingMutationParams(value) {
|
|
|
367
375
|
return typeof value === "object" && value != null && "unitId" in value && typeof value.unitId === "string" && "actions" in value;
|
|
368
376
|
}
|
|
369
377
|
function collectCustomBlockViewports(dataModel) {
|
|
370
|
-
var _snapshot$body;
|
|
371
378
|
const snapshot = dataModel.getSnapshot();
|
|
372
379
|
const documentStyle = snapshot.documentStyle;
|
|
373
380
|
const viewports = {};
|
|
374
|
-
|
|
381
|
+
const bodies = [
|
|
382
|
+
snapshot.body,
|
|
383
|
+
...Object.values(snapshot.headers ?? {}).map((header) => header.body),
|
|
384
|
+
...Object.values(snapshot.footers ?? {}).map((footer) => footer.body)
|
|
385
|
+
];
|
|
386
|
+
for (const customBlock of bodies.flatMap((body) => (body === null || body === void 0 ? void 0 : body.customBlocks) ?? [])) {
|
|
375
387
|
var _snapshot$drawings, _documentStyle$pageSi;
|
|
376
388
|
const drawing = (_snapshot$drawings = snapshot.drawings) === null || _snapshot$drawings === void 0 ? void 0 : _snapshot$drawings[customBlock.blockId];
|
|
377
389
|
if (drawing == null) continue;
|
|
@@ -521,19 +533,21 @@ let DocLayoutExecutorService = _DocLayoutExecutorService = class DocLayoutExecut
|
|
|
521
533
|
this._executorReady = executorReady;
|
|
522
534
|
await executorReady;
|
|
523
535
|
} catch (error) {
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
536
|
+
if (this._executor === executor) {
|
|
537
|
+
const recoveryDiagnostic = error instanceof Error ? error.message : String(error);
|
|
538
|
+
this._executor = null;
|
|
539
|
+
this._executorReady = null;
|
|
540
|
+
this._recoveryFailure = {
|
|
541
|
+
diagnostic: recoveryDiagnostic,
|
|
542
|
+
unitId
|
|
543
|
+
};
|
|
544
|
+
this._executorStatus$.next({
|
|
545
|
+
state: "recovering",
|
|
546
|
+
executor: executor.type,
|
|
547
|
+
diagnostic: recoveryDiagnostic,
|
|
548
|
+
recoveryUnitId: unitId
|
|
549
|
+
});
|
|
550
|
+
}
|
|
537
551
|
throw error;
|
|
538
552
|
}
|
|
539
553
|
}
|
|
@@ -558,7 +572,9 @@ let DocLayoutExecutorService = _DocLayoutExecutorService = class DocLayoutExecut
|
|
|
558
572
|
let session = this._sessions.get(unitId);
|
|
559
573
|
if (session != null && session.sourceMutationRevision !== dataModel.getMutationRevision()) session.needsResnapshot = true;
|
|
560
574
|
if (session == null || session.needsResnapshot) session = await this._replaceSession(dataModel);
|
|
575
|
+
if (session.disposed || this._executor !== executor || this._getEligibleModel(unitId) !== dataModel) return null;
|
|
561
576
|
let result = await this._startSynchronizedLayout(executor, session, identity, options, budgetMs);
|
|
577
|
+
if (session.disposed || this._executor !== executor || this._getEligibleModel(unitId) !== dataModel) return null;
|
|
562
578
|
if (result.status === "not-found" || result.status === "resnapshot-required") {
|
|
563
579
|
session = await this._replaceSession(dataModel);
|
|
564
580
|
result = await this._startSynchronizedLayout(executor, session, identity, options, budgetMs);
|
|
@@ -596,7 +612,7 @@ let DocLayoutExecutorService = _DocLayoutExecutorService = class DocLayoutExecut
|
|
|
596
612
|
unitId,
|
|
597
613
|
sessionEpoch: session.sessionEpoch
|
|
598
614
|
}).catch((error) => {
|
|
599
|
-
this._logService.error("[DocLayoutExecutorService]: failed to dispose a Worker session.", error);
|
|
615
|
+
if (this._executor === executor) this._logService.error("[DocLayoutExecutorService]: failed to dispose a Worker session.", error);
|
|
600
616
|
});
|
|
601
617
|
}
|
|
602
618
|
this._sessions.clear();
|
|
@@ -686,6 +702,7 @@ let DocLayoutExecutorService = _DocLayoutExecutorService = class DocLayoutExecut
|
|
|
686
702
|
return result;
|
|
687
703
|
});
|
|
688
704
|
session.queue = startTask.then(() => void 0, (error) => {
|
|
705
|
+
if (session.disposed || this._executor !== executor) return;
|
|
689
706
|
session.needsResnapshot = true;
|
|
690
707
|
this._logService.error("[DocLayoutExecutorService]: synchronized layout start failed.", error);
|
|
691
708
|
});
|
|
@@ -739,23 +756,25 @@ let DocLayoutExecutorService = _DocLayoutExecutorService = class DocLayoutExecut
|
|
|
739
756
|
try {
|
|
740
757
|
await createTask;
|
|
741
758
|
} catch (error) {
|
|
742
|
-
session.
|
|
743
|
-
|
|
759
|
+
if (!session.disposed && this._executor === executor) {
|
|
760
|
+
session.needsResnapshot = true;
|
|
761
|
+
throw error;
|
|
762
|
+
}
|
|
744
763
|
}
|
|
745
764
|
return session;
|
|
746
765
|
}
|
|
747
766
|
_disposeSession(unitId) {
|
|
748
|
-
var _this$_executor3;
|
|
749
767
|
const session = this._sessions.get(unitId);
|
|
750
768
|
if (session == null) return;
|
|
751
769
|
this._markSessionDisposed(session);
|
|
752
770
|
this._sessions.delete(unitId);
|
|
753
771
|
this._hydrationSamples.delete(unitId);
|
|
754
|
-
|
|
772
|
+
const executor = this._executor;
|
|
773
|
+
executor === null || executor === void 0 || executor.disposeSession({
|
|
755
774
|
unitId,
|
|
756
775
|
sessionEpoch: session.sessionEpoch
|
|
757
776
|
}).catch((error) => {
|
|
758
|
-
this._logService.error("[DocLayoutExecutorService]: failed to dispose a Worker session.", error);
|
|
777
|
+
if (this._executor === executor) this._logService.error("[DocLayoutExecutorService]: failed to dispose a Worker session.", error);
|
|
759
778
|
});
|
|
760
779
|
}
|
|
761
780
|
_getEligibleModel(unitId) {
|
|
@@ -911,7 +930,7 @@ let DocSkeletonManagerService = class DocSkeletonManagerService extends _univerj
|
|
|
911
930
|
supportsIncrementalLayout() {
|
|
912
931
|
var _this$_context$unit$g;
|
|
913
932
|
const documentFlavor = (_this$_context$unit$g = this._context.unit.getSnapshot().documentStyle) === null || _this$_context$unit$g === void 0 ? void 0 : _this$_context$unit$g.documentFlavor;
|
|
914
|
-
return this._docLayoutExecutorService.getExecutor() != null && !(0, _univerjs_core.isInternalEditorID)(this._context.unitId) && (documentFlavor === _univerjs_core.DocumentFlavor.TRADITIONAL || documentFlavor === _univerjs_core.DocumentFlavor.MODERN);
|
|
933
|
+
return this._docLayoutExecutorService.getExecutor() != null && !(0, _univerjs_core.isInternalEditorID)(this._context.unitId) && !(0, _univerjs_engine_render.getDocumentLayoutPresentation)(this._context.unit) && (documentFlavor === _univerjs_core.DocumentFlavor.TRADITIONAL || documentFlavor === _univerjs_core.DocumentFlavor.MODERN);
|
|
915
934
|
}
|
|
916
935
|
recalculate() {
|
|
917
936
|
const skeleton = this._skeleton;
|
|
@@ -1069,23 +1088,136 @@ function getSegmentType(documentDataModel, segmentId) {
|
|
|
1069
1088
|
if ((_documentDataModel$ge = documentDataModel.getSnapshot().notes) === null || _documentDataModel$ge === void 0 ? void 0 : _documentDataModel$ge[segmentId]) return "note";
|
|
1070
1089
|
return "body";
|
|
1071
1090
|
}
|
|
1072
|
-
function
|
|
1091
|
+
function getSnapshotBody(snapshot, segmentId) {
|
|
1092
|
+
var _snapshot$headers, _snapshot$footers, _snapshot$notes;
|
|
1093
|
+
if (!segmentId) return snapshot.body;
|
|
1094
|
+
return ((_snapshot$headers = snapshot.headers) === null || _snapshot$headers === void 0 || (_snapshot$headers = _snapshot$headers[segmentId]) === null || _snapshot$headers === void 0 ? void 0 : _snapshot$headers.body) ?? ((_snapshot$footers = snapshot.footers) === null || _snapshot$footers === void 0 || (_snapshot$footers = _snapshot$footers[segmentId]) === null || _snapshot$footers === void 0 ? void 0 : _snapshot$footers.body) ?? ((_snapshot$notes = snapshot.notes) === null || _snapshot$notes === void 0 || (_snapshot$notes = _snapshot$notes[segmentId]) === null || _snapshot$notes === void 0 ? void 0 : _snapshot$notes.body);
|
|
1095
|
+
}
|
|
1096
|
+
function containsTextXEdit(actions) {
|
|
1097
|
+
const cursor = _univerjs_core.JSON1.type.readCursor(actions);
|
|
1098
|
+
let found = false;
|
|
1099
|
+
cursor.traverse(null, (component) => {
|
|
1100
|
+
if (component.et === _univerjs_core.TextX.id) found = true;
|
|
1101
|
+
});
|
|
1102
|
+
return found;
|
|
1103
|
+
}
|
|
1104
|
+
function subtractBaselineIssues(issues, baseline) {
|
|
1105
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1106
|
+
baseline.forEach((issue) => counts.set(issue.code, (counts.get(issue.code) ?? 0) + 1));
|
|
1107
|
+
return issues.filter((issue) => {
|
|
1108
|
+
const count = counts.get(issue.code) ?? 0;
|
|
1109
|
+
if (count === 0) return true;
|
|
1110
|
+
counts.set(issue.code, count - 1);
|
|
1111
|
+
return false;
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
function assertValidDocBodyStructure(documentDataModel, segmentId, undoActions) {
|
|
1073
1115
|
var _documentDataModel$ge2;
|
|
1074
1116
|
const segmentModel = documentDataModel.getSelfOrHeaderFooterModel(segmentId);
|
|
1075
1117
|
const body = segmentModel === null || segmentModel === void 0 ? void 0 : segmentModel.getBody();
|
|
1076
1118
|
if (!body) return;
|
|
1077
1119
|
const segmentType = getSegmentType(documentDataModel, segmentId);
|
|
1120
|
+
const context = {
|
|
1121
|
+
segmentType,
|
|
1122
|
+
segmentId: segmentId || void 0
|
|
1123
|
+
};
|
|
1078
1124
|
const note = (_documentDataModel$ge2 = documentDataModel.getSnapshot().notes) === null || _documentDataModel$ge2 === void 0 ? void 0 : _documentDataModel$ge2[segmentId];
|
|
1079
1125
|
const issues = note ? (0, _univerjs_core.validateDocumentStructure)({ notes: { [segmentId]: note } }) : (0, _univerjs_core.validateDocBodyStructure)(body, {
|
|
1080
1126
|
segmentType,
|
|
1081
1127
|
segmentId: segmentId || void 0
|
|
1082
1128
|
});
|
|
1083
1129
|
if (!issues.length) return;
|
|
1084
|
-
const
|
|
1130
|
+
const snapshot = _univerjs_core.Tools.deepClone(documentDataModel.getSnapshot());
|
|
1131
|
+
const baselineBody = getSnapshotBody(_univerjs_core.JSONX.apply(snapshot, undoActions), segmentId);
|
|
1132
|
+
const newIssues = baselineBody ? subtractBaselineIssues(issues, (0, _univerjs_core.validateDocBodyStructure)(baselineBody, context)) : issues;
|
|
1133
|
+
if (!newIssues.length) return;
|
|
1134
|
+
const detail = newIssues.map((issue) => `${issue.code}${issue.index == null ? "" : `@${issue.index}`}`).join(", ");
|
|
1085
1135
|
const segmentLabel = segmentId ? `${segmentType} ${segmentId}` : segmentType;
|
|
1086
1136
|
throw new Error(`[DocStructure] ${segmentLabel}: ${detail}`);
|
|
1087
1137
|
}
|
|
1088
|
-
function
|
|
1138
|
+
function getLockedSdtContent(body, range) {
|
|
1139
|
+
var _range$properties;
|
|
1140
|
+
if (((_range$properties = range.properties) === null || _range$properties === void 0 ? void 0 : _range$properties.kind) !== "group") return body.dataStream.slice(range.startIndex, range.endIndex + 1);
|
|
1141
|
+
const children = (body.customRanges ?? []).filter((child) => child.rangeType === _univerjs_core.CustomRangeType.SDT && child.rangeId !== range.rangeId && child.startIndex >= range.startIndex && child.endIndex <= range.endIndex).sort((left, right) => {
|
|
1142
|
+
const position = left.startIndex - right.startIndex || right.endIndex - left.endIndex;
|
|
1143
|
+
if (position || left.rangeId === right.rangeId) return position;
|
|
1144
|
+
return left.rangeId < right.rangeId ? -1 : 1;
|
|
1145
|
+
});
|
|
1146
|
+
const protectedContent = [];
|
|
1147
|
+
let offset = range.startIndex;
|
|
1148
|
+
for (const child of children) {
|
|
1149
|
+
if (child.startIndex < offset) continue;
|
|
1150
|
+
protectedContent.push(body.dataStream.slice(offset, child.startIndex), child.rangeId);
|
|
1151
|
+
offset = child.endIndex + 1;
|
|
1152
|
+
}
|
|
1153
|
+
protectedContent.push(body.dataStream.slice(offset, range.endIndex + 1));
|
|
1154
|
+
return JSON.stringify(protectedContent);
|
|
1155
|
+
}
|
|
1156
|
+
function getRepeatingItemIds(body, section) {
|
|
1157
|
+
const ranges = body.customRanges ?? [];
|
|
1158
|
+
const sectionIndex = ranges.indexOf(section);
|
|
1159
|
+
const nestedSections = ranges.filter((range, index) => {
|
|
1160
|
+
var _range$properties2;
|
|
1161
|
+
return range.rangeType === _univerjs_core.CustomRangeType.SDT && ((_range$properties2 = range.properties) === null || _range$properties2 === void 0 ? void 0 : _range$properties2.kind) === "repeatingSection" && range.rangeId !== section.rangeId && range.startIndex >= section.startIndex && range.endIndex <= section.endIndex && (range.startIndex > section.startIndex || range.endIndex < section.endIndex || index < sectionIndex);
|
|
1162
|
+
});
|
|
1163
|
+
return ranges.filter((range, index) => {
|
|
1164
|
+
var _range$properties3;
|
|
1165
|
+
return range.rangeType === _univerjs_core.CustomRangeType.SDT && ((_range$properties3 = range.properties) === null || _range$properties3 === void 0 ? void 0 : _range$properties3.kind) === "repeatingSectionItem" && range.startIndex >= section.startIndex && range.endIndex <= section.endIndex && !nestedSections.some((nested) => nested.startIndex <= range.startIndex && range.endIndex <= nested.endIndex && (nested.startIndex < range.startIndex || range.endIndex < nested.endIndex || index < ranges.indexOf(nested)));
|
|
1166
|
+
}).map((range) => range.rangeId).sort();
|
|
1167
|
+
}
|
|
1168
|
+
function isDocSdtMutationAllowed(documentDataModel, segmentId, actions) {
|
|
1169
|
+
var _previousBody$customR;
|
|
1170
|
+
if (!containsTextXEdit(actions) && isStructurePreservingJSONXEdit(actions, (0, _univerjs_core.getRichTextEditPath)(documentDataModel, segmentId))) return true;
|
|
1171
|
+
const snapshot = documentDataModel.getSnapshot();
|
|
1172
|
+
const previousBody = getSnapshotBody(snapshot, segmentId);
|
|
1173
|
+
const lockedRanges = previousBody === null || previousBody === void 0 || (_previousBody$customR = previousBody.customRanges) === null || _previousBody$customR === void 0 ? void 0 : _previousBody$customR.filter((range) => {
|
|
1174
|
+
var _range$properties4, _range$properties5, _range$properties$rep;
|
|
1175
|
+
return range.rangeType === _univerjs_core.CustomRangeType.SDT && (((_range$properties4 = range.properties) === null || _range$properties4 === void 0 ? void 0 : _range$properties4.lock) && range.properties.lock !== "unlocked" || ((_range$properties5 = range.properties) === null || _range$properties5 === void 0 ? void 0 : _range$properties5.kind) === "repeatingSection" && ((_range$properties$rep = range.properties.repeatingSection) === null || _range$properties$rep === void 0 ? void 0 : _range$properties$rep.doNotAllowInsertDelete));
|
|
1176
|
+
});
|
|
1177
|
+
if (!previousBody || !(lockedRanges === null || lockedRanges === void 0 ? void 0 : lockedRanges.length)) return true;
|
|
1178
|
+
const candidate = _univerjs_core.JSONX.apply(_univerjs_core.Tools.deepClone(snapshot), actions);
|
|
1179
|
+
const currentBody = getSnapshotBody(candidate, segmentId);
|
|
1180
|
+
for (const previous of lockedRanges) {
|
|
1181
|
+
var _previous$properties, _currentBody$customRa, _previous$properties2, _previous$properties$;
|
|
1182
|
+
const lock = (_previous$properties = previous.properties) === null || _previous$properties === void 0 ? void 0 : _previous$properties.lock;
|
|
1183
|
+
const current = currentBody === null || currentBody === void 0 || (_currentBody$customRa = currentBody.customRanges) === null || _currentBody$customRa === void 0 ? void 0 : _currentBody$customRa.find((range) => range.rangeId === previous.rangeId && range.rangeType === _univerjs_core.CustomRangeType.SDT);
|
|
1184
|
+
const wrapperLocked = lock === "sdtLocked" || lock === "sdtContentLocked";
|
|
1185
|
+
const contentLocked = lock === "contentLocked" || lock === "sdtContentLocked";
|
|
1186
|
+
if (wrapperLocked && !current) return false;
|
|
1187
|
+
if (((_previous$properties2 = previous.properties) === null || _previous$properties2 === void 0 ? void 0 : _previous$properties2.kind) === "repeatingSection" && ((_previous$properties$ = previous.properties.repeatingSection) === null || _previous$properties$ === void 0 ? void 0 : _previous$properties$.doNotAllowInsertDelete) && current && currentBody) {
|
|
1188
|
+
const before = getRepeatingItemIds(previousBody, previous);
|
|
1189
|
+
const after = getRepeatingItemIds(currentBody, current);
|
|
1190
|
+
if (before.length !== after.length || before.some((id, index) => id !== after[index])) return false;
|
|
1191
|
+
}
|
|
1192
|
+
if (contentLocked && current && currentBody) {
|
|
1193
|
+
if (getLockedSdtContent(previousBody, previous) !== getLockedSdtContent(currentBody, current) && !isBoundSdtValueUpdate(snapshot, candidate, previous, current, currentBody)) return false;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
return true;
|
|
1197
|
+
}
|
|
1198
|
+
function isBoundSdtValueUpdate(before, after, previous, current, currentBody) {
|
|
1199
|
+
const key = (0, _univerjs_core.getSdtBindingKey)(previous);
|
|
1200
|
+
const value = (0, _univerjs_core.getSdtBindingValue)(currentBody, current);
|
|
1201
|
+
if (!key || key !== (0, _univerjs_core.getSdtBindingKey)(current) || value === void 0) return false;
|
|
1202
|
+
return [
|
|
1203
|
+
"",
|
|
1204
|
+
...Object.keys(before.headers ?? {}),
|
|
1205
|
+
...Object.keys(before.footers ?? {}),
|
|
1206
|
+
...Object.keys(before.notes ?? {})
|
|
1207
|
+
].some((segmentId) => {
|
|
1208
|
+
var _previousBody$customR2;
|
|
1209
|
+
const previousBody = getSnapshotBody(before, segmentId);
|
|
1210
|
+
const nextBody = getSnapshotBody(after, segmentId);
|
|
1211
|
+
if (!previousBody || !nextBody) return false;
|
|
1212
|
+
return ((_previousBody$customR2 = previousBody.customRanges) === null || _previousBody$customR2 === void 0 ? void 0 : _previousBody$customR2.some((range) => {
|
|
1213
|
+
var _range$properties6, _range$properties7, _nextBody$customRange;
|
|
1214
|
+
if (range.rangeType !== _univerjs_core.CustomRangeType.SDT || ((_range$properties6 = range.properties) === null || _range$properties6 === void 0 ? void 0 : _range$properties6.lock) === "contentLocked" || ((_range$properties7 = range.properties) === null || _range$properties7 === void 0 ? void 0 : _range$properties7.lock) === "sdtContentLocked" || (0, _univerjs_core.getSdtBindingKey)(range) !== key) return false;
|
|
1215
|
+
const next = (_nextBody$customRange = nextBody.customRanges) === null || _nextBody$customRange === void 0 ? void 0 : _nextBody$customRange.find((item) => item.rangeType === _univerjs_core.CustomRangeType.SDT && item.rangeId === range.rangeId);
|
|
1216
|
+
return next != null && (0, _univerjs_core.getSdtBindingKey)(next) === key && (0, _univerjs_core.getSdtBindingValue)(previousBody, range) !== value && (0, _univerjs_core.getSdtBindingValue)(nextBody, next) === value;
|
|
1217
|
+
})) ?? false;
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
function validateDocStructureMutation(documentDataModel, segmentId, actions, undoActions, isHistoryReplay = false) {
|
|
1089
1221
|
const editPath = (0, _univerjs_core.getRichTextEditPath)(documentDataModel, segmentId);
|
|
1090
1222
|
const preservesStructure = isStructurePreservingJSONXEdit(actions, editPath) && isStructurePreservingJSONXEdit(undoActions, editPath);
|
|
1091
1223
|
let changesFootnoteStructure = false;
|
|
@@ -1094,6 +1226,7 @@ function validateDocStructureMutation(documentDataModel, segmentId, actions, und
|
|
|
1094
1226
|
const path = cursor.getPath();
|
|
1095
1227
|
if (path[0] === "notes" && (path.length <= 2 || path[2] !== "body") || path.includes("customRanges")) changesFootnoteStructure = true;
|
|
1096
1228
|
if (component.et === _univerjs_core.TextX.id && Array.isArray(component.e)) for (const action of component.e) {
|
|
1229
|
+
if (isRecord$3(action) && Array.isArray(action.rangeUpdates) && action.rangeUpdates.some((update) => isRecord$3(update) && isRecord$3(update.range) && (update.range.rangeType === _univerjs_core.CustomRangeType.FOOTNOTE || update.range.rangeType === _univerjs_core.CustomRangeType.ENDNOTE))) changesFootnoteStructure = true;
|
|
1097
1230
|
const ranges = isRecord$3(action) && isRecord$3(action.body) ? action.body.customRanges : void 0;
|
|
1098
1231
|
if (Array.isArray(ranges) && ranges.some((range) => isRecord$3(range) && (range.rangeType === _univerjs_core.CustomRangeType.FOOTNOTE || range.rangeType === _univerjs_core.CustomRangeType.ENDNOTE))) changesFootnoteStructure = true;
|
|
1099
1232
|
}
|
|
@@ -1101,7 +1234,7 @@ function validateDocStructureMutation(documentDataModel, segmentId, actions, und
|
|
|
1101
1234
|
if (changesFootnoteStructure) {
|
|
1102
1235
|
const issues = (0, _univerjs_core.validateDocumentStructure)(documentDataModel.getSnapshot());
|
|
1103
1236
|
if (issues.length > 0) throw new Error(`[DocStructure] ${issues.map((issue) => `${issue.code}@${issue.index ?? issue.segmentId ?? ""}`).join(", ")}`);
|
|
1104
|
-
} else if (!preservesStructure) assertValidDocBodyStructure(documentDataModel, segmentId);
|
|
1237
|
+
} else if (!preservesStructure && !isHistoryReplay) assertValidDocBodyStructure(documentDataModel, segmentId, undoActions);
|
|
1105
1238
|
return preservesStructure && !changesFootnoteStructure;
|
|
1106
1239
|
}
|
|
1107
1240
|
|
|
@@ -1157,12 +1290,12 @@ function canRemoveFootnoteReference(actions, references) {
|
|
|
1157
1290
|
if (path.length === 1 && component.et === _univerjs_core.TextX.id && Array.isArray(component.e)) {
|
|
1158
1291
|
let offset = 0;
|
|
1159
1292
|
for (const action of component.e) {
|
|
1160
|
-
var _action$body;
|
|
1293
|
+
var _action$body, _action$rangeUpdates;
|
|
1161
1294
|
if (action.t === _univerjs_core.TextXActionType.DELETE && references.some((reference) => offset <= reference.endIndex && offset + action.len > reference.startIndex)) {
|
|
1162
1295
|
canRemove = true;
|
|
1163
1296
|
return;
|
|
1164
1297
|
}
|
|
1165
|
-
if (action.t === _univerjs_core.TextXActionType.RETAIN && ((_action$body = action.body) === null || _action$body === void 0 ? void 0 : _action$body.customRanges) != null) {
|
|
1298
|
+
if (action.t === _univerjs_core.TextXActionType.RETAIN && (((_action$body = action.body) === null || _action$body === void 0 ? void 0 : _action$body.customRanges) != null || ((_action$rangeUpdates = action.rangeUpdates) === null || _action$rangeUpdates === void 0 ? void 0 : _action$rangeUpdates.some((update) => references.some((reference) => reference.rangeId === update.rangeId))))) {
|
|
1166
1299
|
canRemove = true;
|
|
1167
1300
|
return;
|
|
1168
1301
|
}
|
|
@@ -1193,7 +1326,7 @@ function includeFootnoteCleanup(before, actions) {
|
|
|
1193
1326
|
}
|
|
1194
1327
|
return _univerjs_core.JSONX.isNoop(cleanup) ? actions : _univerjs_core.JSONX.compose(actions, cleanup);
|
|
1195
1328
|
}
|
|
1196
|
-
function applyValidatedDocumentActions(documentDataModel, segmentId, actions) {
|
|
1329
|
+
function applyValidatedDocumentActions(documentDataModel, segmentId, actions, isHistoryReplay = false) {
|
|
1197
1330
|
const before = documentDataModel.getSnapshot();
|
|
1198
1331
|
const appliedActions = includeFootnoteCleanup(before, actions);
|
|
1199
1332
|
const undoActions = _univerjs_core.JSONX.invertWithDoc(appliedActions, before);
|
|
@@ -1202,7 +1335,7 @@ function applyValidatedDocumentActions(documentDataModel, segmentId, actions) {
|
|
|
1202
1335
|
return {
|
|
1203
1336
|
actions: appliedActions,
|
|
1204
1337
|
undoActions,
|
|
1205
|
-
preservesStructure: validateDocStructureMutation(documentDataModel, segmentId, appliedActions, undoActions)
|
|
1338
|
+
preservesStructure: validateDocStructureMutation(documentDataModel, segmentId, appliedActions, undoActions, isHistoryReplay)
|
|
1206
1339
|
};
|
|
1207
1340
|
} catch (error) {
|
|
1208
1341
|
documentDataModel.apply(undoActions);
|
|
@@ -1269,7 +1402,27 @@ const RichTextEditingMutation = {
|
|
|
1269
1402
|
actions: [],
|
|
1270
1403
|
textRanges: docRanges
|
|
1271
1404
|
};
|
|
1272
|
-
const
|
|
1405
|
+
const isHistoryReplay = trigger === _univerjs_core.UndoCommandId || trigger === _univerjs_core.RedoCommandId;
|
|
1406
|
+
if (!isHistoryReplay && !isDocSdtMutationAllowed(documentDataModel, segmentId, actions)) {
|
|
1407
|
+
params.actions = [];
|
|
1408
|
+
return {
|
|
1409
|
+
unitId,
|
|
1410
|
+
actions: [],
|
|
1411
|
+
textRanges: docRanges
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
const presentation = (0, _univerjs_engine_render.getDocumentLayoutPresentation)(documentDataModel);
|
|
1415
|
+
const previousLayoutState = presentation === null || presentation === void 0 ? void 0 : presentation.captureState();
|
|
1416
|
+
const { actions: appliedActions, undoActions, preservesStructure } = applyValidatedDocumentActions(documentDataModel, segmentId, actions, isHistoryReplay);
|
|
1417
|
+
if (presentation) try {
|
|
1418
|
+
if (params.layoutState !== void 0) presentation.restoreState(params.layoutState);
|
|
1419
|
+
else presentation.applyActions(appliedActions, documentDataModel.getSnapshot());
|
|
1420
|
+
params.layoutState = presentation.captureState();
|
|
1421
|
+
} catch (error) {
|
|
1422
|
+
documentDataModel.apply(undoActions);
|
|
1423
|
+
presentation.restoreState(previousLayoutState);
|
|
1424
|
+
throw error;
|
|
1425
|
+
}
|
|
1273
1426
|
params.actions = appliedActions;
|
|
1274
1427
|
resetDocumentViewModel(documentViewModel, documentDataModel, segmentId, appliedActions, preservesStructure);
|
|
1275
1428
|
scheduleDocumentSelectionUpdate(docSelectionManagerService, params, isSync);
|
|
@@ -1281,12 +1434,14 @@ const RichTextEditingMutation = {
|
|
|
1281
1434
|
noHistory,
|
|
1282
1435
|
debounce,
|
|
1283
1436
|
redoState: {
|
|
1437
|
+
...presentation ? { layoutState: params.layoutState } : {},
|
|
1284
1438
|
actions: appliedActions,
|
|
1285
1439
|
textRanges,
|
|
1286
1440
|
options: params.options,
|
|
1287
1441
|
isEditing
|
|
1288
1442
|
},
|
|
1289
1443
|
undoState: {
|
|
1444
|
+
...presentation ? { layoutState: previousLayoutState } : {},
|
|
1290
1445
|
actions: undoActions,
|
|
1291
1446
|
textRanges: prevTextRanges ?? docRanges,
|
|
1292
1447
|
options: selectionInfo === null || selectionInfo === void 0 ? void 0 : selectionInfo.options,
|
|
@@ -1300,6 +1455,7 @@ const RichTextEditingMutation = {
|
|
|
1300
1455
|
return {
|
|
1301
1456
|
unitId,
|
|
1302
1457
|
actions: undoActions,
|
|
1458
|
+
...presentation ? { layoutState: previousLayoutState } : {},
|
|
1303
1459
|
textRanges: docRanges
|
|
1304
1460
|
};
|
|
1305
1461
|
}
|
|
@@ -1416,7 +1572,7 @@ const DeleteTextCommand = {
|
|
|
1416
1572
|
startOffset: start,
|
|
1417
1573
|
endOffset: end + 1,
|
|
1418
1574
|
collapsed: false
|
|
1419
|
-
}], body));
|
|
1575
|
+
}], body, 0, null, true, docDataModel.getDocumentStyle().documentFlavor));
|
|
1420
1576
|
const path = (0, _univerjs_core.getRichTextEditPath)(docDataModel, segmentId);
|
|
1421
1577
|
doMutation.params.actions = appendRemovedDrawingActions(jsonX.editOp(textX.serialize(), path), docDataModel, body, start, end + 1, segmentId);
|
|
1422
1578
|
const result = commandService.syncExecuteCommand(doMutation.id, doMutation.params);
|
|
@@ -2625,7 +2781,7 @@ function composeActions(actions) {
|
|
|
2625
2781
|
//#endregion
|
|
2626
2782
|
//#region package.json
|
|
2627
2783
|
var name = "@univerjs/docs";
|
|
2628
|
-
var version = "1.0.0
|
|
2784
|
+
var version = "1.0.0";
|
|
2629
2785
|
|
|
2630
2786
|
//#endregion
|
|
2631
2787
|
//#region src/config/config.ts
|
|
@@ -3253,6 +3409,20 @@ let DocStateChangeManagerService = class DocStateChangeManagerService extends _u
|
|
|
3253
3409
|
this._initialize();
|
|
3254
3410
|
this._listenDocStateChange();
|
|
3255
3411
|
}
|
|
3412
|
+
dispose() {
|
|
3413
|
+
if (this._historyTimer != null) {
|
|
3414
|
+
clearTimeout(this._historyTimer);
|
|
3415
|
+
this._historyTimer = null;
|
|
3416
|
+
}
|
|
3417
|
+
if (this._changeStateCacheTimer != null) {
|
|
3418
|
+
clearTimeout(this._changeStateCacheTimer);
|
|
3419
|
+
this._changeStateCacheTimer = null;
|
|
3420
|
+
}
|
|
3421
|
+
this._historyStateCache.clear();
|
|
3422
|
+
this._changeStateCache.clear();
|
|
3423
|
+
this._docStateChange$.complete();
|
|
3424
|
+
super.dispose();
|
|
3425
|
+
}
|
|
3256
3426
|
getStateCache(unitId) {
|
|
3257
3427
|
return {
|
|
3258
3428
|
history: this._historyStateCache.get(unitId) ?? [],
|
|
@@ -3266,6 +3436,10 @@ let DocStateChangeManagerService = class DocStateChangeManagerService extends _u
|
|
|
3266
3436
|
clearHistory(unitId) {
|
|
3267
3437
|
this._historyStateCache.delete(unitId);
|
|
3268
3438
|
}
|
|
3439
|
+
flushPendingChanges(unitId) {
|
|
3440
|
+
this._pushHistory(unitId);
|
|
3441
|
+
this._emitChangeState(unitId);
|
|
3442
|
+
}
|
|
3269
3443
|
_setChangeState(changeState) {
|
|
3270
3444
|
this._cacheChangeState(changeState, "history");
|
|
3271
3445
|
this._cacheChangeState(changeState, "collaboration");
|
|
@@ -3304,18 +3478,19 @@ let DocStateChangeManagerService = class DocStateChangeManagerService extends _u
|
|
|
3304
3478
|
const cacheStates = stateCache.get(unitId);
|
|
3305
3479
|
cacheStates === null || cacheStates === void 0 || cacheStates.push(changeState);
|
|
3306
3480
|
} else stateCache.set(unitId, [changeState]);
|
|
3307
|
-
if (debounce)
|
|
3308
|
-
if (
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3481
|
+
if (debounce) {
|
|
3482
|
+
if (type === "history") {
|
|
3483
|
+
if (this._historyTimer) clearTimeout(this._historyTimer);
|
|
3484
|
+
this._historyTimer = setTimeout(() => {
|
|
3485
|
+
cb(unitId);
|
|
3486
|
+
}, DEBOUNCE_DELAY);
|
|
3487
|
+
} else {
|
|
3488
|
+
if (this._changeStateCacheTimer) clearTimeout(this._changeStateCacheTimer);
|
|
3489
|
+
this._changeStateCacheTimer = setTimeout(() => {
|
|
3490
|
+
cb(unitId);
|
|
3491
|
+
}, DEBOUNCE_DELAY);
|
|
3492
|
+
}
|
|
3493
|
+
} else cb(unitId);
|
|
3319
3494
|
}
|
|
3320
3495
|
_pushHistory(unitId) {
|
|
3321
3496
|
const undoRedoService = this._undoRedoService;
|
|
@@ -3327,6 +3502,8 @@ let DocStateChangeManagerService = class DocStateChangeManagerService extends _u
|
|
|
3327
3502
|
const lastState = cacheStates[len - 1];
|
|
3328
3503
|
const redoParams = {
|
|
3329
3504
|
unitId,
|
|
3505
|
+
trigger: _univerjs_core.RedoCommandId,
|
|
3506
|
+
...lastState.redoState.layoutState === void 0 ? {} : { layoutState: lastState.redoState.layoutState },
|
|
3330
3507
|
actions: cacheStates.reduce((acc, cur) => _univerjs_core.JSONX.compose(acc, cur.redoState.actions), null),
|
|
3331
3508
|
textRanges: lastState.redoState.textRanges,
|
|
3332
3509
|
segmentId: lastState.segmentId,
|
|
@@ -3335,6 +3512,8 @@ let DocStateChangeManagerService = class DocStateChangeManagerService extends _u
|
|
|
3335
3512
|
};
|
|
3336
3513
|
const undoParams = {
|
|
3337
3514
|
unitId,
|
|
3515
|
+
trigger: _univerjs_core.UndoCommandId,
|
|
3516
|
+
...firstState.undoState.layoutState === void 0 ? {} : { layoutState: firstState.undoState.layoutState },
|
|
3338
3517
|
actions: cacheStates.reverse().reduce((acc, cur) => _univerjs_core.JSONX.compose(acc, cur.undoState.actions), null),
|
|
3339
3518
|
textRanges: firstState.undoState.textRanges,
|
|
3340
3519
|
segmentId: firstState.segmentId,
|
|
@@ -3488,6 +3667,25 @@ let UniverDocsPlugin = class UniverDocsPlugin extends _univerjs_core.Plugin {
|
|
|
3488
3667
|
this.disposeWithMe(this._injector.get(_univerjs_core.ObjectPermissionService).registerRuleModel(_univerjs_protocol.UnitObject.Document, this._injector.get(DocumentPermissionRuleModel), SetDocumentPermissionRuleMutation.id, SetDocumentPermissionRulesMutation.id));
|
|
3489
3668
|
this._initializeDependencies();
|
|
3490
3669
|
this._initializeCommands();
|
|
3670
|
+
this._initializeWordResources();
|
|
3671
|
+
}
|
|
3672
|
+
_initializeWordResources() {
|
|
3673
|
+
for (const pluginName of ["DOC_WORD_STYLES_PLUGIN", "DOC_NOTE_PLUGIN"]) {
|
|
3674
|
+
const resources = /* @__PURE__ */ new Map();
|
|
3675
|
+
this.disposeWithMe({ dispose: () => resources.clear() });
|
|
3676
|
+
this.disposeWithMe(this._injector.get(_univerjs_core.IResourceManagerService).registerPluginResource({
|
|
3677
|
+
pluginName,
|
|
3678
|
+
businesses: [_univerjs_core.UniverInstanceType.UNIVER_DOC],
|
|
3679
|
+
parseJson: (data) => data,
|
|
3680
|
+
onLoad: (unitId, data) => {
|
|
3681
|
+
resources.set(unitId, data);
|
|
3682
|
+
},
|
|
3683
|
+
onUnLoad: (unitId) => {
|
|
3684
|
+
resources.delete(unitId);
|
|
3685
|
+
},
|
|
3686
|
+
toJson: (unitId) => resources.get(unitId) ?? ""
|
|
3687
|
+
}));
|
|
3688
|
+
}
|
|
3491
3689
|
}
|
|
3492
3690
|
_initializeCommands() {
|
|
3493
3691
|
[
|
|
@@ -3586,6 +3784,12 @@ function collectDocumentFontFamilies(value, families) {
|
|
|
3586
3784
|
}
|
|
3587
3785
|
return;
|
|
3588
3786
|
}
|
|
3787
|
+
const textStyle = value;
|
|
3788
|
+
if (typeof textStyle.eastAsiaFontFamily === "string" && textStyle.eastAsiaFontFamily.trim()) {
|
|
3789
|
+
const primary = typeof textStyle.ff === "string" && textStyle.ff.trim() ? textStyle.ff : _univerjs_core.DEFAULT_STYLES.ff;
|
|
3790
|
+
families.add(`${primary}, ${textStyle.eastAsiaFontFamily.trim()}`);
|
|
3791
|
+
families.add(`${textStyle.eastAsiaFontFamily.trim()}, ${primary}, ${textStyle.eastAsiaFontFamily.trim()}`);
|
|
3792
|
+
}
|
|
3589
3793
|
for (const [key, item] of Object.entries(value)) if (key === "ff" && typeof item === "string") families.add(item);
|
|
3590
3794
|
else collectDocumentFontFamilies(item, families);
|
|
3591
3795
|
}
|
|
@@ -3599,6 +3803,53 @@ function measureDocumentFontFamilies(families) {
|
|
|
3599
3803
|
return _univerjs_engine_render.FontCache.getNormalLineHeightCache();
|
|
3600
3804
|
}
|
|
3601
3805
|
|
|
3806
|
+
//#endregion
|
|
3807
|
+
//#region src/layout-worker/font-loader.ts
|
|
3808
|
+
/** Owns the same explicitly supplied font faces in the rendering and layout realms. */
|
|
3809
|
+
var DocsLayoutFontLoader = class extends _univerjs_core.Disposable {
|
|
3810
|
+
constructor(..._args) {
|
|
3811
|
+
super(..._args);
|
|
3812
|
+
_defineProperty(this, "_loading", null);
|
|
3813
|
+
_defineProperty(this, "_fontSet", void 0);
|
|
3814
|
+
_defineProperty(this, "_faces", []);
|
|
3815
|
+
}
|
|
3816
|
+
load(fonts) {
|
|
3817
|
+
this._loading ??= this._load(fonts);
|
|
3818
|
+
return this._loading;
|
|
3819
|
+
}
|
|
3820
|
+
dispose() {
|
|
3821
|
+
for (const face of this._faces) {
|
|
3822
|
+
var _this$_fontSet;
|
|
3823
|
+
(_this$_fontSet = this._fontSet) === null || _this$_fontSet === void 0 || _this$_fontSet.delete(face);
|
|
3824
|
+
}
|
|
3825
|
+
if (this._faces.length > 0) _univerjs_engine_render.FontCache.invalidateMetrics(() => true);
|
|
3826
|
+
this._faces = [];
|
|
3827
|
+
this._fontSet = void 0;
|
|
3828
|
+
super.dispose();
|
|
3829
|
+
}
|
|
3830
|
+
async _load(fonts) {
|
|
3831
|
+
this.ensureNotDisposed();
|
|
3832
|
+
if (fonts.length === 0) return;
|
|
3833
|
+
const fontSet = typeof document === "undefined" ? globalThis.fonts : document.fonts;
|
|
3834
|
+
if (typeof FontFace === "undefined" || fontSet == null) throw new Error("Document layout requires FontFace support to load the configured fonts.");
|
|
3835
|
+
try {
|
|
3836
|
+
const faces = fonts.map(({ family, source, descriptors }) => {
|
|
3837
|
+
if (!family.trim() || (typeof source === "string" ? !source.trim() : source.byteLength === 0)) throw new TypeError("Document layout font family and source must not be empty.");
|
|
3838
|
+
return new FontFace(family, source, descriptors);
|
|
3839
|
+
});
|
|
3840
|
+
await Promise.all(faces.map((face) => face.load()));
|
|
3841
|
+
this.ensureNotDisposed();
|
|
3842
|
+
this._fontSet = fontSet;
|
|
3843
|
+
this._faces = faces;
|
|
3844
|
+
for (const face of faces) fontSet.add(face);
|
|
3845
|
+
_univerjs_engine_render.FontCache.invalidateMetrics(() => true);
|
|
3846
|
+
} catch (error) {
|
|
3847
|
+
this.dispose();
|
|
3848
|
+
throw error;
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3851
|
+
};
|
|
3852
|
+
|
|
3602
3853
|
//#endregion
|
|
3603
3854
|
//#region src/layout-worker/performance-tracker.ts
|
|
3604
3855
|
const PERFORMANCE_SAMPLE_LIMIT = 2048;
|
|
@@ -3711,10 +3962,11 @@ var DocsLayoutWorkerRuntime = class {
|
|
|
3711
3962
|
constructor(_performanceTracker = new DocsLayoutWorkerPerformanceTracker()) {
|
|
3712
3963
|
this._performanceTracker = _performanceTracker;
|
|
3713
3964
|
_defineProperty(this, "_sessions", /* @__PURE__ */ new Map());
|
|
3965
|
+
_defineProperty(this, "_fontLoader", new DocsLayoutFontLoader());
|
|
3714
3966
|
_defineProperty(this, "type", "worker");
|
|
3715
3967
|
}
|
|
3716
|
-
initialize() {
|
|
3717
|
-
return
|
|
3968
|
+
initialize(fontFaces = []) {
|
|
3969
|
+
return this._fontLoader.load(fontFaces);
|
|
3718
3970
|
}
|
|
3719
3971
|
async getCapabilities() {
|
|
3720
3972
|
const metrics = _univerjs_engine_render.FontCache.getMeasureText(FONT_PROBE_CONTENT, FONT_PROBE_STYLE);
|
|
@@ -3802,7 +4054,9 @@ var DocsLayoutWorkerRuntime = class {
|
|
|
3802
4054
|
reason: request.reason,
|
|
3803
4055
|
anchor: request.anchor,
|
|
3804
4056
|
priorityAnchor: request.priorityAnchor,
|
|
3805
|
-
invalidation: request.invalidation
|
|
4057
|
+
invalidation: request.invalidation,
|
|
4058
|
+
modernPageWidth: request.modernPageWidth,
|
|
4059
|
+
modernHorizontalMargin: request.modernHorizontalMargin
|
|
3806
4060
|
});
|
|
3807
4061
|
mount.activeGeneration = generation;
|
|
3808
4062
|
mount.cancelledGeneration = null;
|
|
@@ -3924,6 +4178,7 @@ var DocsLayoutWorkerRuntime = class {
|
|
|
3924
4178
|
this._performanceTracker.reset(request.unitId);
|
|
3925
4179
|
}
|
|
3926
4180
|
dispose() {
|
|
4181
|
+
this._fontLoader.dispose();
|
|
3927
4182
|
for (const unitId of this._sessions.keys()) this._disposeSession(unitId);
|
|
3928
4183
|
this._performanceTracker.resetAll();
|
|
3929
4184
|
}
|
|
@@ -3981,10 +4236,21 @@ var DocsLayoutWorkerRuntime = class {
|
|
|
3981
4236
|
session.localeService.dispose();
|
|
3982
4237
|
}
|
|
3983
4238
|
};
|
|
4239
|
+
var DocsLayoutWorkerChannelService = class extends _univerjs_rpc.ChannelService {
|
|
4240
|
+
constructor(protocol, _runtime) {
|
|
4241
|
+
super(protocol);
|
|
4242
|
+
this._runtime = _runtime;
|
|
4243
|
+
}
|
|
4244
|
+
dispose() {
|
|
4245
|
+
this._runtime.dispose();
|
|
4246
|
+
super.dispose();
|
|
4247
|
+
}
|
|
4248
|
+
};
|
|
3984
4249
|
function startDocsLayoutWorker() {
|
|
3985
4250
|
const performanceTracker = new DocsLayoutWorkerPerformanceTracker();
|
|
3986
|
-
const
|
|
3987
|
-
channelService
|
|
4251
|
+
const runtime = new DocsLayoutWorkerRuntime(performanceTracker);
|
|
4252
|
+
const channelService = new DocsLayoutWorkerChannelService(createDocsLayoutWorkerMessageProtocol$1(performanceTracker), runtime);
|
|
4253
|
+
channelService.registerChannel(DOCS_LAYOUT_WORKER_CHANNEL, (0, _univerjs_rpc.fromModule)(runtime));
|
|
3988
4254
|
return channelService;
|
|
3989
4255
|
}
|
|
3990
4256
|
|
|
@@ -4015,10 +4281,11 @@ function createDocsLayoutWorkerMessageProtocol(worker, performanceTracker) {
|
|
|
4015
4281
|
};
|
|
4016
4282
|
}
|
|
4017
4283
|
var DocsLayoutWorkerClientService = class extends _univerjs_core.Disposable {
|
|
4018
|
-
constructor(_workerFactory, _requestTimeoutMs = DEFAULT_DOCS_LAYOUT_WORKER_REQUEST_TIMEOUT_MS) {
|
|
4284
|
+
constructor(_workerFactory, _requestTimeoutMs = DEFAULT_DOCS_LAYOUT_WORKER_REQUEST_TIMEOUT_MS, _fontFaces = []) {
|
|
4019
4285
|
super();
|
|
4020
4286
|
this._workerFactory = _workerFactory;
|
|
4021
4287
|
this._requestTimeoutMs = _requestTimeoutMs;
|
|
4288
|
+
this._fontFaces = _fontFaces;
|
|
4022
4289
|
_defineProperty(this, "type", "worker");
|
|
4023
4290
|
_defineProperty(this, "_worker", null);
|
|
4024
4291
|
_defineProperty(this, "_channelService", null);
|
|
@@ -4027,12 +4294,18 @@ var DocsLayoutWorkerClientService = class extends _univerjs_core.Disposable {
|
|
|
4027
4294
|
_defineProperty(this, "_initialized", false);
|
|
4028
4295
|
_defineProperty(this, "_performanceTracker", new DocsLayoutWorkerPerformanceTracker());
|
|
4029
4296
|
_defineProperty(this, "_fontFamilies", /* @__PURE__ */ new Map());
|
|
4297
|
+
_defineProperty(this, "_fontLoader", new DocsLayoutFontLoader());
|
|
4298
|
+
this.disposeWithMe(this._fontLoader);
|
|
4030
4299
|
this._initialization = this._replaceRuntime();
|
|
4031
4300
|
}
|
|
4032
4301
|
initialize() {
|
|
4033
4302
|
return this._initialization;
|
|
4034
4303
|
}
|
|
4035
|
-
|
|
4304
|
+
get renderingFontsReady() {
|
|
4305
|
+
return this._fontFaces.length > 0 ? this._initialization : void 0;
|
|
4306
|
+
}
|
|
4307
|
+
async getCapabilities() {
|
|
4308
|
+
await this._initialization;
|
|
4036
4309
|
return this._getRuntime().getCapabilities();
|
|
4037
4310
|
}
|
|
4038
4311
|
async recover() {
|
|
@@ -4109,13 +4382,22 @@ var DocsLayoutWorkerClientService = class extends _univerjs_core.Disposable {
|
|
|
4109
4382
|
async _replaceRuntime() {
|
|
4110
4383
|
this._initialized = false;
|
|
4111
4384
|
this._disposeRuntime();
|
|
4385
|
+
await this._withTimeout(this._fontLoader.load(this._fontFaces), "load rendering fonts");
|
|
4386
|
+
this.ensureNotDisposed();
|
|
4112
4387
|
const worker = this._workerFactory();
|
|
4113
4388
|
const channelService = new _univerjs_rpc.ChannelService(createDocsLayoutWorkerMessageProtocol(worker, this._performanceTracker));
|
|
4114
4389
|
this._worker = worker;
|
|
4115
4390
|
this._channelService = channelService;
|
|
4116
4391
|
this._runtime = (0, _univerjs_rpc.toModule)(channelService.requestChannel(DOCS_LAYOUT_WORKER_CHANNEL));
|
|
4117
|
-
|
|
4118
|
-
|
|
4392
|
+
try {
|
|
4393
|
+
await this._withTimeout(this._runtime.initialize(this._fontFaces), "load Worker fonts");
|
|
4394
|
+
await this._withTimeout(this._verifyCapabilities(), "verify capabilities");
|
|
4395
|
+
this.ensureNotDisposed();
|
|
4396
|
+
this._initialized = true;
|
|
4397
|
+
} catch (error) {
|
|
4398
|
+
if (this._worker === worker) this._disposeRuntime();
|
|
4399
|
+
throw error;
|
|
4400
|
+
}
|
|
4119
4401
|
}
|
|
4120
4402
|
_disposeRuntime() {
|
|
4121
4403
|
var _this$_channelService, _this$_worker;
|
|
@@ -4144,7 +4426,7 @@ var DocsLayoutWorkerClientService = class extends _univerjs_core.Disposable {
|
|
|
4144
4426
|
});
|
|
4145
4427
|
}
|
|
4146
4428
|
async _verifyCapabilities() {
|
|
4147
|
-
const capabilities = await this.getCapabilities();
|
|
4429
|
+
const capabilities = await this._getRuntime().getCapabilities();
|
|
4148
4430
|
if (capabilities.protocolVersion !== 5) throw new DocsLayoutWorkerCapabilityError("Document layout Worker protocol version mismatch.");
|
|
4149
4431
|
if (!capabilities.offscreenCanvas || !capabilities.structuredClone) throw new DocsLayoutWorkerCapabilityError("Document layout Worker requires OffscreenCanvas and structured clone support.");
|
|
4150
4432
|
const mainMetrics = _univerjs_engine_render.FontCache.getMeasureText(capabilities.fontProbe.content, capabilities.fontProbe.font);
|
|
@@ -4169,7 +4451,7 @@ let UniverDocsLayoutWorkerPlugin = class UniverDocsLayoutWorkerPlugin extends _u
|
|
|
4169
4451
|
if (typeof this._config.workerFactory !== "function") throw new TypeError("[UniverDocsLayoutWorkerPlugin]: workerFactory is required.");
|
|
4170
4452
|
const requestTimeoutMs = this._config.requestTimeoutMs ?? 15e3;
|
|
4171
4453
|
if (!Number.isFinite(requestTimeoutMs) || requestTimeoutMs <= 0) throw new RangeError("[UniverDocsLayoutWorkerPlugin]: requestTimeoutMs must be a positive finite number.");
|
|
4172
|
-
const client = new DocsLayoutWorkerClientService(this._config.workerFactory, requestTimeoutMs);
|
|
4454
|
+
const client = new DocsLayoutWorkerClientService(this._config.workerFactory, requestTimeoutMs, this._config.fontFaces);
|
|
4173
4455
|
this._injector.add([DocsLayoutWorkerClientService, { useValue: client }]);
|
|
4174
4456
|
this.disposeWithMe(client);
|
|
4175
4457
|
this.disposeWithMe(this._layoutExecutorService.register(client));
|
|
@@ -4232,7 +4514,8 @@ let DocInterceptorService = class DocInterceptorService extends _univerjs_core.D
|
|
|
4232
4514
|
}
|
|
4233
4515
|
fetchThroughInterceptors(name) {
|
|
4234
4516
|
const key = name;
|
|
4235
|
-
|
|
4517
|
+
const interceptors = this._interceptorsByName.get(key);
|
|
4518
|
+
return (0, _univerjs_core.composeInterceptors)(interceptors || []);
|
|
4236
4519
|
}
|
|
4237
4520
|
interceptDocumentViewModel(viewModel) {
|
|
4238
4521
|
const disposableCollection = new _univerjs_core.DisposableCollection();
|