@univerjs/docs 1.0.0-alpha.1 → 1.0.0-alpha.3

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.
Files changed (32) hide show
  1. package/lib/cjs/facade.js +1156 -868
  2. package/lib/cjs/index.js +723 -18
  3. package/lib/es/facade.js +1154 -867
  4. package/lib/es/index.js +701 -19
  5. package/lib/facade.js +1154 -867
  6. package/lib/index.js +701 -19
  7. package/lib/types/commands/commands/create-header-footer.command.d.ts +45 -0
  8. package/lib/types/commands/commands/set-document-default-paragraph-style.command.d.ts +24 -0
  9. package/lib/types/commands/commands/set-section-header-footer-link.command.d.ts +26 -0
  10. package/lib/types/commands/commands/update-document-section.command.d.ts +38 -0
  11. package/lib/types/embed-host-anchor.d.ts +61 -0
  12. package/lib/types/facade/f-document-paragraph.d.ts +87 -100
  13. package/lib/types/facade/f-document-section.d.ts +281 -0
  14. package/lib/types/facade/f-document-text-range.d.ts +136 -0
  15. package/lib/types/facade/f-document.d.ts +316 -26
  16. package/lib/types/facade/f-enum.d.ts +32 -0
  17. package/lib/types/facade/f-types.d.ts +16 -0
  18. package/lib/types/facade/index.d.ts +11 -6
  19. package/lib/types/facade/utils.d.ts +15 -1
  20. package/lib/types/index.d.ts +15 -1
  21. package/lib/types/utils/paragraphs.d.ts +18 -0
  22. package/lib/types/utils/section-columns.d.ts +18 -0
  23. package/lib/types/utils/sections.d.ts +18 -0
  24. package/lib/types/utils/util.d.ts +19 -0
  25. package/lib/umd/facade.js +3 -1
  26. package/lib/umd/index.js +2 -1
  27. package/package.json +5 -5
  28. package/lib/types/facade/f-document-block-range.d.ts +0 -132
  29. package/lib/types/facade/f-document-body.d.ts +0 -276
  30. package/lib/types/facade/f-document-custom-block.d.ts +0 -57
  31. package/lib/types/facade/f-document-element.d.ts +0 -193
  32. package/lib/types/facade/f-document-table.d.ts +0 -57
package/lib/cjs/facade.js CHANGED
@@ -3,239 +3,277 @@ let _univerjs_core = require("@univerjs/core");
3
3
  let _univerjs_core_facade = require("@univerjs/core/facade");
4
4
  let _univerjs_docs = require("@univerjs/docs");
5
5
 
6
- //#region src/facade/f-document-element.ts
6
+ //#region src/facade/utils.ts
7
+ function cloneParagraphStyle(paragraphStyle) {
8
+ return paragraphStyle == null ? paragraphStyle : JSON.parse(JSON.stringify(paragraphStyle));
9
+ }
10
+ function normalizePlainTextDataStream(dataStream) {
11
+ return dataStream.replace(/\r\n/g, "\r").replace(/\n/g, "\r");
12
+ }
13
+ function getRemovedLeadingParagraphBreakLength(dataStream, removeLeadingParagraphBreak) {
14
+ const normalized = normalizePlainTextDataStream(dataStream);
15
+ if (removeLeadingParagraphBreak && normalized.length > 1 && normalized.startsWith("\r")) return 1;
16
+ return 0;
17
+ }
18
+ function buildPlainTextInsertBody(dataStream, options = {}) {
19
+ const normalizedDataStream = normalizePlainTextDataStream(dataStream).slice(getRemovedLeadingParagraphBreakLength(dataStream, options.removeLeadingParagraphBreak));
20
+ const body = {
21
+ dataStream: normalizedDataStream,
22
+ customDecorations: [],
23
+ customRanges: [],
24
+ textRuns: []
25
+ };
26
+ const paragraphs = [];
27
+ const existingParagraphIds = /* @__PURE__ */ new Set();
28
+ for (let index = 0; index < normalizedDataStream.length; index++) if (normalizedDataStream[index] === "\r") paragraphs.push({
29
+ startIndex: index,
30
+ paragraphId: (0, _univerjs_core.createParagraphId)(existingParagraphIds),
31
+ ...options.paragraphStyle == null ? {} : { paragraphStyle: cloneParagraphStyle(options.paragraphStyle) }
32
+ });
33
+ if (paragraphs.length > 0) body.paragraphs = paragraphs;
34
+ return body;
35
+ }
36
+ function replaceBodyRange(range, insertBody, docDataModel, injector) {
37
+ const { startOffset, endOffset, segmentId } = range;
38
+ const textX = new _univerjs_core.TextX();
39
+ if (startOffset > 0) textX.push({
40
+ t: _univerjs_core.TextXActionType.RETAIN,
41
+ len: startOffset
42
+ });
43
+ if (endOffset > startOffset) textX.push({
44
+ t: _univerjs_core.TextXActionType.DELETE,
45
+ len: endOffset - startOffset
46
+ });
47
+ if (insertBody.dataStream.length > 0) textX.push({
48
+ t: _univerjs_core.TextXActionType.INSERT,
49
+ body: insertBody,
50
+ len: insertBody.dataStream.length
51
+ });
52
+ const actions = _univerjs_core.JSONX.getInstance().editOp(textX.serialize(), (0, _univerjs_core.getRichTextEditPath)(docDataModel, segmentId));
53
+ const result = injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.RichTextEditingMutation.id, {
54
+ unitId: docDataModel.getUnitId(),
55
+ segmentId,
56
+ actions,
57
+ textRanges: [],
58
+ isEditing: false
59
+ });
60
+ return Boolean((result === null || result === void 0 ? void 0 : result.actions) && result.actions.length > 0);
61
+ }
62
+ function retainBodyRange(range, updateBody, coverType, docDataModel, injector) {
63
+ var _updateBody$textRuns, _docDataModel$getSelf;
64
+ const { startOffset, endOffset, segmentId } = range;
65
+ const commandService = injector.get(_univerjs_core.ICommandService);
66
+ if (((_updateBody$textRuns = updateBody.textRuns) === null || _updateBody$textRuns === void 0 ? void 0 : _updateBody$textRuns.length) && ((_docDataModel$getSelf = docDataModel.getSelfOrHeaderFooterModel(segmentId)) === null || _docDataModel$getSelf === void 0 || (_docDataModel$getSelf = _docDataModel$getSelf.getBody()) === null || _docDataModel$getSelf === void 0 ? void 0 : _docDataModel$getSelf.textRuns) == null) {
67
+ const actions = _univerjs_core.JSONX.getInstance().replaceOp([...(0, _univerjs_core.getRichTextEditPath)(docDataModel, segmentId), "textRuns"], void 0, []);
68
+ commandService.syncExecuteCommand(_univerjs_docs.RichTextEditingMutation.id, {
69
+ unitId: docDataModel.getUnitId(),
70
+ segmentId,
71
+ actions,
72
+ textRanges: [],
73
+ isEditing: false
74
+ });
75
+ }
76
+ const textX = new _univerjs_core.TextX();
77
+ if (startOffset > 0) textX.push({
78
+ t: _univerjs_core.TextXActionType.RETAIN,
79
+ len: startOffset
80
+ });
81
+ textX.push({
82
+ t: _univerjs_core.TextXActionType.RETAIN,
83
+ body: updateBody,
84
+ coverType,
85
+ len: endOffset - startOffset
86
+ });
87
+ const actions = _univerjs_core.JSONX.getInstance().editOp(textX.serialize(), (0, _univerjs_core.getRichTextEditPath)(docDataModel, segmentId));
88
+ const result = commandService.syncExecuteCommand(_univerjs_docs.RichTextEditingMutation.id, {
89
+ unitId: docDataModel.getUnitId(),
90
+ segmentId,
91
+ actions,
92
+ textRanges: [],
93
+ isEditing: false
94
+ });
95
+ return Boolean((result === null || result === void 0 ? void 0 : result.actions) && result.actions.length > 0);
96
+ }
97
+ function stripBlockTokens(text) {
98
+ return Array.from(text).map((char) => char === _univerjs_core.DataStreamTreeTokenType.PARAGRAPH ? "\n" : char).filter((char) => char !== _univerjs_core.DataStreamTreeTokenType.BLOCK_START && char !== _univerjs_core.DataStreamTreeTokenType.BLOCK_END && char !== _univerjs_core.DataStreamTreeTokenType.SECTION_BREAK).join("").replace(/\n$/, "");
99
+ }
100
+
101
+ //#endregion
102
+ //#region src/facade/f-document-text-range.ts
7
103
  /**
8
- * A generic top-level document body element.
9
- *
10
- * Use this wrapper when you need to inspect an element type first, navigate to
11
- * neighboring elements, or cast the element to a more specific facade wrapper.
12
- *
13
- * Paragraph keys are persisted `paragraphId` values. Tables, block ranges, and
14
- * custom blocks use their persisted ids.
104
+ * Facade wrapper for reading and styling a fixed document text range.
15
105
  *
106
+ * Offsets are fixed when the wrapper is created. Create a new range after edits
107
+ * that insert or remove content before it.
16
108
  * @hideconstructor
17
109
  */
