@univerjs/docs 1.0.0-alpha.7 → 1.0.0-alpha.8

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
@@ -13,7 +13,7 @@ const SetTextSelectionsOperation = {
13
13
  };
14
14
 
15
15
  //#endregion
16
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/typeof.js
16
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/typeof.js
17
17
  function _typeof(o) {
18
18
  "@babel/helpers - typeof";
19
19
  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
@@ -24,7 +24,7 @@ function _typeof(o) {
24
24
  }
25
25
 
26
26
  //#endregion
27
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPrimitive.js
27
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/toPrimitive.js
28
28
  function toPrimitive(t, r) {
29
29
  if ("object" != _typeof(t) || !t) return t;
30
30
  var e = t[Symbol.toPrimitive];
@@ -37,14 +37,14 @@ function toPrimitive(t, r) {
37
37
  }
38
38
 
39
39
  //#endregion
40
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPropertyKey.js
40
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/toPropertyKey.js
41
41
  function toPropertyKey(t) {
42
42
  var i = toPrimitive(t, "string");
43
43
  return "symbol" == _typeof(i) ? i : i + "";
44
44
  }
45
45
 
46
46
  //#endregion
47
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/defineProperty.js
47
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/defineProperty.js
48
48
  function _defineProperty(e, r, t) {
49
49
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
50
50
  value: t,
@@ -55,7 +55,7 @@ function _defineProperty(e, r, t) {
55
55
  }
56
56
 
57
57
  //#endregion
58
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/decorateParam.js
58
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/decorateParam.js
59
59
  function __decorateParam(paramIndex, decorator) {
60
60
  return function(target, key) {
61
61
  decorator(target, key, paramIndex);
@@ -63,7 +63,7 @@ function __decorateParam(paramIndex, decorator) {
63
63
  }
64
64
 
65
65
  //#endregion
66
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/decorate.js
66
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/decorate.js
67
67
  function __decorate(decorators, target, key, desc) {
68
68
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
69
69
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -73,6 +73,11 @@ function __decorate(decorators, target, key, desc) {
73
73
 
74
74
  //#endregion
75
75
  //#region src/services/doc-selection-manager.service.ts
76
+ /**
77
+ * Keeps a programmatically restored collapsed caret from being promoted back
78
+ * into a neighboring whole-entity selection by feature-specific UI.
79
+ */
80
+ const DOC_SELECTION_OPTION_PRESERVE_CARET = "preserveCaret";
76
81
  let DocSelectionManagerService = class DocSelectionManagerService extends _univerjs_core.RxDisposable {
77
82
  constructor(_commandService, _univerInstanceService) {
78
83
  super();
@@ -134,16 +139,6 @@ let DocSelectionManagerService = class DocSelectionManagerService extends _unive
134
139
  const { textRanges } = selectionInfo;
135
140
  return textRanges.find((textRange) => textRange.isActive);
136
141
  }
137
- /**
138
- *
139
- * @deprecated
140
- */
141
- getActiveRectRange() {
142
- const selectionInfo = this._getTextRanges(this._currentSelection);
143
- if (selectionInfo == null) return;
144
- const { rectRanges } = selectionInfo;
145
- return rectRanges.find((rectRange) => rectRange.isActive);
146
- }
147
142
  __TEST_ONLY_add(textRanges, isEditing = true) {
148
143
  if (this._currentSelection == null) return;
149
144
  this._addByParam({
@@ -156,12 +151,6 @@ let DocSelectionManagerService = class DocSelectionManagerService extends _unive
156
151
  style: _univerjs_engine_render.NORMAL_TEXT_SELECTION_PLUGIN_STYLE
157
152
  });
158
153
  }
159
- /**
160
- * @deprecated pls use replaceDocRanges.
161
- */
162
- replaceTextRanges(docRanges, isEditing = true, options) {
163
- return this.replaceDocRanges(docRanges, this._currentSelection, isEditing, options);
164
- }
165
154
  replaceDocRanges(docRanges, params = this._currentSelection, isEditing = true, options) {
166
155
  if (params == null) return;
167
156
  const { unitId, subUnitId } = params;
@@ -212,14 +201,15 @@ let DocSelectionManagerService = class DocSelectionManagerService extends _unive
212
201
  _refresh(param) {
213
202
  const allTextSelectionInfo = this._getTextRanges(param);
214
203
  if (allTextSelectionInfo == null) return;
215
- const { textRanges, rectRanges } = allTextSelectionInfo;
204
+ const { textRanges, rectRanges, options } = allTextSelectionInfo;
216
205
  const docRanges = [...textRanges, ...rectRanges];
217
206
  const { unitId, subUnitId } = param;
218
207
  this._refreshSelection$.next({
219
208
  unitId,
220
209
  subUnitId,
221
210
  docRanges,
222
- isEditing: false
211
+ isEditing: false,
212
+ options
223
213
  });
224
214
  }
225
215
  _replaceByParam(insertParam) {
@@ -863,6 +853,178 @@ function buildUnlinkActions(context, kind, requestedSegmentId) {
863
853
  ], segmentId)];
864
854
  }
865
855
 
856
+ //#endregion
857
+ //#region src/commands/commands/update-document-paragraph-style.command.ts
858
+ function isValidParams(params) {
859
+ return Boolean((params === null || params === void 0 ? void 0 : params.unitId) && params.paragraphId && Number.isInteger(params.startOffset) && Number.isInteger(params.endOffset) && params.startOffset >= 0 && params.endOffset >= params.startOffset && params.style && Object.keys(params.style).length > 0);
860
+ }
861
+ function getCurrentParagraph(body, params) {
862
+ var _body$paragraphs;
863
+ const matches = ((_body$paragraphs = body.paragraphs) !== null && _body$paragraphs !== void 0 ? _body$paragraphs : []).filter((paragraph) => paragraph.paragraphId === params.paragraphId);
864
+ if (matches.length !== 1) return null;
865
+ const paragraph = matches[0];
866
+ return (0, _univerjs_core.getParagraphContentStartOffset)(body, paragraph) === params.startOffset && paragraph.startIndex === params.endOffset && body.dataStream[params.endOffset] === "\r" ? paragraph : null;
867
+ }
868
+ function createParagraphStyleTextX(body, paragraph, params) {
869
+ var _paragraph$paragraphS;
870
+ const textX = new _univerjs_core.TextX();
871
+ const initializesTextRuns = Boolean(params.style.textStyle && params.startOffset < params.endOffset && body.textRuns == null);
872
+ if (params.startOffset > 0) textX.push({
873
+ t: _univerjs_core.TextXActionType.RETAIN,
874
+ len: params.startOffset
875
+ });
876
+ if (params.style.textStyle && params.startOffset < params.endOffset && !initializesTextRuns) textX.push({
877
+ t: _univerjs_core.TextXActionType.RETAIN,
878
+ len: params.endOffset - params.startOffset,
879
+ coverType: _univerjs_core.UpdateDocsAttributeType.COVER,
880
+ body: {
881
+ dataStream: "",
882
+ textRuns: [{
883
+ st: 0,
884
+ ed: params.endOffset - params.startOffset,
885
+ ts: _univerjs_core.Tools.deepClone(params.style.textStyle)
886
+ }]
887
+ }
888
+ });
889
+ else if (params.startOffset < params.endOffset) textX.push({
890
+ t: _univerjs_core.TextXActionType.RETAIN,
891
+ len: params.endOffset - params.startOffset
892
+ });
893
+ const paragraphBody = {
894
+ dataStream: "",
895
+ paragraphs: [{
896
+ ..._univerjs_core.Tools.deepClone(paragraph),
897
+ startIndex: 0,
898
+ paragraphStyle: {
899
+ ..._univerjs_core.Tools.deepClone((_paragraph$paragraphS = paragraph.paragraphStyle) !== null && _paragraph$paragraphS !== void 0 ? _paragraph$paragraphS : {}),
900
+ ..._univerjs_core.Tools.deepClone(params.style)
901
+ }
902
+ }]
903
+ };
904
+ Object.defineProperty(paragraphBody, _univerjs_core.RESTORE_INSERTED_PARAGRAPH_IDS, {
905
+ value: true,
906
+ enumerable: true
907
+ });
908
+ textX.push({
909
+ t: _univerjs_core.TextXActionType.RETAIN,
910
+ len: 1,
911
+ coverType: _univerjs_core.UpdateDocsAttributeType.REPLACE,
912
+ body: paragraphBody
913
+ });
914
+ return {
915
+ textX,
916
+ initializesTextRuns
917
+ };
918
+ }
919
+ const UpdateDocumentParagraphStyleCommand = {
920
+ id: "doc.command.update-paragraph-style",
921
+ type: _univerjs_core.CommandType.COMMAND,
922
+ handler: (accessor, params) => {
923
+ var _params$segmentId, _documentDataModel$ge;
924
+ if (!isValidParams(params)) return false;
925
+ const instanceService = accessor.get(_univerjs_core.IUniverInstanceService);
926
+ const commandService = accessor.get(_univerjs_core.ICommandService);
927
+ const documentDataModel = instanceService.getUnit(params.unitId, _univerjs_core.UniverInstanceType.UNIVER_DOC);
928
+ const segmentId = (_params$segmentId = params.segmentId) !== null && _params$segmentId !== void 0 ? _params$segmentId : "";
929
+ const body = documentDataModel === null || documentDataModel === void 0 || (_documentDataModel$ge = documentDataModel.getSelfOrHeaderFooterModel(segmentId)) === null || _documentDataModel$ge === void 0 ? void 0 : _documentDataModel$ge.getBody();
930
+ if (!documentDataModel || !body) return false;
931
+ const paragraph = getCurrentParagraph(body, params);
932
+ if (!paragraph) return false;
933
+ const { textX, initializesTextRuns } = createParagraphStyleTextX(body, paragraph, params);
934
+ const jsonX = _univerjs_core.JSONX.getInstance();
935
+ const path = (0, _univerjs_core.getRichTextEditPath)(documentDataModel, segmentId);
936
+ let actions = jsonX.editOp(textX.serialize(), path);
937
+ if (initializesTextRuns) {
938
+ const initializeTextRunsActions = jsonX.replaceOp([...path, "textRuns"], void 0, [{
939
+ st: params.startOffset,
940
+ ed: params.endOffset,
941
+ ts: _univerjs_core.Tools.deepClone(params.style.textStyle)
942
+ }]);
943
+ actions = _univerjs_core.JSONX.compose(initializeTextRunsActions, actions);
944
+ }
945
+ return Boolean(commandService.syncExecuteCommand(RichTextEditingMutation.id, {
946
+ unitId: params.unitId,
947
+ segmentId,
948
+ actions,
949
+ textRanges: null,
950
+ noNeedSetTextRange: true,
951
+ isEditing: false,
952
+ trigger: UpdateDocumentParagraphStyleCommand.id
953
+ }));
954
+ }
955
+ };
956
+
957
+ //#endregion
958
+ //#region src/utils/section-columns.ts
959
+ function resolveSectionValue(sectionValue, documentValue, fallback) {
960
+ var _ref;
961
+ return (_ref = sectionValue !== null && sectionValue !== void 0 ? sectionValue : documentValue) !== null && _ref !== void 0 ? _ref : fallback;
962
+ }
963
+ function getEffectivePageSize(documentStyle, section) {
964
+ var _section$pageSize, _documentStyle$pageSi, _section$pageSize2, _documentStyle$pageSi2;
965
+ const fallback = _univerjs_core.PAGE_SIZE[_univerjs_core.PaperType.A4];
966
+ return {
967
+ width: resolveSectionValue(section === null || section === void 0 || (_section$pageSize = section.pageSize) === null || _section$pageSize === void 0 ? void 0 : _section$pageSize.width, documentStyle === null || documentStyle === void 0 || (_documentStyle$pageSi = documentStyle.pageSize) === null || _documentStyle$pageSi === void 0 ? void 0 : _documentStyle$pageSi.width, fallback.width),
968
+ height: resolveSectionValue(section === null || section === void 0 || (_section$pageSize2 = section.pageSize) === null || _section$pageSize2 === void 0 ? void 0 : _section$pageSize2.height, documentStyle === null || documentStyle === void 0 || (_documentStyle$pageSi2 = documentStyle.pageSize) === null || _documentStyle$pageSi2 === void 0 ? void 0 : _documentStyle$pageSi2.height, fallback.height)
969
+ };
970
+ }
971
+ function getEffectiveMargins(documentStyle, section) {
972
+ return {
973
+ top: resolveSectionValue(section === null || section === void 0 ? void 0 : section.marginTop, documentStyle === null || documentStyle === void 0 ? void 0 : documentStyle.marginTop, _univerjs_core.TRADITIONAL_DOCUMENT_DEFAULT_MARGIN),
974
+ bottom: resolveSectionValue(section === null || section === void 0 ? void 0 : section.marginBottom, documentStyle === null || documentStyle === void 0 ? void 0 : documentStyle.marginBottom, _univerjs_core.TRADITIONAL_DOCUMENT_DEFAULT_MARGIN),
975
+ left: resolveSectionValue(section === null || section === void 0 ? void 0 : section.marginLeft, documentStyle === null || documentStyle === void 0 ? void 0 : documentStyle.marginLeft, _univerjs_core.TRADITIONAL_DOCUMENT_DEFAULT_MARGIN),
976
+ right: resolveSectionValue(section === null || section === void 0 ? void 0 : section.marginRight, documentStyle === null || documentStyle === void 0 ? void 0 : documentStyle.marginRight, _univerjs_core.TRADITIONAL_DOCUMENT_DEFAULT_MARGIN)
977
+ };
978
+ }
979
+ function assertPositivePageSetup(pageSize, contentSize) {
980
+ if (![
981
+ pageSize.width,
982
+ pageSize.height,
983
+ contentSize.width,
984
+ contentSize.height
985
+ ].every((value) => Number.isFinite(value) && value > 0)) throw new RangeError("Effective section page setup must leave a positive content area and use finite positive page dimensions.");
986
+ }
987
+ /** Resolves nominal traditional page geometry without requiring a renderer. */
988
+ function getEffectiveSectionPageSetup(documentStyle, section) {
989
+ var _section$pageNumberSt;
990
+ const pageSize = getEffectivePageSize(documentStyle, section);
991
+ const margins = getEffectiveMargins(documentStyle, section);
992
+ const contentSize = {
993
+ width: getSectionContentWidth(documentStyle, section),
994
+ height: pageSize.height - margins.top - margins.bottom
995
+ };
996
+ assertPositivePageSetup(pageSize, contentSize);
997
+ const pageNumberStart = (_section$pageNumberSt = section === null || section === void 0 ? void 0 : section.pageNumberStart) !== null && _section$pageNumberSt !== void 0 ? _section$pageNumberSt : documentStyle === null || documentStyle === void 0 ? void 0 : documentStyle.pageNumberStart;
998
+ return {
999
+ pageSize,
1000
+ pageOrient: resolveSectionValue(section === null || section === void 0 ? void 0 : section.pageOrient, documentStyle === null || documentStyle === void 0 ? void 0 : documentStyle.pageOrient, _univerjs_core.PageOrientType.PORTRAIT),
1001
+ margins,
1002
+ contentSize,
1003
+ ...pageNumberStart == null ? {} : { pageNumberStart }
1004
+ };
1005
+ }
1006
+ /** Returns the usable horizontal layout width for a traditional section. */
1007
+ function getSectionContentWidth(documentStyle, section) {
1008
+ var _section$pageSize3, _documentStyle$pageSi3;
1009
+ const pageWidth = resolveSectionValue(section === null || section === void 0 || (_section$pageSize3 = section.pageSize) === null || _section$pageSize3 === void 0 ? void 0 : _section$pageSize3.width, documentStyle === null || documentStyle === void 0 || (_documentStyle$pageSi3 = documentStyle.pageSize) === null || _documentStyle$pageSi3 === void 0 ? void 0 : _documentStyle$pageSi3.width, _univerjs_core.PAGE_SIZE[_univerjs_core.PaperType.A4].width);
1010
+ return Math.max(0, pageWidth - resolveSectionValue(section === null || section === void 0 ? void 0 : section.marginLeft, documentStyle === null || documentStyle === void 0 ? void 0 : documentStyle.marginLeft, _univerjs_core.TRADITIONAL_DOCUMENT_DEFAULT_MARGIN) - resolveSectionValue(section === null || section === void 0 ? void 0 : section.marginRight, documentStyle === null || documentStyle === void 0 ? void 0 : documentStyle.marginRight, _univerjs_core.TRADITIONAL_DOCUMENT_DEFAULT_MARGIN));
1011
+ }
1012
+ /** Creates explicit OOXML section columns from a count, gap, and optional widths. */
1013
+ function createSectionColumnProperties(documentStyle, section, columnCount, gap, widths) {
1014
+ if (columnCount <= 1) return [];
1015
+ const safeGap = Math.max(0, gap);
1016
+ const contentWidth = getSectionContentWidth(documentStyle, section);
1017
+ const availableWidth = Math.max(0, contentWidth - safeGap * (columnCount - 1));
1018
+ if (widths) {
1019
+ if (widths.some((width) => !Number.isFinite(width) || width < 0)) throw new RangeError("Section column widths must be finite and non-negative.");
1020
+ if (widths.reduce((sum, width) => sum + width, 0) > availableWidth) throw new RangeError("Section columns exceed the available page content width.");
1021
+ }
1022
+ return (widths !== null && widths !== void 0 ? widths : Array.from({ length: columnCount }, () => availableWidth / columnCount)).map((width, index) => ({
1023
+ width: Math.max(0, width),
1024
+ paddingEnd: index === columnCount - 1 ? 0 : safeGap
1025
+ }));
1026
+ }
1027
+
866
1028
  //#endregion
867
1029
  //#region src/commands/commands/update-document-section.command.ts
868
1030
  const UpdateDocumentSectionCommand = {
@@ -881,6 +1043,11 @@ const UpdateDocumentSectionCommand = {
881
1043
  const selectedIds = new Set(updates.keys());
882
1044
  const sections = getTopLevelSectionBreaks(body).filter((section) => selectedIds.has(section.sectionId)).sort((left, right) => left.startIndex - right.startIndex);
883
1045
  if (sections.length !== selectedIds.size) return false;
1046
+ const documentStyle = documentDataModel.getDocumentStyle();
1047
+ if (sections.some((section) => !isValidSectionConfig({
1048
+ ...section,
1049
+ ...updates.get(section.sectionId)
1050
+ }, documentStyle))) return false;
884
1051
  const cursor = new _univerjs_core.MemoryCursor();
885
1052
  const textX = new _univerjs_core.TextX();
886
1053
  for (const section of sections) {
@@ -924,25 +1091,70 @@ const InsertDocumentSectionBreakCommand = {
924
1091
  id: "doc.command.insert-section-break",
925
1092
  type: _univerjs_core.CommandType.COMMAND,
926
1093
  handler: (accessor, params) => {
927
- var _body$sectionBreaks, _body$tables, _body$columnGroups, _body$blockRanges, _params$config;
1094
+ var _params$config, _body$sectionBreaks;
928
1095
  if (!params) return false;
929
1096
  const context = getTraditionalDocumentContext(accessor, params.unitId);
930
- if (!context || !params.sectionId || !Number.isInteger(params.offset)) return false;
1097
+ if (!context || !params.sectionId || !Number.isInteger(params.offset) || params.nextSectionType != null && !isValidEnumValue(_univerjs_core.SectionType, params.nextSectionType)) return false;
931
1098
  const { body, documentDataModel, commandService } = context;
932
- if (params.offset < 0 || params.offset > body.dataStream.length || ((_body$sectionBreaks = body.sectionBreaks) === null || _body$sectionBreaks === void 0 ? void 0 : _body$sectionBreaks.some((section) => section.sectionId === params.sectionId)) || ((_body$tables = body.tables) === null || _body$tables === void 0 ? void 0 : _body$tables.some((range) => (0, _univerjs_core.containsInteriorInsertionOffset)((0, _univerjs_core.getTableRangeInterval)(range), params.offset))) || ((_body$columnGroups = body.columnGroups) === null || _body$columnGroups === void 0 ? void 0 : _body$columnGroups.some((range) => (0, _univerjs_core.containsInteriorInsertionOffset)((0, _univerjs_core.getColumnGroupRangeInterval)(range), params.offset))) || ((_body$blockRanges = body.blockRanges) === null || _body$blockRanges === void 0 ? void 0 : _body$blockRanges.some((range) => (0, _univerjs_core.containsInteriorInsertionOffset)((0, _univerjs_core.getBlockRangeInterval)(range), params.offset)))) return false;
1099
+ const insertedSection = {
1100
+ ..._univerjs_core.Tools.deepClone((_params$config = params.config) !== null && _params$config !== void 0 ? _params$config : {}),
1101
+ sectionId: params.sectionId,
1102
+ startIndex: params.offset
1103
+ };
1104
+ if (!isValidTopLevelInsertionOffset(body, params.offset) || ((_body$sectionBreaks = body.sectionBreaks) === null || _body$sectionBreaks === void 0 ? void 0 : _body$sectionBreaks.some((section) => section.sectionId === params.sectionId)) || !isValidSectionConfig(insertedSection, documentDataModel.getDocumentStyle())) return false;
1105
+ const nextSection = params.nextSectionType == null ? void 0 : getTopLevelSectionBreaks(body).find((section) => section.startIndex >= params.offset);
1106
+ if (params.nextSectionType != null && !nextSection) return false;
933
1107
  const textX = new _univerjs_core.TextX();
934
1108
  textX.retain(params.offset);
935
1109
  textX.insert(1, {
936
1110
  dataStream: _univerjs_core.DataStreamTreeTokenType.SECTION_BREAK,
937
1111
  sectionBreaks: [{
938
- ..._univerjs_core.Tools.deepClone((_params$config = params.config) !== null && _params$config !== void 0 ? _params$config : {}),
939
- sectionId: params.sectionId,
1112
+ ...insertedSection,
940
1113
  startIndex: 0
941
1114
  }]
942
1115
  });
1116
+ if (nextSection && params.nextSectionType != null) {
1117
+ textX.retain(nextSection.startIndex - params.offset);
1118
+ textX.push({
1119
+ t: _univerjs_core.TextXActionType.RETAIN,
1120
+ len: 1,
1121
+ coverType: _univerjs_core.UpdateDocsAttributeType.REPLACE,
1122
+ body: {
1123
+ dataStream: "",
1124
+ sectionBreaks: [{
1125
+ ..._univerjs_core.Tools.deepClone(nextSection),
1126
+ sectionType: params.nextSectionType,
1127
+ startIndex: 0
1128
+ }]
1129
+ }
1130
+ });
1131
+ }
943
1132
  return executeSectionTextX(commandService, documentDataModel, textX, InsertDocumentSectionBreakCommand.id);
944
1133
  }
945
1134
  };
1135
+ const InsertDocumentColumnBreakCommand = {
1136
+ id: "doc.command.insert-column-break",
1137
+ type: _univerjs_core.CommandType.COMMAND,
1138
+ handler: (accessor, params) => {
1139
+ if (!params) return false;
1140
+ const context = getTraditionalDocumentContext(accessor, params.unitId);
1141
+ if (!context || !isValidTopLevelInsertionOffset(context.body, params.offset)) return false;
1142
+ const textX = new _univerjs_core.TextX();
1143
+ textX.retain(params.offset);
1144
+ textX.insert(1, {
1145
+ dataStream: _univerjs_core.DataStreamTreeTokenType.COLUMN_BREAK,
1146
+ customRanges: [{
1147
+ startIndex: 0,
1148
+ endIndex: 0,
1149
+ rangeId: `docx-break-${(0, _univerjs_core.generateRandomId)()}`,
1150
+ rangeType: _univerjs_core.CustomRangeType.CUSTOM,
1151
+ wholeEntity: true,
1152
+ properties: { docxBreakType: _univerjs_core.DocxBreakType.COLUMN }
1153
+ }]
1154
+ });
1155
+ return executeSectionTextX(context.commandService, context.documentDataModel, textX, InsertDocumentColumnBreakCommand.id);
1156
+ }
1157
+ };
946
1158
  const DeleteDocumentSectionBreakCommand = {
947
1159
  id: "doc.command.delete-section-break",
948
1160
  type: _univerjs_core.CommandType.COMMAND,
@@ -953,7 +1165,7 @@ const DeleteDocumentSectionBreakCommand = {
953
1165
  const sections = getTopLevelSectionBreaks(context.body);
954
1166
  if (sections.length <= 1) return false;
955
1167
  const section = sections.find((item) => item.sectionId === params.sectionId);
956
- if (!section) return false;
1168
+ if (!section || section === sections.at(-1)) return false;
957
1169
  const textX = new _univerjs_core.TextX();
958
1170
  textX.retain(section.startIndex);
959
1171
  textX.delete(1);
@@ -971,6 +1183,39 @@ function getTraditionalDocumentContext(accessor, unitId) {
971
1183
  commandService: accessor.get(_univerjs_core.ICommandService)
972
1184
  };
973
1185
  }
1186
+ function isValidTopLevelInsertionOffset(body, offset) {
1187
+ var _body$tables, _body$columnGroups, _body$blockRanges;
1188
+ return Number.isInteger(offset) && offset >= 0 && offset <= body.dataStream.length && !((_body$tables = body.tables) === null || _body$tables === void 0 ? void 0 : _body$tables.some((range) => (0, _univerjs_core.containsInteriorInsertionOffset)((0, _univerjs_core.getTableRangeInterval)(range), offset))) && !((_body$columnGroups = body.columnGroups) === null || _body$columnGroups === void 0 ? void 0 : _body$columnGroups.some((range) => (0, _univerjs_core.containsInteriorInsertionOffset)((0, _univerjs_core.getColumnGroupRangeInterval)(range), offset))) && !((_body$blockRanges = body.blockRanges) === null || _body$blockRanges === void 0 ? void 0 : _body$blockRanges.some((range) => (0, _univerjs_core.containsInteriorInsertionOffset)((0, _univerjs_core.getBlockRangeInterval)(range), offset)));
1189
+ }
1190
+ function isValidSectionConfig(section, documentStyle) {
1191
+ var _section$pageSize, _ref, _section$marginTop, _ref2, _section$marginBottom, _ref3, _section$marginLeft, _ref4, _section$marginRight, _section$columnProper;
1192
+ if (section.sectionType != null && !isValidEnumValue(_univerjs_core.SectionType, section.sectionType)) return false;
1193
+ if (section.pageOrient != null && !isValidEnumValue(_univerjs_core.PageOrientType, section.pageOrient)) return false;
1194
+ if (section.columnSeparatorType != null && !isValidEnumValue(_univerjs_core.ColumnSeparatorType, section.columnSeparatorType)) return false;
1195
+ if (section.pageNumberStart != null && (!Number.isInteger(section.pageNumberStart) || section.pageNumberStart < 1)) return false;
1196
+ if (section.pageSize && (!isPositiveFinite(section.pageSize.width) || !isPositiveFinite(section.pageSize.height))) return false;
1197
+ if ([
1198
+ section.marginTop,
1199
+ section.marginBottom,
1200
+ section.marginLeft,
1201
+ section.marginRight
1202
+ ].some((margin) => margin != null && (!Number.isFinite(margin) || margin < 0))) return false;
1203
+ const pageSize = (_section$pageSize = section.pageSize) !== null && _section$pageSize !== void 0 ? _section$pageSize : documentStyle.pageSize;
1204
+ const marginTop = (_ref = (_section$marginTop = section.marginTop) !== null && _section$marginTop !== void 0 ? _section$marginTop : documentStyle.marginTop) !== null && _ref !== void 0 ? _ref : 0;
1205
+ const marginBottom = (_ref2 = (_section$marginBottom = section.marginBottom) !== null && _section$marginBottom !== void 0 ? _section$marginBottom : documentStyle.marginBottom) !== null && _ref2 !== void 0 ? _ref2 : 0;
1206
+ const marginLeft = (_ref3 = (_section$marginLeft = section.marginLeft) !== null && _section$marginLeft !== void 0 ? _section$marginLeft : documentStyle.marginLeft) !== null && _ref3 !== void 0 ? _ref3 : 0;
1207
+ const marginRight = (_ref4 = (_section$marginRight = section.marginRight) !== null && _section$marginRight !== void 0 ? _section$marginRight : documentStyle.marginRight) !== null && _ref4 !== void 0 ? _ref4 : 0;
1208
+ if ((pageSize === null || pageSize === void 0 ? void 0 : pageSize.width) != null && marginLeft + marginRight >= pageSize.width || (pageSize === null || pageSize === void 0 ? void 0 : pageSize.height) != null && marginTop + marginBottom >= pageSize.height) return false;
1209
+ const columns = (_section$columnProper = section.columnProperties) !== null && _section$columnProper !== void 0 ? _section$columnProper : [];
1210
+ if (columns.some(({ width, paddingEnd }) => !Number.isFinite(width) || !Number.isFinite(paddingEnd) || width < 0 || paddingEnd < 0)) return false;
1211
+ return columns.reduce((sum, { width, paddingEnd }) => sum + width + paddingEnd, 0) <= getSectionContentWidth(documentStyle, section);
1212
+ }
1213
+ function isPositiveFinite(value) {
1214
+ return value != null && Number.isFinite(value) && value > 0;
1215
+ }
1216
+ function isValidEnumValue(enumObject, value) {
1217
+ return Object.values(enumObject).includes(value);
1218
+ }
974
1219
  function executeSectionTextX(commandService, documentDataModel, textX, trigger) {
975
1220
  const actions = _univerjs_core.JSONX.getInstance().editOp(textX.serialize(), (0, _univerjs_core.getRichTextEditPath)(documentDataModel));
976
1221
  return Boolean(commandService.syncExecuteCommand(RichTextEditingMutation.id, {
@@ -1151,7 +1396,7 @@ function composeActions(actions) {
1151
1396
  //#endregion
1152
1397
  //#region package.json
1153
1398
  var name = "@univerjs/docs";
1154
- var version = "1.0.0-alpha.7";
1399
+ var version = "1.0.0-alpha.8";
1155
1400
 
1156
1401
  //#endregion
1157
1402
  //#region src/commands/mutations/docs-rename.mutation.ts
@@ -1229,7 +1474,7 @@ let DocCustomRangeController = class DocCustomRangeController extends _univerjs_
1229
1474
  const doc = this._univerInstanceService.getUnit(unitId);
1230
1475
  if (!doc) return;
1231
1476
  const transformedRanges = ranges.map((range) => this._transformCustomRange(doc, range));
1232
- if (transformedRanges.some((range, i) => ranges[i] !== range)) this._textSelectionManagerService.replaceTextRanges(transformedRanges, isEditing);
1477
+ if (transformedRanges.some((range, i) => ranges[i] !== range)) this._textSelectionManagerService.replaceDocRanges(transformedRanges, void 0, isEditing);
1233
1478
  }
1234
1479
  }));
1235
1480
  }
@@ -1453,6 +1698,82 @@ DocStateChangeManagerService = __decorate([
1453
1698
  __decorateParam(4, (0, _univerjs_core.Optional)(IDocStateChangeInterceptorService))
1454
1699
  ], DocStateChangeManagerService);
1455
1700
 
1701
+ //#endregion
1702
+ //#region src/services/doc-text-resolver.service.ts
1703
+ /**
1704
+ * Builds a consumer-facing text projection while retaining a mapping back to
1705
+ * the native document offsets.
1706
+ *
1707
+ * Consumers such as find/replace can search the projected text and then use
1708
+ * `characters` to focus the native object that supplied a matching character.
1709
+ * Resolvers must return half-open, non-overlapping replacements.
1710
+ */
1711
+ var DocTextResolverService = class extends _univerjs_core.Disposable {
1712
+ constructor(..._args) {
1713
+ super(..._args);
1714
+ _defineProperty(this, "_resolvers", /* @__PURE__ */ new Set());
1715
+ _defineProperty(this, "_textChanged$", new rxjs.Subject());
1716
+ _defineProperty(this, "textChanged$", this._textChanged$.asObservable());
1717
+ }
1718
+ register(resolver) {
1719
+ this._resolvers.add(resolver);
1720
+ return (0, _univerjs_core.toDisposable)(() => this._resolvers.delete(resolver));
1721
+ }
1722
+ notifyTextChanged(unitId) {
1723
+ this._textChanged$.next(unitId);
1724
+ }
1725
+ resolve(unitId, body) {
1726
+ const replacements = this._collectReplacements(unitId, body);
1727
+ const characters = [];
1728
+ let text = "";
1729
+ let sourceOffset = 0;
1730
+ for (const replacement of replacements) {
1731
+ const sourceText = body.dataStream.slice(sourceOffset, replacement.startOffset);
1732
+ text += sourceText;
1733
+ for (let index = sourceOffset; index < replacement.startOffset; index += 1) characters.push({
1734
+ startOffset: index,
1735
+ endOffset: index + 1,
1736
+ replaceable: true
1737
+ });
1738
+ text += replacement.text;
1739
+ for (let index = 0; index < replacement.text.length; index += 1) {
1740
+ var _replacement$replacea;
1741
+ characters.push({
1742
+ startOffset: replacement.startOffset,
1743
+ endOffset: replacement.endOffset,
1744
+ replaceable: (_replacement$replacea = replacement.replaceable) !== null && _replacement$replacea !== void 0 ? _replacement$replacea : false
1745
+ });
1746
+ }
1747
+ sourceOffset = replacement.endOffset;
1748
+ }
1749
+ text += body.dataStream.slice(sourceOffset);
1750
+ for (let index = sourceOffset; index < body.dataStream.length; index += 1) characters.push({
1751
+ startOffset: index,
1752
+ endOffset: index + 1,
1753
+ replaceable: true
1754
+ });
1755
+ return {
1756
+ characters,
1757
+ text
1758
+ };
1759
+ }
1760
+ _collectReplacements(unitId, body) {
1761
+ const candidates = [...this._resolvers].flatMap((resolver) => resolver.resolve(unitId, body)).filter((replacement) => Number.isInteger(replacement.startOffset) && Number.isInteger(replacement.endOffset) && replacement.startOffset >= 0 && replacement.endOffset > replacement.startOffset && replacement.endOffset <= body.dataStream.length).sort((left, right) => left.startOffset - right.startOffset || right.endOffset - left.endOffset);
1762
+ const replacements = [];
1763
+ let previousEnd = -1;
1764
+ for (const candidate of candidates) {
1765
+ if (candidate.startOffset < previousEnd) continue;
1766
+ replacements.push(candidate);
1767
+ previousEnd = candidate.endOffset;
1768
+ }
1769
+ return replacements;
1770
+ }
1771
+ dispose() {
1772
+ this._textChanged$.complete();
1773
+ super.dispose();
1774
+ }
1775
+ };
1776
+
1456
1777
  //#endregion
1457
1778
  //#region src/plugin.ts
1458
1779
  let UniverDocsPlugin = class UniverDocsPlugin extends _univerjs_core.Plugin {
@@ -1476,8 +1797,10 @@ let UniverDocsPlugin = class UniverDocsPlugin extends _univerjs_core.Plugin {
1476
1797
  CreateHeaderFooterCommand,
1477
1798
  SetDocumentDefaultParagraphStyleCommand,
1478
1799
  SetSectionHeaderFooterLinkCommand,
1800
+ UpdateDocumentParagraphStyleCommand,
1479
1801
  UpdateDocumentSectionCommand,
1480
1802
  InsertDocumentSectionBreakCommand,
1803
+ InsertDocumentColumnBreakCommand,
1481
1804
  DeleteDocumentSectionBreakCommand,
1482
1805
  RichTextEditingMutation,
1483
1806
  DocsRenameMutation,
@@ -1493,6 +1816,7 @@ let UniverDocsPlugin = class UniverDocsPlugin extends _univerjs_core.Plugin {
1493
1816
  [DocStateChangeManagerService],
1494
1817
  [DocBlockMoveValidatorService],
1495
1818
  [DocContentInsertService],
1819
+ [DocTextResolverService],
1496
1820
  [DocCustomRangeController]
1497
1821
  ].forEach((d) => this._injector.add(d));
1498
1822
  }
@@ -1746,22 +2070,6 @@ function replaceSelectionFactory(accessor, params) {
1746
2070
  return doMutation;
1747
2071
  }
1748
2072
 
1749
- //#endregion
1750
- //#region src/utils/section-columns.ts
1751
- /** Creates explicit OOXML section columns from a count, gap, and optional widths. */
1752
- function createSectionColumnProperties(documentStyle, section, columnCount, gap, widths) {
1753
- var _ref, _section$pageSize$wid, _section$pageSize, _documentStyle$pageSi, _ref2, _section$marginLeft, _ref3, _section$marginRight;
1754
- if (columnCount <= 1) return [];
1755
- const safeGap = Math.max(0, gap);
1756
- const pageWidth = (_ref = (_section$pageSize$wid = section === null || section === void 0 || (_section$pageSize = section.pageSize) === null || _section$pageSize === void 0 ? void 0 : _section$pageSize.width) !== null && _section$pageSize$wid !== void 0 ? _section$pageSize$wid : documentStyle === null || documentStyle === void 0 || (_documentStyle$pageSi = documentStyle.pageSize) === null || _documentStyle$pageSi === void 0 ? void 0 : _documentStyle$pageSi.width) !== null && _ref !== void 0 ? _ref : _univerjs_core.PAGE_SIZE[_univerjs_core.PaperType.A4].width;
1757
- const contentWidth = Math.max(0, pageWidth - ((_ref2 = (_section$marginLeft = section === null || section === void 0 ? void 0 : section.marginLeft) !== null && _section$marginLeft !== void 0 ? _section$marginLeft : documentStyle === null || documentStyle === void 0 ? void 0 : documentStyle.marginLeft) !== null && _ref2 !== void 0 ? _ref2 : 72) - ((_ref3 = (_section$marginRight = section === null || section === void 0 ? void 0 : section.marginRight) !== null && _section$marginRight !== void 0 ? _section$marginRight : documentStyle === null || documentStyle === void 0 ? void 0 : documentStyle.marginRight) !== null && _ref3 !== void 0 ? _ref3 : 72));
1758
- const availableWidth = Math.max(0, contentWidth - safeGap * (columnCount - 1));
1759
- return (widths !== null && widths !== void 0 ? widths : Array.from({ length: columnCount }, () => availableWidth / columnCount)).map((width, index) => ({
1760
- width: Math.max(0, width),
1761
- paddingEnd: index === columnCount - 1 ? 0 : safeGap
1762
- }));
1763
- }
1764
-
1765
2073
  //#endregion
1766
2074
  //#region src/utils/transform-position.ts
1767
2075
  function buildDocTransform(width, height, position) {
@@ -1849,6 +2157,7 @@ function normalizeTextRange(textRange) {
1849
2157
  //#endregion
1850
2158
  exports.CreateHeaderFooterCommand = CreateHeaderFooterCommand;
1851
2159
  exports.DOC_INTERCEPTOR_POINT = DOC_INTERCEPTOR_POINT;
2160
+ exports.DOC_SELECTION_OPTION_PRESERVE_CARET = DOC_SELECTION_OPTION_PRESERVE_CARET;
1852
2161
  exports.DeleteDocumentSectionBreakCommand = DeleteDocumentSectionBreakCommand;
1853
2162
  exports.DeleteTextCommand = DeleteTextCommand;
1854
2163
  exports.DocBlockMoveValidatorService = DocBlockMoveValidatorService;
@@ -1878,9 +2187,11 @@ Object.defineProperty(exports, 'DocStateChangeManagerService', {
1878
2187
  }
1879
2188
  });
1880
2189
  exports.DocStateEmitService = DocStateEmitService;
2190
+ exports.DocTextResolverService = DocTextResolverService;
1881
2191
  exports.EMBED_DOCS_CUSTOM_BLOCK_DEFAULT_COMPONENT_KEY = EMBED_DOCS_CUSTOM_BLOCK_DEFAULT_COMPONENT_KEY;
1882
2192
  exports.HeaderFooterType = HeaderFooterType;
1883
2193
  exports.IDocStateChangeInterceptorService = IDocStateChangeInterceptorService;
2194
+ exports.InsertDocumentColumnBreakCommand = InsertDocumentColumnBreakCommand;
1884
2195
  exports.InsertDocumentSectionBreakCommand = InsertDocumentSectionBreakCommand;
1885
2196
  exports.InsertTextCommand = InsertTextCommand;
1886
2197
  exports.RichTextEditingMutation = RichTextEditingMutation;
@@ -1893,6 +2204,7 @@ Object.defineProperty(exports, 'UniverDocsPlugin', {
1893
2204
  return UniverDocsPlugin;
1894
2205
  }
1895
2206
  });
2207
+ exports.UpdateDocumentParagraphStyleCommand = UpdateDocumentParagraphStyleCommand;
1896
2208
  exports.UpdateDocumentSectionCommand = UpdateDocumentSectionCommand;
1897
2209
  exports.UpdateTextCommand = UpdateTextCommand;
1898
2210
  exports.addCustomRangeBySelectionFactory = addCustomRangeBySelectionFactory;
@@ -1910,6 +2222,8 @@ exports.deleteCustomRangeFactory = deleteCustomRangeFactory;
1910
2222
  exports.docDrawingPositionToTransform = docDrawingPositionToTransform;
1911
2223
  exports.generateParagraphs = generateParagraphs;
1912
2224
  exports.getContentInsertRange = getContentInsertRange;
2225
+ exports.getEffectiveSectionPageSetup = getEffectiveSectionPageSetup;
2226
+ exports.getSectionContentWidth = getSectionContentWidth;
1913
2227
  exports.getTopLevelSectionBreaks = getTopLevelSectionBreaks;
1914
2228
  exports.isEmbedDocsCustomBlockData = isEmbedDocsCustomBlockData;
1915
2229
  exports.isHeaderFooterSelection = isHeaderFooterSelection;