@univerjs/docs 1.0.0-rc.0 → 1.0.1

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/index.js CHANGED
@@ -15,7 +15,7 @@ const SetTextSelectionsOperation = {
15
15
  };
16
16
 
17
17
  //#endregion
18
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/typeof.js
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.140.0/helpers/esm/toPrimitive.js
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.140.0/helpers/esm/toPropertyKey.js
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.140.0/helpers/esm/defineProperty.js
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.140.0/helpers/esm/decorateParam.js
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.140.0/helpers/esm/decorate.js
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
- for (const customBlock of ((_snapshot$body = snapshot.body) === null || _snapshot$body === void 0 ? void 0 : _snapshot$body.customBlocks) ?? []) {
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
- const recoveryDiagnostic = error instanceof Error ? error.message : String(error);
525
- this._executor = null;
526
- this._executorReady = null;
527
- this._recoveryFailure = {
528
- diagnostic: recoveryDiagnostic,
529
- unitId
530
- };
531
- this._executorStatus$.next({
532
- state: "recovering",
533
- executor: executor.type,
534
- diagnostic: recoveryDiagnostic,
535
- recoveryUnitId: unitId
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.needsResnapshot = true;
743
- throw error;
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
- (_this$_executor3 = this._executor) === null || _this$_executor3 === void 0 || _this$_executor3.disposeSession({
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 assertValidDocBodyStructure(documentDataModel, segmentId) {
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 detail = issues.map((issue) => `${issue.code}${issue.index == null ? "" : `@${issue.index}`}`).join(", ");
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 validateDocStructureMutation(documentDataModel, segmentId, actions, undoActions) {
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 { actions: appliedActions, undoActions, preservesStructure } = applyValidatedDocumentActions(documentDataModel, segmentId, actions);
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-rc.0";
2784
+ var version = "1.0.1";
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) if (type === "history") {
3308
- if (this._historyTimer) clearTimeout(this._historyTimer);
3309
- this._historyTimer = setTimeout(() => {
3310
- cb(unitId);
3311
- }, DEBOUNCE_DELAY);
3312
- } else {
3313
- if (this._changeStateCacheTimer) clearTimeout(this._changeStateCacheTimer);
3314
- this._changeStateCacheTimer = setTimeout(() => {
3315
- cb(unitId);
3316
- }, DEBOUNCE_DELAY);
3317
- }
3318
- else cb(unitId);
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 Promise.resolve();
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 channelService = new _univerjs_rpc.ChannelService(createDocsLayoutWorkerMessageProtocol$1(performanceTracker));
3987
- channelService.registerChannel(DOCS_LAYOUT_WORKER_CHANNEL, (0, _univerjs_rpc.fromModule)(new DocsLayoutWorkerRuntime(performanceTracker)));
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
- getCapabilities() {
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
- await this._withTimeout(this._verifyCapabilities(), "verify capabilities");
4118
- this._initialized = true;
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
- return (0, _univerjs_core.composeInterceptors)(this._interceptorsByName.get(key) || []);
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();