18
- var FDocumentElement = class extends _univerjs_core_facade.FBase {
19
- constructor(_body, _bodyEdit, _info, _injector) {
20
- super();
21
- this._body = _body;
22
- this._bodyEdit = _bodyEdit;
23
- this._info = _info;
110
+ var FDocumentTextRange = class {
111
+ constructor(_document, _startOffset, _endOffset, _segmentId, _injector) {
112
+ this._document = _document;
113
+ this._startOffset = _startOffset;
114
+ this._endOffset = _endOffset;
115
+ this._segmentId = _segmentId;
24
116
  this._injector = _injector;
117
+ this._validateRange();
25
118
  }
26
119
  /**
27
- * Get the document element type.
28
- * @returns {DocumentBlockType} The element type, such as `paragraph`, `table`, `blockRange`, or `customBlock`.
29
- * @example
30
- * ```ts
31
- * const fDocument = univerAPI.getActiveDocument();
32
- * const fDocumentBody = fDocument.getBody();
33
- * const element = fDocumentBody.getElement(0);
34
- * console.log(element?.getType());
35
- * ```
36
- */
37
- getType() {
38
- return this._info.type;
39
- }
40
- /**
41
- * Whether this element is a paragraph.
42
- * @returns {boolean} `true` if this element is a paragraph.
43
- * @example
44
- * ```ts
45
- * const fDocument = univerAPI.getActiveDocument();
46
- * const fDocumentBody = fDocument.getBody();
47
- * const element = fDocumentBody.getElement(0);
48
- * console.log(element?.isParagraph());
49
- * ```
50
- */
51
- isParagraph() {
52
- return this._info.type === _univerjs_core.DocumentBlockType.PARAGRAPH;
53
- }
54
- /**
55
- * Whether this element is a table.
56
- * @returns {boolean} `true` if this element is a table.
120
+ * Returns the serializable document range.
57
121
  * @example
58
122
  * ```ts
59
123
  * const fDocument = univerAPI.getActiveDocument();
60
- * const fDocumentBody = fDocument.getBody();
61
- * const element = fDocumentBody.getElement(0);
62
- * console.log(element?.isTable());
124
+ * const range = fDocument?.findParagraphByText('Launch')?.getTextRange();
125
+ * console.log(range?.getRange());
63
126
  * ```
64
127
  */
65
- isTable() {
66
- return this._info.type === _univerjs_core.DocumentBlockType.TABLE;
67
- }
68
- /**
69
- * Whether this element is a block range, such as a callout, quote, or code block.
70
- * @returns {boolean} `true` if this element is a block range.
71
- * @example
72
- * ```ts
73
- * const fDocument = univerAPI.getActiveDocument();
74
- * const fDocumentBody = fDocument.getBody();
75
- * const element = fDocumentBody.getElement(0);
76
- * console.log(element?.isBlockRange());
77
- * ```
78
- */
79
- isBlockRange() {
80
- return this._info.type === _univerjs_core.DocumentBlockType.BLOCK_RANGE;
128
+ getRange() {
129
+ return {
130
+ startOffset: this._startOffset,
131
+ endOffset: this._endOffset,
132
+ segmentId: this._segmentId
133
+ };
81
134
  }
82
135
  /**
83
- * Whether this element is a custom block.
84
- * @returns {boolean} `true` if this element is a custom block.
136
+ * Returns the plain data-stream text in this range.
85
137
  * @example
86
138
  * ```ts
87
139
  * const fDocument = univerAPI.getActiveDocument();
88
- * const fDocumentBody = fDocument.getBody();
89
- * const element = fDocumentBody.getElement(0);
90
- * console.log(element?.isCustomBlock());
140
+ * const range = fDocument?.findParagraphByText('Launch')?.getTextRange();
141
+ * console.log(range?.getText());
91
142
  * ```
92
143
  */
93
- isCustomBlock() {
94
- return this._info.type === _univerjs_core.DocumentBlockType.CUSTOM_BLOCK;
144
+ getText() {
145
+ return this._document.getBody(this._segmentId).dataStream.slice(this._startOffset, this._endOffset);
95
146
  }
96
147
  /**
97
- * Get the facade key used to resolve this element.
98
- * @returns {string} The paragraph `paragraphId` or persisted table/block/custom block id.
148
+ * Returns explicit text-style runs intersecting this range.
149
+ * Returned offsets are clipped to the range and remain document-relative.
99
150
  * @example
100
151
  * ```ts
101
152
  * const fDocument = univerAPI.getActiveDocument();
102
- * const fDocumentBody = fDocument.getBody();
103
- * const element = fDocumentBody.getElement(0);
104
- * console.log(element?.getKey());
153
+ * const range = fDocument?.findParagraphByText('Launch')?.getTextRange();
154
+ * console.log(range?.getExplicitTextStyleRuns());
105
155
  * ```
106
156
  */
107
- getKey() {
108
- return this._info.key;
157
+ getExplicitTextStyleRuns() {
158
+ const { textRuns = [] } = this._document.getBody(this._segmentId);
159
+ return textRuns.filter((run) => run.st < this._endOffset && run.ed > this._startOffset).map((run) => {
160
+ var _run$ts;
161
+ return {
162
+ startOffset: Math.max(run.st, this._startOffset),
163
+ endOffset: Math.min(run.ed, this._endOffset),
164
+ textStyle: _univerjs_core.Tools.deepClone((_run$ts = run.ts) !== null && _run$ts !== void 0 ? _run$ts : {})
165
+ };
166
+ });
109
167
  }
110
- /**
111
- * Get the parent body facade that owns this element.
112
- * @returns {FDocumentBody} The document body facade.
113
- * @example
114
- * ```ts
115
- * const fDocument = univerAPI.getActiveDocument();
116
- * const fDocumentBody = fDocument.getBody();
117
- * const element = fDocumentBody.getElement(0);
118
- * console.log(element?.getParent());
119
- * ```
120
- */
121
- getParent() {
122
- return this._body;
168
+ /** @deprecated Use `getExplicitTextStyleRuns()` to distinguish stored styles from effective styles. */
169
+ getTextStyleRuns() {
170
+ return this.getExplicitTextStyleRuns();
123
171
  }
124
172
  /**
125
- * Get the resolved element info for this wrapper.
126
- * @returns {IFDocumentElementInfo} The resolved element info, including type, key, position, and priority.
173
+ * Returns top-level style properties that have the same explicit value
174
+ * across the complete range. Unstyled gaps make a property non-common.
127
175
  * @example
128
176
  * ```ts
129
177
  * const fDocument = univerAPI.getActiveDocument();
130
- * const fDocumentBody = fDocument.getBody();
131
- * const element = fDocumentBody.getElement(0);
132
- * console.log(element?.getResolvedInfo());
178
+ * const range = fDocument?.findParagraphByText('Launch')?.getTextRange();
179
+ * console.log(range?.getCommonExplicitTextStyle());
133
180
  * ```
134
181
  */
135
- getResolvedInfo() {
136
- return this._info;
182
+ getCommonExplicitTextStyle() {
183
+ if (this._startOffset === this._endOffset) return {};
184
+ const [first, ...rest] = this._getStyleSegments();
185
+ const common = _univerjs_core.Tools.deepClone(first.textStyle);
186
+ for (const key of Object.keys(common)) if (rest.some((run) => !isDeepEqual(run.textStyle[key], common[key]))) delete common[key];
187
+ return common;
137
188
  }
138
- /**
139
- * Get the next sibling element in the current body order.
140
- * @returns {FDocumentElement | null} The next sibling wrapper, or `null` when this is the last child.
141
- * @example
142
- * ```ts
143
- * const fDocument = univerAPI.getActiveDocument();
144
- * const fDocumentBody = fDocument.getBody();
145
- * const element = fDocumentBody.getElement(0);
146
- * console.log(element?.getNextSibling());
147
- * ```
148
- */
149
- getNextSibling() {
150
- return this._createSibling(1);
189
+ /** @deprecated Use `getCommonExplicitTextStyle()` to distinguish stored styles from effective styles. */
190
+ getCommonTextStyle() {
191
+ return this.getCommonExplicitTextStyle();
151
192
  }
152
193
  /**
153
- * Get the previous sibling element in the current body order.
154
- * @returns {FDocumentElement | null} The previous sibling wrapper, or `null` when this is the first child.
194
+ * Returns a serializable summary suitable for an agent/tool response.
155
195
  * @example
156
196
  * ```ts
157
197
  * const fDocument = univerAPI.getActiveDocument();
158
- * const fDocumentBody = fDocument.getBody();
159
- * const element = fDocumentBody.getElement(1);
160
- * console.log(element?.getPreviousSibling());
198
+ * const range = fDocument?.findParagraphByText('Launch')?.getTextRange();
199
+ * console.log(range?.describe());
161
200
  * ```
162
201
  */
163
- getPreviousSibling() {
164
- return this._createSibling(-1);
202
+ describe() {
203
+ const explicitTextStyleRuns = this.getExplicitTextStyleRuns();
204
+ const commonExplicitTextStyle = this.getCommonExplicitTextStyle();
205
+ return {
206
+ ...this.getRange(),
207
+ text: this.getText(),
208
+ length: this._endOffset - this._startOffset,
209
+ explicitTextStyleRuns,
210
+ commonExplicitTextStyle,
211
+ textStyleRuns: explicitTextStyleRuns,
212
+ commonTextStyle: commonExplicitTextStyle
213
+ };
165
214
  }
166
215
  /**
167
- * Get the sibling element at a relative offset from this element.
168
- * @param {number} offset The relative offset from this element. Use `1` for the next sibling, `-1` for the previous sibling, and so on.
169
- * @returns {FDocumentElement | null} The sibling wrapper at the specified offset, or `null` when the offset is out of range.
216
+ * Merges a text-style patch into every character in the range.
217
+ * Existing text-run splitting, merging, and normalization are handled by
218
+ * the document mutation pipeline.
219
+ * `style.fs` is a font size in points (pt), not CSS pixels.
170
220
  * @example
171
221
  * ```ts
172
222
  * const fDocument = univerAPI.getActiveDocument();
173
- * const fDocumentBody = fDocument.getBody();
174
- * const element = fDocumentBody.getElement(0);
175
- *
176
- * // Get the third sibling after this element
177
- * const nextThirdSibling = element?.getSibling(3);
178
- * console.log(nextThirdSibling?.getType());
223
+ * const range = fDocument?.findParagraphByText('Launch')?.getTextRange();
224
+ * range?.setTextStyle({ fs: 10.5, bl: univerAPI.Enum.BooleanNumber.TRUE });
179
225
  * ```
180
226
  */
181
- getSibling(offset) {
182
- return this._createSibling(offset);
227
+ setTextStyle(style) {
228
+ if (this._startOffset === this._endOffset) return false;
229
+ return retainBodyRange(this.getRange(), {
230
+ dataStream: "",
231
+ textRuns: [{
232
+ st: 0,
233
+ ed: this._endOffset - this._startOffset,
234
+ ts: _univerjs_core.Tools.deepClone(style)
235
+ }]
236
+ }, _univerjs_core.UpdateDocsAttributeType.COVER, this._document.getDocumentDataModel(), this._injector);
183
237
  }
184
238
  /**
185
- * Remove this element from its parent body.
186
- * @returns {boolean} `true` if the element content was removed.
239
+ * Replaces the range with plain text while preserving document mutation semantics.
187
240
  * @example
188
241
  * ```ts
189
242
  * const fDocument = univerAPI.getActiveDocument();
190
- * const fDocumentBody = fDocument.getBody();
191
- * const element = fDocumentBody.getElement(0);
192
- * const removed = element?.remove();
193
- * console.log(removed);
243
+ * const range = fDocument?.findParagraphByText('Draft')?.getTextRange();
244
+ * range?.setText('Final');
194
245
  * ```
195
246
  */
196
- remove() {
197
- if (this.isParagraph()) return this._body.removeParagraph(this.asParagraph());
198
- if (this.isBlockRange()) return this._body.removeBlockRange(this.asBlockRange());
199
- if (this.isTable()) return this._body.removeTable(this.asTable());
200
- return this._body.removeCustomBlock(this.asCustomBlock());
201
- }
202
- _createSibling(offset) {
203
- if (offset === 0) throw new Error("Offset cannot be zero.");
204
- const index = this._body.getElementIndex(this);
205
- return this._body.getElement(index + offset);
247
+ setText(text) {
248
+ return replaceBodyRange(this.getRange(), buildPlainTextInsertBody(text), this._document.getDocumentDataModel(), this._injector);
249
+ }
250
+ _validateRange() {
251
+ const bodyLength = this._document.getBody(this._segmentId).dataStream.length;
252
+ if (!Number.isInteger(this._startOffset) || !Number.isInteger(this._endOffset) || this._startOffset < 0 || this._endOffset < this._startOffset || this._endOffset > bodyLength) throw new RangeError(`Invalid document text range [${this._startOffset}, ${this._endOffset}) for body length ${bodyLength}.`);
253
+ }
254
+ _getStyleSegments() {
255
+ const explicitRuns = this.getExplicitTextStyleRuns();
256
+ const segments = [];
257
+ let offset = this._startOffset;
258
+ for (const run of explicitRuns) {
259
+ if (offset < run.startOffset) segments.push({
260
+ startOffset: offset,
261
+ endOffset: run.startOffset,
262
+ textStyle: {}
263
+ });
264
+ segments.push(run);
265
+ offset = run.endOffset;
266
+ }
267
+ if (offset < this._endOffset) segments.push({
268
+ startOffset: offset,
269
+ endOffset: this._endOffset,
270
+ textStyle: {}
271
+ });
272
+ return segments;
206
273
  }
207
274
  };
208
-
209
- //#endregion
210
- //#region src/facade/utils.ts
211
- function cloneParagraphStyle(paragraphStyle) {
212
- return paragraphStyle == null ? paragraphStyle : JSON.parse(JSON.stringify(paragraphStyle));
213
- }
214
- function normalizePlainTextDataStream(dataStream) {
215
- return dataStream.replace(/\r\n/g, "\r").replace(/\n/g, "\r");
216
- }
217
- function getRemovedLeadingParagraphBreakLength(dataStream, removeLeadingParagraphBreak) {
218
- const normalized = normalizePlainTextDataStream(dataStream);
219
- if (removeLeadingParagraphBreak && normalized.length > 1 && normalized.startsWith("\r")) return 1;
220
- return 0;
221
- }
222
- function buildPlainTextInsertBody(dataStream, options = {}) {
223
- const normalizedDataStream = normalizePlainTextDataStream(dataStream).slice(getRemovedLeadingParagraphBreakLength(dataStream, options.removeLeadingParagraphBreak));
224
- const body = {
225
- dataStream: normalizedDataStream,
226
- customDecorations: [],
227
- customRanges: [],
228
- textRuns: []
229
- };
230
- const paragraphs = [];
231
- const existingParagraphIds = /* @__PURE__ */ new Set();
232
- for (let index = 0; index < normalizedDataStream.length; index++) if (normalizedDataStream[index] === "\r") paragraphs.push({
233
- startIndex: index,
234
- paragraphId: (0, _univerjs_core.createParagraphId)(existingParagraphIds),
235
- ...options.paragraphStyle == null ? {} : { paragraphStyle: cloneParagraphStyle(options.paragraphStyle) }
236
- });
237
- if (paragraphs.length > 0) body.paragraphs = paragraphs;
238
- return body;
275
+ function isDeepEqual(left, right) {
276
+ return JSON.stringify(left) === JSON.stringify(right);
239
277
  }
240
278
 
241
279
  //#endregion
@@ -249,14 +287,12 @@ function buildPlainTextInsertBody(dataStream, options = {}) {
249
287
  *
250
288
  * @hideconstructor
251
289
  */
252
- var FDocumentParagraph = class extends FDocumentElement {
253
- constructor(body, bodyEdit, info, injector) {
254
- super(body, bodyEdit, info, injector);
255
- this.body = body;
256
- this.bodyEdit = bodyEdit;
257
- this.info = info;
258
- this.injector = injector;
259
- if (this.getType() !== _univerjs_core.DocumentBlockType.PARAGRAPH) throw new Error(`Element type is not a paragraph: ${this.getType()}`);
290
+ var FDocumentParagraph = class {
291
+ constructor(_document, _paragraphId, _segmentId = "", _injector) {
292
+ this._document = _document;
293
+ this._paragraphId = _paragraphId;
294
+ this._segmentId = _segmentId;
295
+ this._injector = _injector;
260
296
  }
261
297
  /**
262
298
  * Get the persisted paragraph id.
@@ -264,46 +300,52 @@ var FDocumentParagraph = class extends FDocumentElement {
264
300
  * @example
265
301
  * ```ts
266
302
  * const fDocument = univerAPI.getActiveDocument();
267
- * const fDocumentBody = fDocument.getBody();
268
- * const element = fDocumentBody.getElement(0);
269
- *
270
- * if (element?.isParagraph()) {
271
- * const paragraph = element.asParagraph();
272
- * console.log(paragraph.getParagraphId());
273
- * }
303
+ * const paragraph = fDocument.getParagraphs()[0];
304
+ * console.log(paragraph?.getId());
274
305
  * ```
275
306
  */
276
- getParagraphId() {
277
- return this.getKey();
307
+ getId() {
308
+ return this._paragraphId;
278
309
  }
279
310
  /**
280
- * Get the resolved paragraph info for this wrapper.
281
- * @returns {IFDocumentResolvedParagraph} The resolved paragraph info, including the paragraph object, its index, and its text range.
311
+ * Get the segment id of this paragraph.
312
+ * The main body paragraphs have an empty string segment id.
313
+ * The header and footer paragraphs have a non-empty string segment id.
314
+ * @returns {string} The segment id.
282
315
  * @example
283
316
  * ```ts
284
317
  * const fDocument = univerAPI.getActiveDocument();
285
- * const fDocumentBody = fDocument.getBody();
286
- * const element = fDocumentBody.getElement(0);
287
- *
288
- * if (element?.isParagraph()) {
289
- * const paragraph = element.asParagraph();
290
- * console.log(paragraph.getResolvedParagraphInfo());
291
- * }
318
+ * const paragraph = fDocument.getParagraphs()[0];
319
+ * console.log(paragraph?.getSegmentId());
320
+ * ```
321
+ */
322
+ getSegmentId() {
323
+ return this._segmentId;
324
+ }
325
+ /**
326
+ * Get this paragraph's metadata.
327
+ * @returns {IFDocumentParagraphInfo} The paragraph info.
328
+ * @example
329
+ * ```ts
330
+ * const fDocument = univerAPI.getActiveDocument();
331
+ * const paragraph = fDocument.getParagraphs()[0];
332
+ * console.log(paragraph?.getInfo());
292
333
  * ```
293
334
  */
294
- getResolvedParagraphInfo() {
295
- const { paragraphs = [] } = this._body.getBody();
335
+ getInfo() {
336
+ const body = this._document.getBody(this._segmentId);
337
+ const { paragraphs = [] } = body;
296
338
  const matches = paragraphs.map((paragraph, paragraphIndex) => ({
297
339
  paragraph,
298
340
  paragraphIndex
299
- })).filter(({ paragraph }) => paragraph.paragraphId === this.getKey());
300
- if (matches.length === 0) throw new Error(`Document paragraph with id ${this.getKey()} not found`);
301
- if (matches.length > 1) throw new Error(`Multiple document paragraphs with id ${this.getKey()} found`);
341
+ })).filter(({ paragraph }) => paragraph.paragraphId === this._paragraphId);
342
+ if (matches.length === 0) throw new Error(`Document paragraph with id ${this._paragraphId} not found`);
343
+ if (matches.length > 1) throw new Error(`Multiple document paragraphs with id ${this._paragraphId} found`);
302
344
  const { paragraph, paragraphIndex } = matches[0];
303
345
  return {
304
346
  paragraph,
305
347
  paragraphIndex,
306
- startOffset: paragraphIndex > 0 ? paragraphs[paragraphIndex - 1].startIndex + 1 : 0,
348
+ startOffset: (0, _univerjs_core.getParagraphContentStartOffset)(body, paragraph),
307
349
  endOffset: paragraph.startIndex
308
350
  };
309
351
  }
@@ -313,42 +355,46 @@ var FDocumentParagraph = class extends FDocumentElement {
313
355
  * @example
314
356
  * ```ts
315
357
  * const fDocument = univerAPI.getActiveDocument();
316
- * const fDocumentBody = fDocument.getBody();
317
- * const element = fDocumentBody.getElement(0);
318
- *
319
- * if (element?.isParagraph()) {
320
- * const paragraph = element.asParagraph();
321
- * const range = paragraph.getRange();
322
- * fDocumentBody.setTextStyle(range, { bl: 1 });
323
- * }
358
+ * const paragraph = fDocument.getParagraphs()[0];
359
+ * console.log(paragraph?.getRange());
324
360
  * ```
325
361
  */
326
362
  getRange() {
327
- const { startOffset, endOffset } = this.getResolvedParagraphInfo();
363
+ const { startOffset, endOffset } = this.getInfo();
328
364
  return {
329
365
  startOffset,
330
366
  endOffset,
331
- segmentId: this._body.getSegmentId()
367
+ segmentId: this._segmentId
332
368
  };
333
369
  }
334
370
  /**
371
+ * Returns an agent-friendly facade for reading and styling this paragraph's text.
372
+ * @returns {FDocumentTextRange} The paragraph text range, excluding the trailing paragraph break.
373
+ * @example
374
+ * ```ts
375
+ * const fDocument = univerAPI.getActiveDocument();
376
+ * const paragraph = fDocument?.findParagraphByText('Launch');
377
+ * const range = paragraph?.getTextRange();
378
+ * console.log(range?.describe());
379
+ * ```
380
+ */
381
+ getTextRange() {
382
+ const { startOffset, endOffset } = this.getInfo();
383
+ return this._injector.createInstance(FDocumentTextRange, this._document, startOffset, endOffset, this._segmentId, this._injector);
384
+ }
385
+ /**
335
386
  * Get this paragraph's plain text.
336
387
  * @returns {string} The paragraph text without the trailing paragraph break.
337
388
  * @example
338
389
  * ```ts
339
390
  * const fDocument = univerAPI.getActiveDocument();
340
- * const fDocumentBody = fDocument.getBody();
341
- * const element = fDocumentBody.getElement(0);
342
- *
343
- * if (element?.isParagraph()) {
344
- * const paragraph = element.asParagraph();
345
- * console.log(paragraph.getText());
346
- * }
391
+ * const paragraph = fDocument.getParagraphs()[0];
392
+ * console.log(paragraph?.getText());
347
393
  * ```
348
394
  */
349
395
  getText() {
350
- const { dataStream } = this._body.getBody();
351
- const { startOffset, endOffset } = this.getResolvedParagraphInfo();
396
+ const { dataStream } = this._document.getBody(this._segmentId);
397
+ const { startOffset, endOffset } = this.getInfo();
352
398
  return dataStream.slice(startOffset, endOffset);
353
399
  }
354
400
  /**
@@ -358,22 +404,18 @@ var FDocumentParagraph = class extends FDocumentElement {
358
404
  * @example
359
405
  * ```ts
360
406
  * const fDocument = univerAPI.getActiveDocument();
361
- * const fDocumentBody = fDocument.getBody();
362
- * const element = fDocumentBody.getElement(0);
363
- *
364
- * if (element?.isParagraph()) {
365
- * const paragraph = element.asParagraph();
366
- * const success = paragraph.setText('Updated title');
367
- * console.log(success ? 'Text updated' : 'Failed to update text');
368
- * }
407
+ * const paragraph = fDocument.getParagraphs()[0];
408
+ * paragraph?.setText('New text');
409
+ * console.log(paragraph?.getText());
369
410
  * ```
370
411
  */
371
412
  setText(text) {
372
- const { startOffset, endOffset } = this.getResolvedParagraphInfo();
373
- return this._bodyEdit.replaceRange({
413
+ const { startOffset, endOffset } = this.getInfo();
414
+ return replaceBodyRange({
374
415
  startOffset,
375
- endOffset
376
- }, buildPlainTextInsertBody(text));
416
+ endOffset,
417
+ segmentId: this._segmentId
418
+ }, buildPlainTextInsertBody(text), this._document.getDocumentDataModel(), this._injector);
377
419
  }
378
420
  /**
379
421
  * Append plain text before this paragraph's trailing paragraph break.
@@ -382,38 +424,52 @@ var FDocumentParagraph = class extends FDocumentElement {
382
424
  * @example
383
425
  * ```ts
384
426
  * const fDocument = univerAPI.getActiveDocument();
385
- * const fDocumentBody = fDocument.getBody();
386
- * const element = fDocumentBody.getElement(0);
387
- *
388
- * if (element?.isParagraph()) {
389
- * const paragraph = element.asParagraph();
390
- * const success = paragraph.appendText(' Appended text');
391
- * console.log(success ? 'Text appended' : 'Failed to append text');
392
- * }
427
+ * const paragraph = fDocument.getParagraphs()[0];
428
+ * paragraph?.appendText(' Appended text');
429
+ * console.log(paragraph?.getText());
393
430
  * ```
394
431
  */
395
432
  appendText(text) {
396
- const { endOffset } = this.getResolvedParagraphInfo();
397
- return this._body.insertText(endOffset, text);
433
+ const { endOffset } = this.getInfo();
434
+ return this._document.insertText(endOffset, text, this._segmentId);
398
435
  }
399
436
  /**
400
437
  * Apply paragraph style to a paragraph handle or text range.
438
+ * `style.textStyle.fs` is a font size in points (pt), not CSS pixels.
401
439
  * @param {IParagraphStyle} style The Univer paragraph style patch.
402
440
  * @returns {boolean} `true` if the style was applied.
403
441
  * @example
404
442
  * ```ts
405
443
  * const fDocument = univerAPI.getActiveDocument();
406
- * const fDocumentBody = fDocument.getBody();
407
- * const element = fDocumentBody.getElement(0);
408
- *
409
- * if (element?.isParagraph()) {
410
- * const paragraph = element.asParagraph();
411
- * paragraph.setStyle({ horizontalAlign: 2 });
412
- * }
444
+ * const paragraph = fDocument.getParagraphs()[0];
445
+ * paragraph?.setText('Styled text');
446
+ * paragraph?.setStyle({
447
+ * textStyle: {
448
+ * cl: {
449
+ * rgb: '#FF0000',
450
+ * },
451
+ * fs: 14,
452
+ * },
453
+ * horizontalAlign: 2,
454
+ * });
455
+ * console.log(paragraph?.getInfo().paragraph.paragraphStyle);
413
456
  * ```
414
457
  */
415
458
  setStyle(style) {
416
- const { paragraph, endOffset } = this.getResolvedParagraphInfo();
459
+ const { paragraph, startOffset, endOffset } = this.getInfo();
460
+ let result = true;
461
+ if (style.textStyle && startOffset < endOffset) result = retainBodyRange({
462
+ startOffset,
463
+ endOffset,
464
+ segmentId: this._segmentId
465
+ }, {
466
+ dataStream: "",
467
+ textRuns: [{
468
+ st: 0,
469
+ ed: endOffset - startOffset,
470
+ ts: style.textStyle
471
+ }]
472
+ }, _univerjs_core.UpdateDocsAttributeType.COVER, this._document.getDocumentDataModel(), this._injector);
417
473
  const updateBody = {
418
474
  dataStream: "",
419
475
  paragraphs: [{
@@ -426,10 +482,11 @@ var FDocumentParagraph = class extends FDocumentElement {
426
482
  }]
427
483
  };
428
484
  this._preserveExplicitParagraphIds(updateBody);
429
- return this._bodyEdit.retainRange({
485
+ return retainBodyRange({
430
486
  startOffset: endOffset,
431
- endOffset: endOffset + 1
432
- }, updateBody, _univerjs_core.UpdateDocsAttributeType.REPLACE);
487
+ endOffset: endOffset + 1,
488
+ segmentId: this._segmentId
489
+ }, updateBody, _univerjs_core.UpdateDocsAttributeType.REPLACE, this._document.getDocumentDataModel(), this._injector) && result;
433
490
  }
434
491
  /**
435
492
  * Check whether this paragraph is a bullet, ordered, or checklist item.
@@ -437,17 +494,12 @@ var FDocumentParagraph = class extends FDocumentElement {
437
494
  * @example
438
495
  * ```ts
439
496
  * const fDocument = univerAPI.getActiveDocument();
440
- * const fDocumentBody = fDocument.getBody();
441
- * const element = fDocumentBody.getElement(0);
442
- *
443
- * if (element?.isParagraph()) {
444
- * const paragraph = element.asParagraph();
445
- * console.log(paragraph.isListItem() ? 'This is a list item' : 'This is not a list item');
446
- * }
497
+ * const paragraph = fDocument.getParagraphs()[0];
498
+ * console.log(paragraph?.isListItem());
447
499
  * ```
448
500
  */
449
501
  isListItem() {
450
- const { paragraph } = this.getResolvedParagraphInfo();
502
+ const { paragraph } = this.getInfo();
451
503
  return Boolean(paragraph.bullet);
452
504
  }
453
505
  /**
@@ -456,18 +508,13 @@ var FDocumentParagraph = class extends FDocumentElement {
456
508
  * @example
457
509
  * ```ts
458
510
  * const fDocument = univerAPI.getActiveDocument();
459
- * const fDocumentBody = fDocument.getBody();
460
- * const element = fDocumentBody.getElement(0);
461
- *
462
- * if (element?.isParagraph()) {
463
- * const paragraph = element.asParagraph();
464
- * console.log(paragraph.isTask() ? 'This is a task item' : 'This is not a task item');
465
- * }
511
+ * const paragraph = fDocument.getParagraphs()[0];
512
+ * console.log(paragraph?.isTask());
466
513
  * ```
467
514
  */
468
515
  isTask() {
469
516
  var _paragraph$bullet;
470
- const { paragraph } = this.getResolvedParagraphInfo();
517
+ const { paragraph } = this.getInfo();
471
518
  const listType = (_paragraph$bullet = paragraph.bullet) === null || _paragraph$bullet === void 0 ? void 0 : _paragraph$bullet.listType;
472
519
  return listType === _univerjs_core.PresetListType.CHECK_LIST || listType === _univerjs_core.PresetListType.CHECK_LIST_CHECKED;
473
520
  }
@@ -478,22 +525,17 @@ var FDocumentParagraph = class extends FDocumentElement {
478
525
  * @example
479
526
  * ```ts
480
527
  * const fDocument = univerAPI.getActiveDocument();
481
- * const fDocumentBody = fDocument.getBody();
482
- * const element = fDocumentBody.getElement(0);
528
+ * const paragraph = fDocument.getParagraphs()[0];
483
529
  *
484
- * if (element?.isParagraph()) {
485
- * const paragraph = element.asParagraph();
486
- *
487
- * if (paragraph.isTask()) {
488
- * const success = paragraph.setTaskChecked(true);
489
- * console.log(success ? 'Task checked' : 'Failed to check task');
490
- * }
530
+ * if (paragraph.isTask()) {
531
+ * const success = paragraph.setTaskChecked(true);
532
+ * console.log(success ? 'Task checked' : 'Failed to check task');
491
533
  * }
492
534
  * ```
493
535
  */
494
536
  setTaskChecked(checked) {
495
537
  if (!this.isTask()) return false;
496
- const { paragraph, endOffset } = this.getResolvedParagraphInfo();
538
+ const { paragraph, endOffset } = this.getInfo();
497
539
  const bullet = paragraph.bullet;
498
540
  const updateBody = {
499
541
  dataStream: "",
@@ -507,494 +549,488 @@ var FDocumentParagraph = class extends FDocumentElement {
507
549
  }]
508
550
  };
509
551
  this._preserveExplicitParagraphIds(updateBody);
510
- return this._bodyEdit.retainRange({
552
+ return retainBodyRange({
511
553
  startOffset: endOffset,
512
- endOffset: endOffset + 1
513
- }, updateBody, _univerjs_core.UpdateDocsAttributeType.REPLACE);
554
+ endOffset: endOffset + 1,
555
+ segmentId: this._segmentId
556
+ }, updateBody, _univerjs_core.UpdateDocsAttributeType.REPLACE, this._document.getDocumentDataModel(), this._injector);
557
+ }
558
+ /**
559
+ * Remove this paragraph.
560
+ * @returns {boolean} `true` if the paragraph was removed.
561
+ * @example
562
+ * ```ts
563
+ * const fDocument = univerAPI.getActiveDocument();
564
+ * const paragraph = fDocument.getParagraphs()[0];
565
+ * const success = paragraph?.remove();
566
+ * console.log(success ? 'Paragraph removed' : 'Failed to remove paragraph');
567
+ * ```
568
+ */
569
+ remove() {
570
+ const { startOffset, endOffset } = this.getInfo();
571
+ return this._document.deleteRange({
572
+ startOffset,
573
+ endOffset: endOffset + 1,
574
+ segmentId: this._segmentId
575
+ });
514
576
  }
515
577
  _preserveExplicitParagraphIds(body) {
516
578
  body[_univerjs_core.RESTORE_INSERTED_PARAGRAPH_IDS] = true;
517
579
  }
518
580
  };
519
- var FDocumentParagraphMixin = class extends FDocumentElement {
520
- asParagraph() {
521
- if (this.getType() !== _univerjs_core.DocumentBlockType.PARAGRAPH) throw new Error(`Element type is not a paragraph: ${this.getType()}`);
522
- return this._injector.createInstance(FDocumentParagraph, this._body, this._bodyEdit, this.getResolvedInfo(), this._injector);
523
- }
524
- };
525
- FDocumentElement.extend(FDocumentParagraphMixin);
526
-
527
- //#endregion
528
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/typeof.js
529
- function _typeof(o) {
530
- "@babel/helpers - typeof";
531
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
532
- return typeof o;
533
- } : function(o) {
534
- return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
535
- }, _typeof(o);
581
+ function isParagraphFacade(value) {
582
+ if (typeof value !== "object" || value === null) return false;
583
+ return typeof value.getId === "function" && typeof value.getSegmentId === "function" && typeof value.getInfo === "function" && typeof value.getRange === "function";
536
584
  }
537
585
 
538
586
  //#endregion
539
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPrimitive.js
540
- function toPrimitive(t, r) {
541
- if ("object" != _typeof(t) || !t) return t;
542
- var e = t[Symbol.toPrimitive];
543
- if (void 0 !== e) {
544
- var i = e.call(t, r || "default");
545
- if ("object" != _typeof(i)) return i;
546
- throw new TypeError("@@toPrimitive must return a primitive value.");
587
+ //#region src/facade/f-document-section.ts
588
+ /** Error thrown when traditional section APIs are used to mutate a modern document. */
589
+ var DocsSectionUnsupportedDocumentFlavorError = class extends Error {
590
+ constructor() {
591
+ super("Section column APIs are supported only in traditional documents. Use ColumnGroup APIs for modern documents.");
592
+ this.name = "DocsSectionUnsupportedDocumentFlavorError";
547
593
  }
548
- return ("string" === r ? String : Number)(t);
549
- }
550
-
551
- //#endregion
552
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPropertyKey.js
553
- function toPropertyKey(t) {
554
- var i = toPrimitive(t, "string");
555
- return "symbol" == _typeof(i) ? i : i + "";
556
- }
557
-
558
- //#endregion
559
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/defineProperty.js
560
- function _defineProperty(e, r, t) {
561
- return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
562
- value: t,
563
- enumerable: !0,
564
- configurable: !0,
565
- writable: !0
566
- }) : e[r] = t, e;
567
- }
568
-
569
- //#endregion
570
- //#region src/facade/f-document-body.ts
594
+ };
571
595
  /**
572
- * A Facade API object bounded to a document body or header/footer segment.
573
- * It provides Google Docs-like element access and range editing methods.
574
- *
575
- * Paragraph elements use their persisted `paragraphId`. Tables, block ranges, and
576
- * custom blocks use their persisted ids.
577
- *
578
- * @hideconstructor
596
+ * Facade wrapper for an OOXML-compatible traditional document section.
597
+ * Modern documents use ColumnGroup APIs and cannot mutate this facade.
598
+ * @example
599
+ * ```ts
600
+ * const fDocument = univerAPI.getActiveDocument();
601
+ * if (fDocument && !fDocument.isModern()) {
602
+ * console.log(fDocument.getSection(0)?.describe());
603
+ * }
604
+ * ```
579
605
  */
580
- var FDocumentBody = class {
581
- constructor(_documentDataModel, _injector, _segmentId = "") {
582
- this._documentDataModel = _documentDataModel;
606
+ var FDocumentSection = class {
607
+ constructor(_document, _sectionId, _injector) {
608
+ this._document = _document;
609
+ this._sectionId = _sectionId;
583
610
  this._injector = _injector;
584
- this._segmentId = _segmentId;
585
- _defineProperty(this, "_bodyEdit", void 0);
586
- this._bodyEdit = {
587
- replaceRange: this._replaceBodyRange.bind(this),
588
- retainRange: this._retainBodyRange.bind(this)
589
- };
590
611
  }
591
612
  /**
592
- * Get the segment id of this document body facade.
593
- * The main body has an empty string segment id.
594
- * The header and footer FDocumentBody instances have their respective segment ids.
595
- * @returns {string} The segment id of this document body facade.
613
+ * Returns the persisted section id.
596
614
  * @example
597
615
  * ```ts
598
616
  * const fDocument = univerAPI.getActiveDocument();
599
- * const fDocumentBody = fDocument.getBody();
600
- * console.log(fDocumentBody.getSegmentId());
617
+ * console.log(fDocument?.getSection(0)?.getId());
601
618
  * ```
602
619
  */
603
- getSegmentId() {
604
- return this._segmentId;
620
+ getId() {
621
+ return this._sectionId;
605
622
  }
606
623
  /**
607
- * Get the underlying document body snapshot.
608
- * @returns {IDocumentBody} The document body snapshot.
624
+ * Returns the current zero-based section index.
609
625
  * @example
610
626
  * ```ts
611
627
  * const fDocument = univerAPI.getActiveDocument();
612
- * const fDocumentBody = fDocument.getBody();
613
- * console.log(fDocumentBody.getBody());
628
+ * console.log(fDocument?.getSection(0)?.getIndex());
614
629
  * ```
615
630
  */
616
- getBody() {
617
- const body = this._documentDataModel.getSelfOrHeaderFooterModel(this._segmentId).getBody();
618
- if (!body) throw new Error("The document body is empty");
619
- return body;
631
+ getIndex() {
632
+ return this._resolve().index;
620
633
  }
621
634
  /**
622
- * Get a list of top-level child elements in the body.
623
- * @returns {FDocumentElement[]} The list of top-level document elements.
635
+ * Returns the section break snapshot that terminates this section.
624
636
  * @example
625
637
  * ```ts
626
638
  * const fDocument = univerAPI.getActiveDocument();
627
- * const fDocumentBody = fDocument.getBody();
628
- * const elements = fDocumentBody.getElements();
629
- * console.log(elements);
639
+ * console.log(fDocument?.getSection(0)?.getConfig());
630
640
  * ```
631
641
  */
632
- getElements() {
633
- return this._getChildren().map((child) => {
634
- return this._injector.createInstance(FDocumentElement, this, this._bodyEdit, child, this._injector);
635
- });
642
+ getConfig() {
643
+ const { sectionBreak } = this._resolve();
644
+ return _univerjs_core.Tools.deepClone(sectionBreak);
636
645
  }
637
646
  /**
638
- * Get a top-level child element by child index.
639
- * @param {number} index The zero-based child index.
640
- * @returns {FDocumentElement} The top-level child element wrapper.
647
+ * Returns the section content range, excluding its terminating section-break token.
641
648
  * @example
642
649
  * ```ts
643
650
  * const fDocument = univerAPI.getActiveDocument();
644
- * const fDocumentBody = fDocument.getBody();
645
- * const element = fDocumentBody.getElement(0);
646
- * console.log(element);
651
+ * console.log(fDocument?.getSection(0)?.getRange());
647
652
  * ```
648
653
  */
649
- getElement(index) {
650
- var _this$getElements$ind;
651
- return (_this$getElements$ind = this.getElements()[index]) !== null && _this$getElements$ind !== void 0 ? _this$getElements$ind : null;
654
+ getRange() {
655
+ const sectionBreaks = (0, _univerjs_docs.getTopLevelSectionBreaks)(this._document.getBody());
656
+ const { index, sectionBreak } = this._resolve();
657
+ return {
658
+ startOffset: index === 0 ? 0 : sectionBreaks[index - 1].startIndex + 1,
659
+ endOffset: sectionBreak.startIndex,
660
+ segmentId: ""
661
+ };
652
662
  }
653
663
  /**
654
- * Get the current child index of an element handle.
655
- * The index is resolved from the element key, so a paragraph handle keeps pointing
656
- * to the same paragraph after facade edits insert content before it.
657
- * @param {FDocumentElement} element The element handle to locate.
658
- * @returns {number} The current zero-based child index.
664
+ * Returns the explicit columns. An empty array means the normal single-column layout.
665
+ * Column widths and trailing spaces are in points (pt).
659
666
  * @example
660
667
  * ```ts
661
668
  * const fDocument = univerAPI.getActiveDocument();
662
- * const fDocumentBody = fDocument.getBody();
663
- * const element = fDocumentBody.getElement(0);
664
- * console.log(fDocumentBody.getElementIndex(element));
669
+ * console.log(fDocument?.getSection(0)?.getColumns());
665
670
  * ```
666
671
  */
667
- getElementIndex(element) {
668
- const { type, key } = element.getResolvedInfo();
669
- const index = this._getChildren().findIndex((child) => child.type === type && child.key === key);
670
- if (index < 0) throw new Error("Doc element is stale");
671
- return index;
672
+ getColumns() {
673
+ var _this$getConfig$colum;
674
+ return _univerjs_core.Tools.deepClone((_this$getConfig$colum = this.getConfig().columnProperties) !== null && _this$getConfig$colum !== void 0 ? _this$getConfig$colum : []);
672
675
  }
673
676
  /**
674
- * Insert plain text at a document body offset.
675
- * @param {number} index The zero-based insertion offset.
676
- * @param {string} text The plain text to insert.
677
- * @returns {boolean} `true` if the edit was applied.
677
+ * Returns a compact serializable section summary.
678
678
  * @example
679
679
  * ```ts
680
680
  * const fDocument = univerAPI.getActiveDocument();
681
- * const fDocumentBody = fDocument.getBody();
682
- * fDocumentBody.insertText(0, 'Hello ');
681
+ * console.log(fDocument?.getSection(0)?.describe());
683
682
  * ```
684
683
  */
685
- insertText(index, text) {
686
- return this._replaceBodyRange({
687
- startOffset: index,
688
- endOffset: index
689
- }, buildPlainTextInsertBody(text));
684
+ describe() {
685
+ var _config$columnPropert, _config$columnSeparat, _config$sectionType;
686
+ const config = this.getConfig();
687
+ const columns = (_config$columnPropert = config.columnProperties) !== null && _config$columnPropert !== void 0 ? _config$columnPropert : [];
688
+ const headerFooter = {
689
+ defaultHeader: this._describeHeaderFooterReference("header", "default"),
690
+ defaultFooter: this._describeHeaderFooterReference("footer", "default"),
691
+ firstHeader: this._describeHeaderFooterReference("header", "first"),
692
+ firstFooter: this._describeHeaderFooterReference("footer", "first"),
693
+ evenHeader: this._describeHeaderFooterReference("header", "even"),
694
+ evenFooter: this._describeHeaderFooterReference("footer", "even")
695
+ };
696
+ return {
697
+ sectionId: this._sectionId,
698
+ index: this.getIndex(),
699
+ range: this.getRange(),
700
+ columnCount: columns.length || 1,
701
+ columns: _univerjs_core.Tools.deepClone(columns),
702
+ columnSeparatorType: (_config$columnSeparat = config.columnSeparatorType) !== null && _config$columnSeparat !== void 0 ? _config$columnSeparat : _univerjs_core.ColumnSeparatorType.NONE,
703
+ sectionType: (_config$sectionType = config.sectionType) !== null && _config$sectionType !== void 0 ? _config$sectionType : _univerjs_core.SectionType.SECTION_TYPE_UNSPECIFIED,
704
+ headerFooter,
705
+ config
706
+ };
690
707
  }
691
708
  /**
692
- * Apply text style to a body range.
693
- * @param {IFDocumentTextRange} range The range to style.
694
- * @param {ITextStyle} style The Univer text style patch.
695
- * @returns {boolean} `true` if the style was applied.
709
+ * Sets equal or explicitly sized columns for this traditional section.
710
+ * Use `columnCount = 1` to restore normal single-column layout.
711
+ * `gap` and `widths` are in points (pt).
696
712
  * @example
697
713
  * ```ts
698
714
  * const fDocument = univerAPI.getActiveDocument();
699
- * const fDocumentBody = fDocument.getBody();
700
- * fDocumentBody.setTextStyle({ startOffset: 0, endOffset: 5 }, { bl: 1 });
715
+ * if (fDocument && !fDocument.isModern()) {
716
+ * fDocument.getSection(0)?.setColumns(2, { gap: 18, separator: true });
717
+ * }
701
718
  * ```
702
719
  */
703
- setTextStyle(range, style) {
704
- const updateBody = {
705
- dataStream: "",
706
- textRuns: [{
707
- st: 0,
708
- ed: range.endOffset - range.startOffset,
709
- ts: style
710
- }]
711
- };
712
- return this._retainBodyRange(range, updateBody, _univerjs_core.UpdateDocsAttributeType.COVER);
720
+ setColumns(columnCount, options = {}) {
721
+ var _options$gap, _options$separator;
722
+ this._assertTraditionalDocument();
723
+ if (!Number.isInteger(columnCount) || columnCount < 1) throw new RangeError("Section column count must be a positive integer.");
724
+ if (options.widths && options.widths.length !== columnCount) throw new RangeError("Section column widths must match the column count.");
725
+ const gap = Math.max(0, (_options$gap = options.gap) !== null && _options$gap !== void 0 ? _options$gap : 18);
726
+ const config = this.getConfig();
727
+ const columns = (0, _univerjs_docs.createSectionColumnProperties)(this._document.getDocumentDataModel().getSnapshot().documentStyle, config, columnCount, gap, options.widths);
728
+ const separator = typeof options.separator === "boolean" ? options.separator ? _univerjs_core.ColumnSeparatorType.BETWEEN_EACH_COLUMN : _univerjs_core.ColumnSeparatorType.NONE : (_options$separator = options.separator) !== null && _options$separator !== void 0 ? _options$separator : _univerjs_core.ColumnSeparatorType.NONE;
729
+ return this._update({
730
+ columnProperties: columns,
731
+ columnSeparatorType: separator,
732
+ ...options.sectionType == null ? {} : { sectionType: options.sectionType }
733
+ });
713
734
  }
714
735
  /**
715
- * Insert a plain-text paragraph before the paragraph at the given paragraph index.
716
- * @param {number} index The zero-based paragraph insertion index.
717
- * @param {string} text The paragraph text. Defaults to an empty paragraph.
718
- * @returns {FDocumentParagraph} The inserted paragraph wrapper.
736
+ * Sets explicit OOXML-compatible column width and trailing-space values in points (pt).
719
737
  * @example
720
738
  * ```ts
721
739
  * const fDocument = univerAPI.getActiveDocument();
722
- * const fDocumentBody = fDocument.getBody();
723
- * const paragraph = fDocumentBody.insertParagraph(0, 'Document title');
724
- * paragraph.appendText(' suffix');
740
+ * if (fDocument && !fDocument.isModern()) {
741
+ * fDocument.getSection(0)?.setColumnProperties([
742
+ * { width: 240, paddingEnd: 18 },
743
+ * { width: 240, paddingEnd: 0 },
744
+ * ], univerAPI.Enum.ColumnSeparatorType.BETWEEN_EACH_COLUMN);
745
+ * }
725
746
  * ```
726
747
  */
727
- insertParagraph(index, text = "") {
728
- var _paragraphs;
729
- const offset = this._getParagraphInsertOffset(index);
730
- if (!this._replaceBodyRange({
731
- startOffset: offset,
732
- endOffset: offset
733
- }, buildPlainTextInsertBody(`${text}\r`))) throw new Error("Failed to insert paragraph.");
734
- const { paragraphs = [] } = this.getBody();
735
- const paragraph = paragraphs[index];
736
- if (!paragraph) throw new Error("Failed to insert paragraph.");
737
- const info = this._resolveParagraphInfo(paragraph, index, (_paragraphs = paragraphs[index - 1]) === null || _paragraphs === void 0 ? void 0 : _paragraphs.startIndex);
738
- return this._injector.createInstance(FDocumentParagraph, this, this._bodyEdit, info, this._injector);
748
+ setColumnProperties(columns, separator = _univerjs_core.ColumnSeparatorType.NONE) {
749
+ this._assertTraditionalDocument();
750
+ if (columns.some(({ width, paddingEnd }) => width < 0 || paddingEnd < 0)) throw new RangeError("Section column widths and padding must be non-negative.");
751
+ return this._update({
752
+ columnProperties: _univerjs_core.Tools.deepClone(columns),
753
+ columnSeparatorType: separator
754
+ });
739
755
  }
740
756
  /**
741
- * Append a plain-text paragraph at the end of the body.
742
- * @param {string} text The paragraph text. Defaults to an empty paragraph.
743
- * @returns {FDocumentParagraph} The appended paragraph wrapper.
757
+ * Sets how the next section begins.
744
758
  * @example
745
759
  * ```ts
746
760
  * const fDocument = univerAPI.getActiveDocument();
747
- * const fDocumentBody = fDocument.getBody();
748
- * const paragraph = fDocumentBody.appendParagraph('Summary');
749
- * console.log(paragraph.getText());
761
+ * if (fDocument && !fDocument.isModern()) {
762
+ * fDocument.getSection(0)?.setSectionType(univerAPI.Enum.SectionType.NEXT_PAGE);
763
+ * }
750
764
  * ```
751
765
  */
752
- appendParagraph(text = "") {
753
- const { paragraphs = [] } = this.getBody();
754
- return this.insertParagraph(paragraphs.length, text);
766
+ setSectionType(sectionType) {
767
+ this._assertTraditionalDocument();
768
+ return this._update({ sectionType });
755
769
  }
756
770
  /**
757
- * Delete a range from the body.
758
- * @param {IFDocumentTextRange} range The text range to delete.
759
- * @returns {boolean} `true` if the range was deleted.
771
+ * Ensures a header segment linked specifically to this section.
760
772
  * @example
761
773
  * ```ts
762
774
  * const fDocument = univerAPI.getActiveDocument();
763
- * const fDocumentBody = fDocument.getBody();
764
- * fDocumentBody.deleteRange({ startOffset: 0, endOffset: 5 });
775
+ * if (fDocument && !fDocument.isModern()) {
776
+ * const segmentId = fDocument.getSection(0)?.ensureHeader();
777
+ * if (segmentId) {
778
+ * fDocument.insertText(0, 'Quarterly report', segmentId);
779
+ * }
780
+ * }
765
781
  * ```
766
782
  */
767
- deleteRange(range) {
768
- return this._replaceBodyRange(range, { dataStream: "" });
783
+ ensureHeader(variant = "default") {
784
+ return this._ensureHeaderFooter("header", variant);
769
785
  }
770
786
  /**
771
- * Remove a paragraph by paragraph id.
772
- * @param {FDocumentParagraph} paragraph The paragraph handle to remove.
773
- * @returns {boolean} `true` if the paragraph was removed.
787
+ * Ensures a footer segment linked specifically to this section.
774
788
  * @example
775
789
  * ```ts
776
790
  * const fDocument = univerAPI.getActiveDocument();
777
- * const fDocumentBody = fDocument.getBody();
778
- * const element = fDocumentBody.getElement(0);
779
- *
780
- * if (element?.isParagraph()) {
781
- * const paragraph = element.asParagraph();
782
- * const removed = fDocumentBody.removeParagraph(paragraph);
783
- * console.log(removed ? 'Paragraph removed' : 'Failed to remove paragraph');
791
+ * if (fDocument && !fDocument.isModern()) {
792
+ * const segmentId = fDocument.getSection(0)?.ensureFooter('first');
793
+ * if (segmentId) {
794
+ * fDocument.insertText(0, 'Confidential', segmentId);
795
+ * }
784
796
  * }
785
797
  * ```
786
798
  */
787
- removeParagraph(paragraph) {
788
- const { startOffset, endOffset } = paragraph.getResolvedParagraphInfo();
789
- return this.deleteRange({
790
- startOffset,
791
- endOffset: endOffset + 1
792
- });
799
+ ensureFooter(variant = "default") {
800
+ return this._ensureHeaderFooter("footer", variant);
793
801
  }
794
802
  /**
795
- * Remove a callout, quote, or code block range and its content.
796
- * @param {FDocumentBlockRange} blockRange The block range handle to remove.
797
- * @returns {boolean} `true` if the block range content was removed.
803
+ * Returns the effective header id after resolving links to previous sections.
798
804
  * @example
799
805
  * ```ts
800
806
  * const fDocument = univerAPI.getActiveDocument();
801
- * const fDocumentBody = fDocument.getBody();
802
- * const element = fDocumentBody.getElement(0);
803
- *
804
- * if (element?.isBlockRange()) {
805
- * const blockRange = element.asBlockRange();
806
- * const removed = fDocumentBody.removeBlockRange(blockRange);
807
- * console.log(removed ? 'Block range removed' : 'Failed to remove block range');
807
+ * console.log(fDocument?.getSection(0)?.getHeaderId('default'));
808
+ * ```
809
+ */
810
+ getHeaderId(variant = "default") {
811
+ var _this$_getHeaderFoote;
812
+ return (_this$_getHeaderFoote = this._getHeaderFooterReference("header", variant).segmentId) !== null && _this$_getHeaderFoote !== void 0 ? _this$_getHeaderFoote : null;
813
+ }
814
+ /**
815
+ * Returns the effective footer id after resolving links to previous sections.
816
+ * @example
817
+ * ```ts
818
+ * const fDocument = univerAPI.getActiveDocument();
819
+ * console.log(fDocument?.getSection(0)?.getFooterId('first'));
820
+ * ```
821
+ */
822
+ getFooterId(variant = "default") {
823
+ var _this$_getHeaderFoote2;
824
+ return (_this$_getHeaderFoote2 = this._getHeaderFooterReference("footer", variant).segmentId) !== null && _this$_getHeaderFoote2 !== void 0 ? _this$_getHeaderFoote2 : null;
825
+ }
826
+ /**
827
+ * Whether this header variant inherits the previous section's reference.
828
+ * @example
829
+ * ```ts
830
+ * const fDocument = univerAPI.getActiveDocument();
831
+ * console.log(fDocument?.getSection(1)?.isHeaderLinkedToPrevious());
832
+ * ```
833
+ */
834
+ isHeaderLinkedToPrevious(variant = "default") {
835
+ return this._getHeaderFooterReference("header", variant).linkedToPrevious;
836
+ }
837
+ /**
838
+ * Whether this footer variant inherits the previous section's reference.
839
+ * @example
840
+ * ```ts
841
+ * const fDocument = univerAPI.getActiveDocument();
842
+ * console.log(fDocument?.getSection(1)?.isFooterLinkedToPrevious('even'));
843
+ * ```
844
+ */
845
+ isFooterLinkedToPrevious(variant = "default") {
846
+ return this._getHeaderFooterReference("footer", variant).linkedToPrevious;
847
+ }
848
+ /**
849
+ * Links or unlinks this header variant. Unlinking clones the inherited header.
850
+ * @example
851
+ * ```ts
852
+ * const fDocument = univerAPI.getActiveDocument();
853
+ * if (fDocument && !fDocument.isModern()) {
854
+ * fDocument.getSection(1)?.setHeaderLinkedToPrevious(false, 'default');
808
855
  * }
809
856
  * ```
810
857
  */
811
- removeBlockRange(blockRange) {
812
- const { startIndex, endIndex } = blockRange.getBlockRange();
813
- return this.deleteRange({
814
- startOffset: startIndex,
815
- endOffset: endIndex + 1
816
- });
858
+ setHeaderLinkedToPrevious(linkedToPrevious, variant = "default") {
859
+ return this._setHeaderFooterLinkedToPrevious("header", variant, linkedToPrevious);
817
860
  }
818
861
  /**
819
- * Remove a table marker and its content range.
820
- * @returns {boolean} `true` if the table range was removed.
862
+ * Links or unlinks this footer variant. Unlinking clones the inherited footer.
821
863
  * @example
822
864
  * ```ts
823
865
  * const fDocument = univerAPI.getActiveDocument();
824
- * const fDocumentBody = fDocument.getBody();
825
- * const element = fDocumentBody.getElement(0);
826
- *
827
- * if (element?.isTable()) {
828
- * const table = element.asTable();
829
- * const removed = fDocumentBody.removeTable(table);
830
- * console.log(removed ? 'Table removed' : 'Failed to remove table');
866
+ * if (fDocument && !fDocument.isModern()) {
867
+ * fDocument.getSection(1)?.setFooterLinkedToPrevious(true, 'even');
831
868
  * }
832
869
  * ```
833
870
  */
834
- removeTable(table) {
835
- const { startIndex, endIndex } = table.getTable();
836
- return this.deleteRange({
837
- startOffset: startIndex,
838
- endOffset: endIndex + 1
839
- });
871
+ setFooterLinkedToPrevious(linkedToPrevious, variant = "default") {
872
+ return this._setHeaderFooterLinkedToPrevious("footer", variant, linkedToPrevious);
840
873
  }
841
874
  /**
842
- * Remove a custom block marker and its placeholder character.
843
- * @param {FDocumentCustomBlock} customBlock The custom block handle to remove.
844
- * @returns {boolean} `true` if the custom block placeholder was removed.
875
+ * Updates header/footer switches and margins on this section break.
876
+ * `marginHeader` and `marginFooter` are in points (pt).
845
877
  * @example
846
878
  * ```ts
847
879
  * const fDocument = univerAPI.getActiveDocument();
848
- * const fDocumentBody = fDocument.getBody();
849
- * const element = fDocumentBody.getElement(0);
850
- *
851
- * if (element?.isCustomBlock()) {
852
- * const customBlock = element.asCustomBlock();
853
- * const removed = fDocumentBody.removeCustomBlock(customBlock);
854
- * console.log(removed ? 'Custom block removed' : 'Failed to remove custom block');
880
+ * if (fDocument && !fDocument.isModern()) {
881
+ * fDocument.getSection(0)?.setHeaderFooterOptions({
882
+ * marginHeader: 36,
883
+ * marginFooter: 36,
884
+ * useFirstPageHeaderFooter: univerAPI.Enum.BooleanNumber.TRUE,
885
+ * });
855
886
  * }
856
887
  * ```
857
888
  */
858
- removeCustomBlock(customBlock) {
859
- const { startIndex } = customBlock.getCustomBlock();
860
- return this.deleteRange({
861
- startOffset: startIndex,
862
- endOffset: startIndex + 1
863
- });
889
+ setHeaderFooterOptions(options) {
890
+ this._assertTraditionalDocument();
891
+ return this._update(options);
864
892
  }
865
893
  /**
866
- * Resolve an element key to its current child metadata.
867
- * @param {FDocumentElement} element The element handle to resolve.
868
- * @returns {IFDocumentElementInfo} The current child metadata used by the facade.
894
+ * Deletes this section break. The final top-level section break cannot be removed.
869
895
  * @example
870
896
  * ```ts
871
897
  * const fDocument = univerAPI.getActiveDocument();
872
- * const fDocumentBody = fDocument.getBody();
873
- * const element = fDocumentBody.getElement(0);
874
- * const resolved = fDocumentBody.resolveElement(element);
875
- * console.log(resolved);
876
- * ```
877
- */
878
- resolveElement(element) {
879
- const { type, key } = element.getResolvedInfo();
880
- const child = this._getChildren().find((item) => item.type === type && item.key === key);
881
- if (!child) throw new Error("Doc element is stale");
882
- return child;
883
- }
884
- _getChildren() {
885
- const { paragraphs, blockRanges, tables, customBlocks } = this.getBody();
886
- const children = [];
887
- if (paragraphs) for (let i = 0; i < paragraphs.length; i++) {
888
- var _paragraphs2;
889
- const paragraph = paragraphs[i];
890
- const info = this._resolveParagraphInfo(paragraph, i, (_paragraphs2 = paragraphs[i - 1]) === null || _paragraphs2 === void 0 ? void 0 : _paragraphs2.startIndex);
891
- children.push(info);
892
- }
893
- if (blockRanges) for (let i = 0; i < blockRanges.length; i++) {
894
- const blockRange = blockRanges[i];
895
- children.push({
896
- type: _univerjs_core.DocumentBlockType.BLOCK_RANGE,
897
- key: blockRange.blockId,
898
- position: blockRange.startIndex,
899
- priority: 0
900
- });
901
- }
902
- if (tables) for (let i = 0; i < tables.length; i++) {
903
- const table = tables[i];
904
- children.push({
905
- type: _univerjs_core.DocumentBlockType.TABLE,
906
- key: table.tableId,
907
- position: table.startIndex,
908
- priority: 1
909
- });
910
- }
911
- if (customBlocks) for (let i = 0; i < customBlocks.length; i++) {
912
- const customBlock = customBlocks[i];
913
- children.push({
914
- type: _univerjs_core.DocumentBlockType.CUSTOM_BLOCK,
915
- key: customBlock.blockId,
916
- position: customBlock.startIndex,
917
- priority: 2
918
- });
919
- }
920
- return children.sort((a, b) => a.position - b.position || a.priority - b.priority);
898
+ * if (fDocument && !fDocument.isModern()) {
899
+ * const sections = fDocument.getSections();
900
+ * if (sections.length > 1) {
901
+ * sections[0].remove();
902
+ * }
903
+ * }
904
+ * ```
905
+ */
906
+ remove() {
907
+ this._assertTraditionalDocument();
908
+ return this._injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.DeleteDocumentSectionBreakCommand.id, {
909
+ unitId: this._document.getId(),
910
+ sectionId: this._sectionId
911
+ });
921
912
  }
922
- _resolveParagraphInfo(paragraph, paragraphIndex, previousParagraphStartIndex) {
913
+ _update(patch) {
914
+ const { sectionId: _sectionId, startIndex: _startIndex, ...config } = patch;
915
+ return this._injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.UpdateDocumentSectionCommand.id, {
916
+ unitId: this._document.getId(),
917
+ updates: [{
918
+ sectionId: this._sectionId,
919
+ config
920
+ }]
921
+ });
922
+ }
923
+ _ensureHeaderFooter(kind, variant) {
924
+ this._assertTraditionalDocument();
925
+ const { index } = this._resolve();
926
+ const existing = this.getConfig()[(0, _univerjs_core.getSectionHeaderFooterReferenceKey)(kind, variant)];
927
+ if (typeof existing === "string" && existing) return existing;
928
+ if (index > 0) {
929
+ const segmentId = (0, _univerjs_core.generateRandomId)(6);
930
+ if (!this._injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.SetSectionHeaderFooterLinkCommand.id, {
931
+ unitId: this._document.getId(),
932
+ sectionId: this._sectionId,
933
+ kind,
934
+ variant,
935
+ linkedToPrevious: false,
936
+ segmentId
937
+ })) throw new Error(`Failed to create section ${kind}.`);
938
+ return segmentId;
939
+ }
940
+ const types = {
941
+ default: kind === "header" ? _univerjs_docs.HeaderFooterType.DEFAULT_HEADER : _univerjs_docs.HeaderFooterType.DEFAULT_FOOTER,
942
+ first: kind === "header" ? _univerjs_docs.HeaderFooterType.FIRST_PAGE_HEADER : _univerjs_docs.HeaderFooterType.FIRST_PAGE_FOOTER,
943
+ even: kind === "header" ? _univerjs_docs.HeaderFooterType.EVEN_PAGE_HEADER : _univerjs_docs.HeaderFooterType.EVEN_PAGE_FOOTER
944
+ };
945
+ const segmentId = (0, _univerjs_core.generateRandomId)(6);
946
+ if (!this._injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.CreateHeaderFooterCommand.id, {
947
+ unitId: this._document.getId(),
948
+ segmentId,
949
+ createType: types[variant],
950
+ sectionId: this._sectionId
951
+ })) throw new Error(`Failed to create section ${kind}.`);
952
+ return segmentId;
953
+ }
954
+ _getHeaderFooterReference(kind, variant) {
955
+ const { index } = this._resolve();
956
+ return (0, _univerjs_core.resolveSectionHeaderFooterReference)(this._document.getDocumentDataModel().getSnapshot().documentStyle, (0, _univerjs_docs.getTopLevelSectionBreaks)(this._document.getBody()), index, (0, _univerjs_core.getSectionHeaderFooterReferenceKey)(kind, variant));
957
+ }
958
+ _describeHeaderFooterReference(kind, variant) {
959
+ var _reference$segmentId;
960
+ const reference = this._getHeaderFooterReference(kind, variant);
923
961
  return {
924
- type: _univerjs_core.DocumentBlockType.PARAGRAPH,
925
- key: this._getParagraphId(paragraph, paragraphIndex),
926
- position: paragraphIndex > 0 ? previousParagraphStartIndex + 1 : 0,
927
- priority: 3
962
+ segmentId: (_reference$segmentId = reference.segmentId) !== null && _reference$segmentId !== void 0 ? _reference$segmentId : null,
963
+ linkedToPrevious: reference.linkedToPrevious
928
964
  };
929
965
  }
930
- _getParagraphId(paragraph, paragraphIndex) {
931
- if (!paragraph) throw new Error(`Paragraph index ${paragraphIndex} is out of range.`);
932
- if (!paragraph.paragraphId) throw new Error(`Paragraph at index ${paragraphIndex} is missing paragraphId.`);
933
- return paragraph.paragraphId;
934
- }
935
- _getParagraphInsertOffset(index) {
936
- if (index <= 0) return 0;
937
- const { dataStream, paragraphs = [] } = this.getBody();
938
- if (paragraphs.length === 0) return Math.max(0, dataStream.length - 1);
939
- if (index >= paragraphs.length) return paragraphs[paragraphs.length - 1].startIndex + 1;
940
- return paragraphs[index - 1].startIndex + 1;
941
- }
942
- _replaceBodyRange(range, insertBody) {
943
- const { startOffset, endOffset } = range;
944
- const textX = new _univerjs_core.TextX();
945
- if (startOffset > 0) textX.push({
946
- t: _univerjs_core.TextXActionType.RETAIN,
947
- len: startOffset
948
- });
949
- if (endOffset > startOffset) textX.push({
950
- t: _univerjs_core.TextXActionType.DELETE,
951
- len: endOffset - startOffset
952
- });
953
- if (insertBody.dataStream.length > 0) textX.push({
954
- t: _univerjs_core.TextXActionType.INSERT,
955
- body: insertBody,
956
- len: insertBody.dataStream.length
957
- });
958
- return this._executeTextX(textX);
959
- }
960
- _retainBodyRange(range, body, coverType) {
961
- var _body$textRuns;
962
- if (((_body$textRuns = body.textRuns) === null || _body$textRuns === void 0 ? void 0 : _body$textRuns.length) && this.getBody().textRuns == null) this._ensureTextRuns();
963
- const textX = new _univerjs_core.TextX();
964
- if (range.startOffset > 0) textX.push({
965
- t: _univerjs_core.TextXActionType.RETAIN,
966
- len: range.startOffset
966
+ _setHeaderFooterLinkedToPrevious(kind, variant, linkedToPrevious) {
967
+ this._assertTraditionalDocument();
968
+ return this._injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.SetSectionHeaderFooterLinkCommand.id, {
969
+ unitId: this._document.getId(),
970
+ sectionId: this._sectionId,
971
+ kind,
972
+ variant,
973
+ linkedToPrevious,
974
+ ...linkedToPrevious ? {} : { segmentId: (0, _univerjs_core.generateRandomId)(6) }
967
975
  });
968
- textX.push({
969
- t: _univerjs_core.TextXActionType.RETAIN,
970
- body,
971
- coverType,
972
- len: range.endOffset - range.startOffset
973
- });
974
- return this._executeTextX(textX);
975
976
  }
976
- _ensureTextRuns() {
977
- const actions = _univerjs_core.JSONX.getInstance().replaceOp([...(0, _univerjs_core.getRichTextEditPath)(this._documentDataModel, this._segmentId), "textRuns"], void 0, []);
978
- this._injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.RichTextEditingMutation.id, {
979
- unitId: this._documentDataModel.getUnitId(),
980
- segmentId: this._segmentId,
981
- actions,
982
- textRanges: [],
983
- isEditing: false
984
- });
977
+ _assertTraditionalDocument() {
978
+ if (this._document.getDocumentDataModel().getSnapshot().documentStyle.documentFlavor !== _univerjs_core.DocumentFlavor.TRADITIONAL) throw new DocsSectionUnsupportedDocumentFlavorError();
985
979
  }
986
- _executeTextX(textX) {
987
- const actions = _univerjs_core.JSONX.getInstance().editOp(textX.serialize(), (0, _univerjs_core.getRichTextEditPath)(this._documentDataModel, this._segmentId));
988
- return this._injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.RichTextEditingMutation.id, {
989
- unitId: this._documentDataModel.getUnitId(),
990
- segmentId: this._segmentId,
991
- actions,
992
- textRanges: [],
993
- isEditing: false
994
- }) !== false;
980
+ _resolve() {
981
+ this._assertTraditionalDocument();
982
+ const sectionBreaks = (0, _univerjs_docs.getTopLevelSectionBreaks)(this._document.getBody());
983
+ const index = sectionBreaks.findIndex((section) => section.sectionId === this._sectionId);
984
+ if (index < 0) throw new Error(`Document section with id ${this._sectionId} not found.`);
985
+ return {
986
+ index,
987
+ sectionBreak: sectionBreaks[index]
988
+ };
995
989
  }
996
990
  };
997
991
 
992
+ //#endregion
993
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/typeof.js
994
+ function _typeof(o) {
995
+ "@babel/helpers - typeof";
996
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
997
+ return typeof o;
998
+ } : function(o) {
999
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
1000
+ }, _typeof(o);
1001
+ }
1002
+
1003
+ //#endregion
1004
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPrimitive.js
1005
+ function toPrimitive(t, r) {
1006
+ if ("object" != _typeof(t) || !t) return t;
1007
+ var e = t[Symbol.toPrimitive];
1008
+ if (void 0 !== e) {
1009
+ var i = e.call(t, r || "default");
1010
+ if ("object" != _typeof(i)) return i;
1011
+ throw new TypeError("@@toPrimitive must return a primitive value.");
1012
+ }
1013
+ return ("string" === r ? String : Number)(t);
1014
+ }
1015
+
1016
+ //#endregion
1017
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPropertyKey.js
1018
+ function toPropertyKey(t) {
1019
+ var i = toPrimitive(t, "string");
1020
+ return "symbol" == _typeof(i) ? i : i + "";
1021
+ }
1022
+
1023
+ //#endregion
1024
+ //#region \0@oxc-project+runtime@0.137.0/helpers/esm/defineProperty.js
1025
+ function _defineProperty(e, r, t) {
1026
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
1027
+ value: t,
1028
+ enumerable: !0,
1029
+ configurable: !0,
1030
+ writable: !0
1031
+ }) : e[r] = t, e;
1032
+ }
1033
+
998
1034
  //#endregion
999
1035
  //#region \0@oxc-project+runtime@0.137.0/helpers/esm/decorateParam.js
1000
1036
  function __decorateParam(paramIndex, decorator) {
@@ -1027,42 +1063,42 @@ let FDocument = class FDocument extends _univerjs_core_facade.FBaseInitialable {
1027
1063
  }
1028
1064
  /**
1029
1065
  * Get the document data model of the document.
1066
+ * @param {string} segmentId The segment id used to get the header/footer data model. Defaults to an empty string for the document data model of the document.
1030
1067
  * @returns {DocumentDataModel} The document data model.
1031
1068
  * @example
1032
1069
  * ```typescript
1033
1070
  * const fDocument = univerAPI.getActiveDocument();
1034
- * const documentDataModel = fDocument.getDocumentDataModel();
1035
- * console.log(documentDataModel);
1071
+ * console.log(fDocument.getDocumentDataModel());
1072
+ *
1073
+ * const headerSegmentId = fDocument.ensurePageHeader();
1074
+ * console.log(fDocument.getDocumentDataModel(headerSegmentId));
1036
1075
  * ```
1037
1076
  */
1038
- getDocumentDataModel() {
1039
- return this._documentDataModel;
1077
+ getDocumentDataModel(segmentId = "") {
1078
+ const documentDataModel = this._documentDataModel.getSelfOrHeaderFooterModel(segmentId);
1079
+ if (!documentDataModel) throw new Error(segmentId === "" ? "Document data model is not found." : `Document data model is not found in the segment: ${segmentId}`);
1080
+ return documentDataModel;
1040
1081
  }
1041
1082
  /**
1042
- * Get the document body facade.
1043
- *
1044
- * The returned body facade provides synchronous Google Docs-like element APIs
1045
- * for reading and editing top-level document body elements. Paragraph elements
1046
- * use their persisted `paragraphId` values. Persisted elements, such as tables
1047
- * and custom blocks, use their existing ids.
1048
- *
1049
- * @returns {FDocumentBody} The document body API instance.
1083
+ * Get the document body or header/footer body by the segment id.
1084
+ * The main body has an empty segment id.
1085
+ * The header and footer body have their respective segment ids.
1086
+ * @param {string} segmentId The segment id of the body. Defaults to an empty string for the main body.
1087
+ * @returns {IDocumentBody} The document body.
1050
1088
  * @example
1051
1089
  * ```typescript
1052
1090
  * const fDocument = univerAPI.getActiveDocument();
1053
- * const fDocumentBody = fDocument.getBody();
1054
- * console.log(fDocumentBody.getBody());
1091
+ * console.log(fDocument.getBody()); // Get the main body
1055
1092
  *
1056
- * const element = fDocumentBody.getElement(0);
1057
- * if (element.isParagraph()) {
1058
- * const paragraph = element.asParagraph();
1059
- * paragraph.appendText(' updated');
1060
- * console.log(paragraph.getText());
1061
- * }
1093
+ * const footerSegmentId = fDocument.ensurePageFooter();
1094
+ * console.log(fDocument.getBody(footerSegmentId)); // Get the footer body
1062
1095
  * ```
1063
1096
  */
1064
- getBody() {
1065
- return this._injector.createInstance(FDocumentBody, this._documentDataModel, this._injector);
1097
+ getBody(segmentId = "") {
1098
+ var _this$_documentDataMo;
1099
+ const body = (_this$_documentDataMo = this._documentDataModel.getSelfOrHeaderFooterModel(segmentId)) === null || _this$_documentDataMo === void 0 ? void 0 : _this$_documentDataMo.getBody();
1100
+ if (!body) throw new Error(segmentId === "" ? "Body is not found in the document." : `Body is not found in the segment: ${segmentId}`);
1101
+ return body;
1066
1102
  }
1067
1103
  dispose() {
1068
1104
  super.dispose();
@@ -1073,8 +1109,7 @@ let FDocument = class FDocument extends _univerjs_core_facade.FBaseInitialable {
1073
1109
  * @example
1074
1110
  * ```typescript
1075
1111
  * const fDocument = univerAPI.getActiveDocument();
1076
- * const unitId = fDocument.getId();
1077
- * console.log(unitId);
1112
+ * console.log(fDocument.getId());
1078
1113
  * ```
1079
1114
  */
1080
1115
  getId() {
@@ -1086,14 +1121,25 @@ let FDocument = class FDocument extends _univerjs_core_facade.FBaseInitialable {
1086
1121
  * @example
1087
1122
  * ```typescript
1088
1123
  * const fDocument = univerAPI.getActiveDocument();
1089
- * const name = fDocument.getName();
1090
- * console.log(name);
1124
+ * console.log(fDocument.getName());
1091
1125
  * ```
1092
1126
  */
1093
1127
  getName() {
1094
1128
  return this._documentDataModel.getTitle() || "";
1095
1129
  }
1096
1130
  /**
1131
+ * Whether the document is a modern document or not.
1132
+ * @returns {boolean} `true` if the document is a modern document, or `false` if it is not.
1133
+ * @example
1134
+ * ```typescript
1135
+ * const fDocument = univerAPI.getActiveDocument();
1136
+ * console.log(fDocument.isModern());
1137
+ * ```
1138
+ */
1139
+ isModern() {
1140
+ return this._documentDataModel.getSnapshot().documentStyle.documentFlavor === _univerjs_core.DocumentFlavor.MODERN;
1141
+ }
1142
+ /**
1097
1143
  * Save the document snapshot data, including the document content and resource data, etc.
1098
1144
  * @returns {IDocumentData} The document snapshot data.
1099
1145
  * @example
@@ -1134,275 +1180,517 @@ let FDocument = class FDocument extends _univerjs_core_facade.FBaseInitialable {
1134
1180
  this._univerInstanceService.focusUnit(this.id);
1135
1181
  return this._commandService.syncExecuteCommand(_univerjs_core.RedoCommand.id);
1136
1182
  }
1137
- };
1138
- FDocument = __decorate([
1139
- __decorateParam(1, (0, _univerjs_core.Inject)(_univerjs_core.Injector)),
1140
- __decorateParam(2, _univerjs_core.IUniverInstanceService),
1141
- __decorateParam(3, (0, _univerjs_core.Inject)(_univerjs_core.IResourceLoaderService)),
1142
- __decorateParam(4, _univerjs_core.ICommandService)
1143
- ], FDocument);
1144
-
1145
- //#endregion
1146
- //#region src/facade/f-univer.ts
1147
- var FUniverDocsMixin = class extends _univerjs_core_facade.FUniver {
1148
- createDocument(data) {
1149
- const document = this._injector.get(_univerjs_core.IUniverInstanceService).createUnit(_univerjs_core.UniverInstanceType.UNIVER_DOC, data);
1150
- return this._injector.createInstance(FDocument, document);
1183
+ /**
1184
+ * Ensure the page header segment exists and return its segment id.
1185
+ * @param {number} pageIndex The zero-based page index. Defaults to the first page.
1186
+ * @returns {string} The header segment id.
1187
+ * @example
1188
+ * ```ts
1189
+ * const fDocument = univerAPI.getActiveDocument();
1190
+ * const headerSegmentId = fDocument.ensurePageHeader();
1191
+ * fDocument.insertText(0, 'Header text', headerSegmentId);
1192
+ * ```
1193
+ */
1194
+ ensurePageHeader(pageIndex = 0) {
1195
+ return this._ensureHeaderFooter("header", pageIndex);
1151
1196
  }
1152
- getActiveDocument() {
1153
- const document = this._univerInstanceService.getCurrentUnitOfType(_univerjs_core.UniverInstanceType.UNIVER_DOC);
1154
- if (!document) return null;
1155
- return this._injector.createInstance(FDocument, document);
1197
+ /**
1198
+ * Ensure the page footer segment exists and return its segment id.
1199
+ * @param {number} pageIndex The zero-based page index. Defaults to the first page.
1200
+ * @returns {string} The footer segment id.
1201
+ * @example
1202
+ * ```ts
1203
+ * const fDocument = univerAPI.getActiveDocument();
1204
+ * const footerSegmentId = fDocument.ensurePageFooter();
1205
+ * fDocument.insertText(0, 'Footer text', footerSegmentId);
1206
+ * ```
1207
+ */
1208
+ ensurePageFooter(pageIndex = 0) {
1209
+ return this._ensureHeaderFooter("footer", pageIndex);
1156
1210
  }
1157
- getDocument(id) {
1158
- const document = this._univerInstanceService.getUnit(id, _univerjs_core.UniverInstanceType.UNIVER_DOC);
1159
- if (!document) return null;
1160
- return this._injector.createInstance(FDocument, document);
1211
+ /**
1212
+ * Insert plain text at a document body offset.
1213
+ * @param {number} index The zero-based insertion offset.
1214
+ * @param {string} text The plain text to insert.
1215
+ * @param {string} segmentId The segment id of the body. Defaults to an empty string for the main body.
1216
+ * @returns {boolean} `true` if the edit was applied.
1217
+ * @example
1218
+ * ```ts
1219
+ * const fDocument = univerAPI.getActiveDocument();
1220
+ * fDocument.insertText(0, 'Hello ');
1221
+ *
1222
+ * const headerSegmentId = fDocument.ensurePageHeader();
1223
+ * fDocument.insertText(0, 'Header text', headerSegmentId);
1224
+ * ```
1225
+ */
1226
+ insertText(index, text, segmentId = "") {
1227
+ return replaceBodyRange({
1228
+ startOffset: index,
1229
+ endOffset: index,
1230
+ segmentId
1231
+ }, buildPlainTextInsertBody(text), this._documentDataModel, this._injector);
1161
1232
  }
1162
- };
1163
- _univerjs_core_facade.FUniver.extend(FUniverDocsMixin);
1164
-
1165
- //#endregion
1166
- //#region src/facade/f-document-block-range.ts
1167
- /**
1168
- * A facade wrapper for document block ranges, such as callout, quote, and code blocks.
1169
- *
1170
- * Block range identity is backed by the persisted `IDocumentBlockRange.blockId`,
1171
- * so wrappers can be re-resolved after text is inserted before the block range.
1172
- *
1173
- * @hideconstructor
1174
- */
1175
- var FDocumentBlockRange = class extends FDocumentElement {
1176
- constructor(body, bodyEdit, info, injector) {
1177
- super(body, bodyEdit, info, injector);
1178
- this.body = body;
1179
- this.bodyEdit = bodyEdit;
1180
- this.info = info;
1181
- this.injector = injector;
1182
- if (this.getType() !== _univerjs_core.DocumentBlockType.BLOCK_RANGE) throw new Error(`Element type is not a block range: ${this.getType()}`);
1233
+ /**
1234
+ * Returns document-level header/footer switches and margins. Margin values are in points (pt).
1235
+ * @example
1236
+ * ```ts
1237
+ * const fDocument = univerAPI.getActiveDocument();
1238
+ * console.log(fDocument?.getHeaderFooterOptions());
1239
+ * ```
1240
+ */
1241
+ getHeaderFooterOptions() {
1242
+ const style = this._documentDataModel.getSnapshot().documentStyle;
1243
+ return {
1244
+ marginHeader: style.marginHeader,
1245
+ marginFooter: style.marginFooter,
1246
+ useFirstPageHeaderFooter: style.useFirstPageHeaderFooter,
1247
+ evenAndOddHeaders: style.evenAndOddHeaders
1248
+ };
1183
1249
  }
1184
1250
  /**
1185
- * Get the top-level block range data model.
1186
- * @returns {IDocumentBlockRange} The block range data model.
1251
+ * Updates document-level header/footer switches and margins in a traditional document.
1252
+ * `marginHeader` and `marginFooter` are in points (pt).
1187
1253
  * @example
1188
1254
  * ```ts
1189
1255
  * const fDocument = univerAPI.getActiveDocument();
1190
- * const fDocumentBody = fDocument.getBody();
1191
- * const element = fDocumentBody.getElement(0);
1192
- *
1193
- * if (element?.isBlockRange()) {
1194
- * const blockRange = element.asBlockRange();
1195
- * console.log(blockRange.getBlockRange());
1256
+ * if (fDocument && !fDocument.isModern()) {
1257
+ * fDocument.setHeaderFooterOptions({ marginHeader: 36, marginFooter: 36 });
1196
1258
  * }
1197
1259
  * ```
1198
1260
  */
1199
- getBlockRange() {
1200
- const { blockRanges = [] } = this._body.getBody();
1201
- const blockRange = blockRanges.find((blockRange) => blockRange.blockId === this.getKey());
1202
- if (!blockRange) throw new Error(`Block range not found: ${this.getKey()}`);
1203
- return blockRange;
1261
+ setHeaderFooterOptions(options) {
1262
+ if (this.isModern()) throw new Error("The document is a modern document, header/footer is not supported.");
1263
+ return this._commandService.syncExecuteCommand(_univerjs_docs.CreateHeaderFooterCommand.id, {
1264
+ unitId: this.getId(),
1265
+ headerFooterProps: options
1266
+ });
1204
1267
  }
1205
1268
  /**
1206
- * Get the block range type.
1207
- * @returns {DocumentBlockRangeType} The block type, such as callout, quote, or code.
1269
+ * Creates a facade for reading and styling a document text range.
1270
+ * The end offset is exclusive, and offsets are scoped to the selected body segment.
1271
+ * @param {number} startOffset The inclusive start offset.
1272
+ * @param {number} endOffset The exclusive end offset.
1273
+ * @param {string} segmentId The header/footer segment id, or an empty string for the main body.
1274
+ * @returns {FDocumentTextRange} A fixed text-range facade.
1275
+ * @example
1276
+ * ```ts
1277
+ * const range = univerAPI.getActiveDocument()?.getTextRange(0, 5);
1278
+ * console.log(range?.describe());
1279
+ * range?.setTextStyle({ bl: 1 });
1280
+ * ```
1281
+ */
1282
+ getTextRange(startOffset, endOffset, segmentId = "") {
1283
+ return this._injector.createInstance(FDocumentTextRange, this, startOffset, endOffset, segmentId, this._injector);
1284
+ }
1285
+ /**
1286
+ * Returns traditional document sections backed by persisted SectionBreak ids.
1287
+ * Modern documents use ColumnGroup instead and return an empty array from this read API.
1208
1288
  * @example
1209
1289
  * ```ts
1210
1290
  * const fDocument = univerAPI.getActiveDocument();
1211
- * const fDocumentBody = fDocument.getBody();
1212
- * const element = fDocumentBody.getElement(0);
1213
- *
1214
- * if (element?.isBlockRange()) {
1215
- * const blockRange = element.asBlockRange();
1216
- * console.log(blockRange.getBlockType());
1217
- * }
1291
+ * const sections = fDocument?.getSections() ?? [];
1292
+ * console.log(sections.map((section) => section.describe()));
1218
1293
  * ```
1219
1294
  */
1220
- getBlockType() {
1221
- return this.getBlockRange().blockType;
1295
+ getSections() {
1296
+ if (this._documentDataModel.getSnapshot().documentStyle.documentFlavor !== _univerjs_core.DocumentFlavor.TRADITIONAL) return [];
1297
+ return (0, _univerjs_docs.getTopLevelSectionBreaks)(this.getBody()).map((sectionBreak) => this._injector.createInstance(FDocumentSection, this, sectionBreak.sectionId, this._injector));
1222
1298
  }
1223
1299
  /**
1224
- * Get the plain text inside this block range.
1225
- * @returns {string} The block range text.
1300
+ * Returns a traditional section by zero-based index, or `null` in modern documents.
1226
1301
  * @example
1227
1302
  * ```ts
1228
1303
  * const fDocument = univerAPI.getActiveDocument();
1229
- * const fDocumentBody = fDocument.getBody();
1230
- * const element = fDocumentBody.getElement(0);
1231
- *
1232
- * if (element?.isBlockRange()) {
1233
- * const blockRange = element.asBlockRange();
1234
- * console.log(blockRange.getText());
1304
+ * const firstSection = fDocument?.getSection(0);
1305
+ * console.log(firstSection?.describe());
1306
+ * ```
1307
+ */
1308
+ getSection(index) {
1309
+ var _this$getSections$ind;
1310
+ return (_this$getSections$ind = this.getSections()[index]) !== null && _this$getSections$ind !== void 0 ? _this$getSections$ind : null;
1311
+ }
1312
+ /**
1313
+ * Returns the traditional section containing a data-stream offset, or `null` in modern documents.
1314
+ * @example
1315
+ * ```ts
1316
+ * const fDocument = univerAPI.getActiveDocument();
1317
+ * const paragraph = fDocument?.findParagraphByText('Launch');
1318
+ * const offset = paragraph?.getInfo().startOffset;
1319
+ * const section = offset == null ? null : fDocument?.getSectionAt(offset);
1320
+ * console.log(section?.getId());
1321
+ * ```
1322
+ */
1323
+ getSectionAt(offset) {
1324
+ var _this$getSections$fin;
1325
+ return (_this$getSections$fin = this.getSections().find((section) => {
1326
+ const range = section.getRange();
1327
+ return offset >= range.startOffset && offset <= range.endOffset;
1328
+ })) !== null && _this$getSections$fin !== void 0 ? _this$getSections$fin : null;
1329
+ }
1330
+ /**
1331
+ * Inserts a traditional document section break and returns its stable facade.
1332
+ * Modern documents must use ColumnGroup and throw `DocsSectionUnsupportedDocumentFlavorError`.
1333
+ * Numeric layout values in `config` are in points (pt).
1334
+ * @example
1335
+ * ```ts
1336
+ * const fDocument = univerAPI.getActiveDocument();
1337
+ * if (fDocument && !fDocument.isModern()) {
1338
+ * const paragraph = fDocument.findParagraphByText('Appendix');
1339
+ * const offset = paragraph?.getInfo().startOffset;
1340
+ * const section = offset == null ? null : fDocument.insertSectionBreak(offset);
1341
+ * console.log(section?.getId());
1235
1342
  * }
1236
1343
  * ```
1237
1344
  */
1238
- getText() {
1239
- const { dataStream } = this._body.getBody();
1240
- const { startIndex, endIndex } = this.getBlockRange();
1241
- return dataStream.slice(startIndex, endIndex);
1345
+ insertSectionBreak(offset, config = {}) {
1346
+ var _this$getBody$section;
1347
+ if (this._documentDataModel.getSnapshot().documentStyle.documentFlavor !== _univerjs_core.DocumentFlavor.TRADITIONAL) throw new DocsSectionUnsupportedDocumentFlavorError();
1348
+ const sectionId = (0, _univerjs_core.createSectionId)(new Set(((_this$getBody$section = this.getBody().sectionBreaks) !== null && _this$getBody$section !== void 0 ? _this$getBody$section : []).map((section) => section.sectionId)));
1349
+ return this._commandService.syncExecuteCommand(_univerjs_docs.InsertDocumentSectionBreakCommand.id, {
1350
+ unitId: this.getId(),
1351
+ offset,
1352
+ sectionId,
1353
+ config
1354
+ }) ? this._injector.createInstance(FDocumentSection, this, sectionId, this._injector) : null;
1242
1355
  }
1243
1356
  /**
1244
- * Replace the plain text inside this block range.
1245
- * @param {string} text The replacement text.
1246
- * @returns {boolean} `true` if the block range text was replaced.
1357
+ * Inserts a column-break token in a traditional document.
1358
+ * Modern documents must use ColumnGroup and throw `DocsSectionUnsupportedDocumentFlavorError`.
1247
1359
  * @example
1248
1360
  * ```ts
1249
1361
  * const fDocument = univerAPI.getActiveDocument();
1250
- * const fDocumentBody = fDocument.getBody();
1251
- * const element = fDocumentBody.getElement(0);
1252
- *
1253
- * if (element?.isBlockRange()) {
1254
- * const blockRange = element.asBlockRange();
1255
- * blockRange.setText('Updated block text');
1256
- * console.log(blockRange.getText());
1362
+ * if (fDocument && !fDocument.isModern()) {
1363
+ * const paragraph = fDocument.findParagraphByText('Continue in next column');
1364
+ * const offset = paragraph?.getInfo().startOffset;
1365
+ * if (offset != null) {
1366
+ * fDocument.insertColumnBreak(offset);
1367
+ * }
1257
1368
  * }
1258
1369
  * ```
1259
1370
  */
1260
- setText(text) {
1261
- const blockRange = this.getBlockRange();
1262
- const { startIndex, endIndex } = blockRange;
1263
- const updateBody = buildPlainTextInsertBody(`${text}\r`);
1264
- updateBody.blockRanges = [{
1265
- ...blockRange,
1266
- startIndex: 0,
1267
- endIndex: text.length
1268
- }];
1269
- return this._bodyEdit.replaceRange({
1270
- startOffset: startIndex,
1271
- endOffset: endIndex + 1
1272
- }, updateBody);
1273
- }
1274
- /**
1275
- * Remove this block range wrapper from the body.
1276
- *
1277
- * This currently removes the block range and its content, matching
1278
- * `remove()`.
1279
- *
1280
- * @returns {boolean} `true` if the block range content was removed.
1371
+ insertColumnBreak(offset) {
1372
+ if (this._documentDataModel.getSnapshot().documentStyle.documentFlavor !== _univerjs_core.DocumentFlavor.TRADITIONAL) throw new DocsSectionUnsupportedDocumentFlavorError();
1373
+ return this.insertText(offset, _univerjs_core.DataStreamTreeTokenType.COLUMN_BREAK);
1374
+ }
1375
+ /**
1376
+ * Inserts a horizontal rule using the existing paragraph `borderBottom` mechanism.
1377
+ * The returned paragraph can be inspected or removed with normal paragraph APIs.
1378
+ * Border width and padding are in points (pt).
1379
+ * @example
1380
+ * ```ts
1381
+ * const fDocument = univerAPI.getActiveDocument();
1382
+ * const paragraph = fDocument?.findParagraphByText('Summary');
1383
+ * const offset = paragraph?.getInfo().startOffset;
1384
+ * const rule = offset == null ? null : fDocument?.insertHorizontalRule(offset);
1385
+ * console.log(rule?.getId());
1386
+ * ```
1387
+ */
1388
+ insertHorizontalRule(offset, border = {
1389
+ padding: 5,
1390
+ color: { rgb: "#CDD0D8" },
1391
+ width: 1,
1392
+ dashStyle: _univerjs_core.DashStyleType.SOLID
1393
+ }, segmentId = "") {
1394
+ var _body$paragraphs;
1395
+ const body = this.getBody(segmentId);
1396
+ const paragraphs = (0, _univerjs_docs.generateParagraphs)(_univerjs_core.DataStreamTreeTokenType.PARAGRAPH, void 0, border, (_body$paragraphs = body.paragraphs) === null || _body$paragraphs === void 0 ? void 0 : _body$paragraphs.map((paragraph) => paragraph.paragraphId));
1397
+ const paragraphId = paragraphs[0].paragraphId;
1398
+ return replaceBodyRange({
1399
+ startOffset: offset,
1400
+ endOffset: offset,
1401
+ segmentId
1402
+ }, {
1403
+ dataStream: _univerjs_core.DataStreamTreeTokenType.PARAGRAPH,
1404
+ paragraphs
1405
+ }, this._documentDataModel, this._injector) ? this.getParagraph(paragraphId, segmentId) : null;
1406
+ }
1407
+ /**
1408
+ * Get all paragraphs in the document body or header/footer body by the segment id.
1409
+ * @param {string} segmentId The segment id of the body. Defaults to an empty string for the main body.
1410
+ * @returns {FDocumentParagraph[]} An array of paragraph facade instances.
1281
1411
  * @example
1282
1412
  * ```ts
1283
1413
  * const fDocument = univerAPI.getActiveDocument();
1284
- * const fDocumentBody = fDocument.getBody();
1285
- * const element = fDocumentBody.getElement(0);
1414
+ * const paragraphs = fDocument.getParagraphs();
1415
+ * console.log(paragraphs);
1286
1416
  *
1287
- * if (element?.isBlockRange()) {
1288
- * const blockRange = element.asBlockRange();
1289
- * const removed = blockRange.unwrap();
1290
- * console.log(removed ? 'Block range removed' : 'Failed to remove block range');
1291
- * }
1417
+ * const headerSegmentId = fDocument.ensurePageHeader();
1418
+ * const headerParagraphs = fDocument.getParagraphs(headerSegmentId);
1419
+ * console.log(headerParagraphs);
1292
1420
  * ```
1293
1421
  */
1294
- unwrap() {
1295
- return this.remove();
1422
+ getParagraphs(segmentId = "") {
1423
+ const { paragraphs = [] } = this.getBody(segmentId);
1424
+ return paragraphs.map((paragraph) => this._createFDocumentParagraph(paragraph.paragraphId, segmentId));
1296
1425
  }
1297
- };
1298
- var FDocumentBlockRangeMixin = class extends FDocumentElement {
1299
- asBlockRange() {
1300
- if (this.getType() !== _univerjs_core.DocumentBlockType.BLOCK_RANGE) throw new Error(`Element type is not a block range: ${this.getType()}`);
1301
- return this._injector.createInstance(FDocumentBlockRange, this._body, this._bodyEdit, this.getResolvedInfo(), this._injector);
1426
+ /**
1427
+ * Get a paragraph by its paragraph id and segment id.
1428
+ * @param {string} paragraphId The paragraph id.
1429
+ * @param {string} segmentId The segment id of the body. Defaults to an empty string for the main body.
1430
+ * @returns {FDocumentParagraph | null} The paragraph facade instance, or `null` if the paragraph is not found.
1431
+ * @example
1432
+ * ```ts
1433
+ * const fDocument = univerAPI.getActiveDocument();
1434
+ * const paragraph = fDocument.getParagraph('paragraph-01');
1435
+ * console.log(paragraph);
1436
+ *
1437
+ * const headerSegmentId = fDocument.ensurePageHeader();
1438
+ * const headerParagraph = fDocument.getParagraph('header-paragraph-01', headerSegmentId);
1439
+ * console.log(headerParagraph);
1440
+ * ```
1441
+ */
1442
+ getParagraph(paragraphId, segmentId = "") {
1443
+ const { paragraphs = [] } = this.getBody(segmentId);
1444
+ if (!paragraphs.find((paragraph) => paragraph.paragraphId === paragraphId)) return null;
1445
+ return this._createFDocumentParagraph(paragraphId, segmentId);
1302
1446
  }
1303
- };
1304
- FDocumentElement.extend(FDocumentBlockRangeMixin);
1305
-
1306
- //#endregion
1307
- //#region src/facade/f-document-custom-block.ts
1308
- /**
1309
- * A facade wrapper for document top-level custom blocks.
1310
- * @hideconstructor
1311
- */
1312
- var FDocumentCustomBlock = class extends FDocumentElement {
1313
- constructor(body, bodyEdit, info, injector) {
1314
- super(body, bodyEdit, info, injector);
1315
- this.body = body;
1316
- this.bodyEdit = bodyEdit;
1317
- this.info = info;
1318
- this.injector = injector;
1319
- if (this.getType() !== _univerjs_core.DocumentBlockType.CUSTOM_BLOCK) throw new Error(`Element type is not a custom block: ${this.getType()}`);
1447
+ /**
1448
+ * Find a paragraph by its text content and segment id.
1449
+ * @param {string} text The text content to search for.
1450
+ * @param {string} segmentId The segment id of the body. Defaults to an empty string for the main body.
1451
+ * @returns {FDocumentParagraph | null} The paragraph facade instance, or `null` if the paragraph is not found.
1452
+ * @example
1453
+ * ```ts
1454
+ * const fDocument = univerAPI.getActiveDocument();
1455
+ * const paragraph = fDocument.findParagraphByText('Hello');
1456
+ * console.log(paragraph);
1457
+ *
1458
+ * const footerSegmentId = fDocument.ensurePageFooter();
1459
+ * const footerParagraph = fDocument.findParagraphByText('Page', footerSegmentId);
1460
+ * console.log(footerParagraph);
1461
+ * ```
1462
+ */
1463
+ findParagraphByText(text, segmentId = "") {
1464
+ return this.findParagraphs({
1465
+ text,
1466
+ segmentId
1467
+ })[0] || null;
1320
1468
  }
1321
1469
  /**
1322
- * Get the custom block marker.
1323
- * @returns {ICustomBlock} The custom block marker.
1470
+ * Find paragraphs by a query object, which can include text content, paragraph id, and segment id.
1471
+ * @param {string | IFDocumentParagraphQuery} query The query object or text content to search for.
1472
+ * @returns {FDocumentParagraph[]} An array of paragraph facade instances that match the query.
1324
1473
  * @example
1325
1474
  * ```ts
1326
1475
  * const fDocument = univerAPI.getActiveDocument();
1327
- * const fDocumentBody = fDocument.getBody();
1328
- * const element = fDocumentBody.getElement(0);
1476
+ * const paragraphsWithText = fDocument.findParagraphs('Hello');
1477
+ * console.log(paragraphsWithText);
1329
1478
  *
1330
- * if (element?.isCustomBlock()) {
1331
- * const customBlock = element.asCustomBlock();
1332
- * console.log(customBlock.getCustomBlock());
1333
- * }
1479
+ * const paragraphsWithId = fDocument.findParagraphs({ paragraphId: 'paragraph-01' });
1480
+ * console.log(paragraphsWithId);
1481
+ *
1482
+ * const headerSegmentId = fDocument.ensurePageHeader();
1483
+ * const paragraphsWithSegment = fDocument.findParagraphs({ segmentId: headerSegmentId });
1484
+ * console.log(paragraphsWithSegment);
1334
1485
  * ```
1335
1486
  */
1336
- getCustomBlock() {
1337
- const { customBlocks = [] } = this._body.getBody();
1338
- const block = customBlocks.find((item) => item.blockId === this.getKey());
1339
- if (!block) throw new Error("Doc custom block is stale");
1340
- return block;
1487
+ findParagraphs(query) {
1488
+ const { text, paragraphId, segmentId = "" } = typeof query === "string" ? { text: query } : query;
1489
+ return this.getParagraphs(segmentId).filter((paragraph) => {
1490
+ if (paragraphId && paragraph.getId() !== paragraphId) return false;
1491
+ if (text && !paragraph.getText().includes(text)) return false;
1492
+ return true;
1493
+ });
1341
1494
  }
1342
- };
1343
- var FDocumentCustomBlockMixin = class extends FDocumentElement {
1344
- asCustomBlock() {
1345
- if (this.getType() !== _univerjs_core.DocumentBlockType.CUSTOM_BLOCK) throw new Error(`Element type is not a custom block: ${this.getType()}`);
1346
- return this._injector.createInstance(FDocumentCustomBlock, this._body, this._bodyEdit, this.getResolvedInfo(), this._injector);
1495
+ /**
1496
+ * Insert a plain-text paragraph before the paragraph at the given paragraph index.
1497
+ * @param {number} index The zero-based paragraph insertion index.
1498
+ * @param {string} text The paragraph text. Defaults to an empty paragraph.
1499
+ * @param {string} segmentId The segment id of the body. Defaults to an empty string for the main body.
1500
+ * @returns {FDocumentParagraph} The inserted paragraph facade instance.
1501
+ * @example
1502
+ * ```ts
1503
+ * const fDocument = univerAPI.getActiveDocument();
1504
+ * const paragraph = fDocument.insertParagraph(0, 'Document title');
1505
+ * paragraph.appendText(' suffix');
1506
+ *
1507
+ * const headerSegmentId = fDocument.ensurePageHeader();
1508
+ * const headerParagraph = fDocument.insertParagraph(0, 'Header title', headerSegmentId);
1509
+ * headerParagraph.appendText(' suffix');
1510
+ * ```
1511
+ */
1512
+ insertParagraph(index, text = "", segmentId = "") {
1513
+ const offset = this._getParagraphInsertOffset(index, segmentId);
1514
+ if (!replaceBodyRange({
1515
+ startOffset: offset,
1516
+ endOffset: offset,
1517
+ segmentId
1518
+ }, buildPlainTextInsertBody(`${text}\r`), this._documentDataModel, this._injector)) throw new Error("Failed to insert paragraph.");
1519
+ const { paragraphs = [] } = this.getBody(segmentId);
1520
+ const paragraph = paragraphs[index];
1521
+ if (!paragraph) throw new Error("Failed to insert paragraph.");
1522
+ return this._createFDocumentParagraph(paragraph.paragraphId, segmentId);
1347
1523
  }
1348
- };
1349
- FDocumentElement.extend(FDocumentCustomBlockMixin);
1350
-
1351
- //#endregion
1352
- //#region src/facade/f-document-table.ts
1353
- /**
1354
- * A facade wrapper for document top-level tables.
1355
- * @hideconstructor
1356
- */
1357
- var FDocumentTable = class extends FDocumentElement {
1358
- constructor(body, bodyEdit, info, injector) {
1359
- super(body, bodyEdit, info, injector);
1360
- this.body = body;
1361
- this.bodyEdit = bodyEdit;
1362
- this.info = info;
1363
- this.injector = injector;
1364
- if (this.getType() !== _univerjs_core.DocumentBlockType.TABLE) throw new Error(`Element type is not a table: ${this.getType()}`);
1524
+ /**
1525
+ * Append a plain-text paragraph at the end of the body.
1526
+ * @param {string} text The paragraph text. Defaults to an empty paragraph.
1527
+ * @param {string} segmentId The segment id of the body. Defaults to an empty string for the main body.
1528
+ * @returns {FDocumentParagraph} The appended paragraph wrapper.
1529
+ * @example
1530
+ * ```ts
1531
+ * const fDocument = univerAPI.getActiveDocument();
1532
+ * const paragraph = fDocument.appendParagraph('Summary');
1533
+ * console.log(paragraph.getText());
1534
+ *
1535
+ * const footerSegmentId = fDocument.ensurePageFooter();
1536
+ * const footerParagraph = fDocument.appendParagraph('Confidential', footerSegmentId);
1537
+ * console.log(footerParagraph.getText());
1538
+ * ```
1539
+ */
1540
+ appendParagraph(text = "", segmentId = "") {
1541
+ const { paragraphs = [] } = this.getBody(segmentId);
1542
+ return this.insertParagraph(paragraphs.length, text, segmentId);
1365
1543
  }
1366
1544
  /**
1367
- * Get the table marker.
1368
- * @returns {ICustomTable} The table marker.
1545
+ * Delete a range from the body.
1546
+ * @param {IFDocumentTextRange} range The text range to delete.
1547
+ * @returns {boolean} `true` if the range was deleted.
1369
1548
  * @example
1370
1549
  * ```ts
1371
1550
  * const fDocument = univerAPI.getActiveDocument();
1372
- * const fDocumentBody = fDocument.getBody();
1373
- * const element = fDocumentBody.getElement(0);
1551
+ * fDocument.deleteRange({ startOffset: 0, endOffset: 5 });
1374
1552
  *
1375
- * if (element?.isTable()) {
1376
- * const table = element.asTable();
1377
- * console.log(table.getTable());
1378
- * }
1553
+ * const headerSegmentId = fDocument.ensurePageHeader();
1554
+ * fDocument.deleteRange({ startOffset: 0, endOffset: 5, segmentId: headerSegmentId });
1379
1555
  * ```
1380
1556
  */
1381
- getTable() {
1382
- const { tables = [] } = this._body.getBody();
1383
- const table = tables.find((item) => item.tableId === this.getKey());
1384
- if (!table) throw new Error("Doc table is stale");
1385
- return table;
1557
+ deleteRange(range) {
1558
+ const normalizedRange = this._normalizeDeleteRange(range);
1559
+ if (normalizedRange.startOffset >= normalizedRange.endOffset) return false;
1560
+ return replaceBodyRange(normalizedRange, { dataStream: "" }, this._documentDataModel, this._injector);
1561
+ }
1562
+ _createFDocumentParagraph(paragraphId, segmentId = "") {
1563
+ return this._injector.createInstance(FDocumentParagraph, this, paragraphId, segmentId, this._injector);
1564
+ }
1565
+ _normalizeDeleteRange(range) {
1566
+ const body = this.getBody(range.segmentId);
1567
+ const protectedEndOffset = body.dataStream.endsWith("\r\n") ? Math.max(0, body.dataStream.length - 2) : body.dataStream.length;
1568
+ const endOffset = Math.min(Math.max(range.endOffset, 0), protectedEndOffset);
1569
+ return {
1570
+ ...range,
1571
+ startOffset: Math.min(Math.max(range.startOffset, 0), endOffset),
1572
+ endOffset
1573
+ };
1574
+ }
1575
+ _getParagraphInsertOffset(index, segmentId = "") {
1576
+ if (index <= 0) return 0;
1577
+ const body = this.getBody(segmentId);
1578
+ const { dataStream, paragraphs = [] } = body;
1579
+ if (paragraphs.length === 0) return Math.max(0, dataStream.length - 1);
1580
+ if (index >= paragraphs.length) return paragraphs[paragraphs.length - 1].startIndex + 1;
1581
+ return (0, _univerjs_core.getParagraphContentStartOffset)(body, paragraphs[index]);
1582
+ }
1583
+ _ensureHeaderFooter(kind, pageIndex) {
1584
+ if (this.isModern()) throw new Error("The document is a modern document, header/footer is not supported.");
1585
+ const { createType, segmentId: existingSegmentId } = this._getHeaderFooterCreateInfo(kind, pageIndex);
1586
+ if (existingSegmentId) return existingSegmentId;
1587
+ const segmentId = (0, _univerjs_core.generateRandomId)(6);
1588
+ if (!this._commandService.syncExecuteCommand(_univerjs_docs.CreateHeaderFooterCommand.id, {
1589
+ unitId: this.getId(),
1590
+ segmentId,
1591
+ createType
1592
+ })) throw new Error(`Failed to create page ${kind}.`);
1593
+ return segmentId;
1594
+ }
1595
+ _getHeaderFooterCreateInfo(kind, pageIndex) {
1596
+ var _documentStyle$defaul, _documentStyle$defaul2;
1597
+ const { documentStyle } = this._documentDataModel.getSnapshot();
1598
+ const isFirstPage = pageIndex === 0;
1599
+ const isEvenPage = (pageIndex + 1) % 2 === 0;
1600
+ if (isFirstPage && documentStyle.useFirstPageHeaderFooter === _univerjs_core.BooleanNumber.TRUE) {
1601
+ var _documentStyle$firstP, _documentStyle$firstP2;
1602
+ return kind === "header" ? {
1603
+ createType: _univerjs_docs.HeaderFooterType.FIRST_PAGE_HEADER,
1604
+ segmentId: (_documentStyle$firstP = documentStyle.firstPageHeaderId) !== null && _documentStyle$firstP !== void 0 ? _documentStyle$firstP : ""
1605
+ } : {
1606
+ createType: _univerjs_docs.HeaderFooterType.FIRST_PAGE_FOOTER,
1607
+ segmentId: (_documentStyle$firstP2 = documentStyle.firstPageFooterId) !== null && _documentStyle$firstP2 !== void 0 ? _documentStyle$firstP2 : ""
1608
+ };
1609
+ }
1610
+ if (isEvenPage && documentStyle.evenAndOddHeaders === _univerjs_core.BooleanNumber.TRUE) {
1611
+ var _documentStyle$evenPa, _documentStyle$evenPa2;
1612
+ return kind === "header" ? {
1613
+ createType: _univerjs_docs.HeaderFooterType.EVEN_PAGE_HEADER,
1614
+ segmentId: (_documentStyle$evenPa = documentStyle.evenPageHeaderId) !== null && _documentStyle$evenPa !== void 0 ? _documentStyle$evenPa : ""
1615
+ } : {
1616
+ createType: _univerjs_docs.HeaderFooterType.EVEN_PAGE_FOOTER,
1617
+ segmentId: (_documentStyle$evenPa2 = documentStyle.evenPageFooterId) !== null && _documentStyle$evenPa2 !== void 0 ? _documentStyle$evenPa2 : ""
1618
+ };
1619
+ }
1620
+ return kind === "header" ? {
1621
+ createType: _univerjs_docs.HeaderFooterType.DEFAULT_HEADER,
1622
+ segmentId: (_documentStyle$defaul = documentStyle.defaultHeaderId) !== null && _documentStyle$defaul !== void 0 ? _documentStyle$defaul : ""
1623
+ } : {
1624
+ createType: _univerjs_docs.HeaderFooterType.DEFAULT_FOOTER,
1625
+ segmentId: (_documentStyle$defaul2 = documentStyle.defaultFooterId) !== null && _documentStyle$defaul2 !== void 0 ? _documentStyle$defaul2 : ""
1626
+ };
1627
+ }
1628
+ };
1629
+ FDocument = __decorate([
1630
+ __decorateParam(1, (0, _univerjs_core.Inject)(_univerjs_core.Injector)),
1631
+ __decorateParam(2, _univerjs_core.IUniverInstanceService),
1632
+ __decorateParam(3, (0, _univerjs_core.Inject)(_univerjs_core.IResourceLoaderService)),
1633
+ __decorateParam(4, _univerjs_core.ICommandService)
1634
+ ], FDocument);
1635
+
1636
+ //#endregion
1637
+ //#region src/facade/f-univer.ts
1638
+ var FUniverDocsMixin = class extends _univerjs_core_facade.FUniver {
1639
+ createDocument(data) {
1640
+ const document = this._injector.get(_univerjs_core.IUniverInstanceService).createUnit(_univerjs_core.UniverInstanceType.UNIVER_DOC, data);
1641
+ return this._injector.createInstance(FDocument, document);
1642
+ }
1643
+ getActiveDocument() {
1644
+ const document = this._univerInstanceService.getCurrentUnitOfType(_univerjs_core.UniverInstanceType.UNIVER_DOC);
1645
+ if (!document) return null;
1646
+ return this._injector.createInstance(FDocument, document);
1647
+ }
1648
+ getDocument(id) {
1649
+ const document = this._univerInstanceService.getUnit(id, _univerjs_core.UniverInstanceType.UNIVER_DOC);
1650
+ if (!document) return null;
1651
+ return this._injector.createInstance(FDocument, document);
1386
1652
  }
1387
1653
  };
1388
- var FDocumentTableMixin = class extends FDocumentElement {
1389
- asTable() {
1390
- if (this.getType() !== _univerjs_core.DocumentBlockType.TABLE) throw new Error(`Element type is not a table: ${this.getType()}`);
1391
- return this._injector.createInstance(FDocumentTable, this._body, this._bodyEdit, this.getResolvedInfo(), this._injector);
1654
+ _univerjs_core_facade.FUniver.extend(FUniverDocsMixin);
1655
+
1656
+ //#endregion
1657
+ //#region src/facade/f-enum.ts
1658
+ /**
1659
+ * Copyright 2023-present DreamNum Co., Ltd.
1660
+ *
1661
+ * Licensed under the Apache License, Version 2.0 (the "License");
1662
+ * you may not use this file except in compliance with the License.
1663
+ * You may obtain a copy of the License at
1664
+ *
1665
+ * http://www.apache.org/licenses/LICENSE-2.0
1666
+ *
1667
+ * Unless required by applicable law or agreed to in writing, software
1668
+ * distributed under the License is distributed on an "AS IS" BASIS,
1669
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1670
+ * See the License for the specific language governing permissions and
1671
+ * limitations under the License.
1672
+ */
1673
+ var FDocsEnumMixin = class extends _univerjs_core_facade.FEnum {
1674
+ get SectionType() {
1675
+ return _univerjs_core.SectionType;
1676
+ }
1677
+ get ColumnSeparatorType() {
1678
+ return _univerjs_core.ColumnSeparatorType;
1392
1679
  }
1393
1680
  };
1394
- FDocumentElement.extend(FDocumentTableMixin);
1681
+ _univerjs_core_facade.FEnum.extend(FDocsEnumMixin);
1395
1682
 
1396
1683
  //#endregion
1684
+ exports.DocsSectionUnsupportedDocumentFlavorError = DocsSectionUnsupportedDocumentFlavorError;
1685
+ exports.FDocsEnumMixin = FDocsEnumMixin;
1397
1686
  Object.defineProperty(exports, 'FDocument', {
1398
1687
  enumerable: true,
1399
1688
  get: function () {
1400
1689
  return FDocument;
1401
1690
  }
1402
1691
  });
1403
- exports.FDocumentBlockRange = FDocumentBlockRange;
1404
- exports.FDocumentBody = FDocumentBody;
1405
- exports.FDocumentCustomBlock = FDocumentCustomBlock;
1406
- exports.FDocumentElement = FDocumentElement;
1407
1692
  exports.FDocumentParagraph = FDocumentParagraph;
1408
- exports.FDocumentTable = FDocumentTable;
1693
+ exports.FDocumentSection = FDocumentSection;
1694
+ exports.FDocumentTextRange = FDocumentTextRange;
1695
+ exports.isParagraphFacade = isParagraphFacade;
1696
+ exports.stripBlockTokens = stripBlockTokens;