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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/cjs/facade.js CHANGED
@@ -107,8 +107,9 @@ function stripBlockTokens(text) {
107
107
  * that insert or remove content before it.
108
108
  * @hideconstructor
109
109
  */
110
- var FDocumentTextRange = class {
110
+ var FDocumentTextRange = class extends _univerjs_core_facade.FBaseInitialable {
111
111
  constructor(_document, _startOffset, _endOffset, _segmentId, _injector) {
112
+ super(_injector);
112
113
  this._document = _document;
113
114
  this._startOffset = _startOffset;
114
115
  this._endOffset = _endOffset;
@@ -165,10 +166,6 @@ var FDocumentTextRange = class {
165
166
  };
166
167
  });
167
168
  }
168
- /** @deprecated Use `getExplicitTextStyleRuns()` to distinguish stored styles from effective styles. */
169
- getTextStyleRuns() {
170
- return this.getExplicitTextStyleRuns();
171
- }
172
169
  /**
173
170
  * Returns top-level style properties that have the same explicit value
174
171
  * across the complete range. Unstyled gaps make a property non-common.
@@ -186,10 +183,6 @@ var FDocumentTextRange = class {
186
183
  for (const key of Object.keys(common)) if (rest.some((run) => !isDeepEqual(run.textStyle[key], common[key]))) delete common[key];
187
184
  return common;
188
185
  }
189
- /** @deprecated Use `getCommonExplicitTextStyle()` to distinguish stored styles from effective styles. */
190
- getCommonTextStyle() {
191
- return this.getCommonExplicitTextStyle();
192
- }
193
186
  /**
194
187
  * Returns a serializable summary suitable for an agent/tool response.
195
188
  * @example
@@ -207,9 +200,7 @@ var FDocumentTextRange = class {
207
200
  text: this.getText(),
208
201
  length: this._endOffset - this._startOffset,
209
202
  explicitTextStyleRuns,
210
- commonExplicitTextStyle,
211
- textStyleRuns: explicitTextStyleRuns,
212
- commonTextStyle: commonExplicitTextStyle
203
+ commonExplicitTextStyle
213
204
  };
214
205
  }
215
206
  /**
@@ -276,23 +267,33 @@ function isDeepEqual(left, right) {
276
267
  return JSON.stringify(left) === JSON.stringify(right);
277
268
  }
278
269
 
270
+ //#endregion
271
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/decorateParam.js
272
+ function __decorateParam(paramIndex, decorator) {
273
+ return function(target, key) {
274
+ decorator(target, key, paramIndex);
275
+ };
276
+ }
277
+
278
+ //#endregion
279
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/decorate.js
280
+ function __decorate(decorators, target, key, desc) {
281
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
282
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
283
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
284
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
285
+ }
286
+
279
287
  //#endregion
280
288
  //#region src/facade/f-document-paragraph.ts
281
- /**
282
- * A paragraph facade wrapper.
283
- *
284
- * Paragraph identity is backed by the persisted `paragraphId`. The id is
285
- * re-resolved before each method call, so insertions before this paragraph do
286
- * not break the wrapper.
287
- *
288
- * @hideconstructor
289
- */
290
- var FDocumentParagraph = class {
291
- constructor(_document, _paragraphId, _segmentId = "", _injector) {
289
+ let FDocumentParagraph = class FDocumentParagraph extends _univerjs_core_facade.FBaseInitialable {
290
+ constructor(_document, _paragraphId, _segmentId = "", _injector, _commandService) {
291
+ super(_injector);
292
292
  this._document = _document;
293
293
  this._paragraphId = _paragraphId;
294
294
  this._segmentId = _segmentId;
295
295
  this._injector = _injector;
296
+ this._commandService = _commandService;
296
297
  }
297
298
  /**
298
299
  * Get the persisted paragraph id.
@@ -383,6 +384,73 @@ var FDocumentParagraph = class {
383
384
  return this._injector.createInstance(FDocumentTextRange, this._document, startOffset, endOffset, this._segmentId, this._injector);
384
385
  }
385
386
  /**
387
+ * Finds one literal text occurrence inside this paragraph.
388
+ *
389
+ * The returned text range is fixed when it is created. Resolve a new range
390
+ * after edits that insert or remove content before the match.
391
+ *
392
+ * @param {string} text Literal text to find. It must not be empty.
393
+ * @param {IFDocumentFindTextOptions} [options] Case sensitivity and zero-based occurrence.
394
+ * @returns {FDocumentTextRange | null} The matching fixed text range, or `null` when no such occurrence exists.
395
+ * @example
396
+ * ```ts
397
+ * const univerAPI = FUniver.newAPI(univer);
398
+ * const document = univerAPI.getActiveDocument();
399
+ * if (!document) throw new Error('No active document');
400
+ *
401
+ * const paragraph = document.findParagraphByText('Launch formula');
402
+ * if (!paragraph) throw new Error('Target paragraph not found');
403
+ *
404
+ * const range = paragraph.findText('formula');
405
+ * if (!range) throw new Error('Target text not found');
406
+ *
407
+ * console.log(range.describe());
408
+ * ```
409
+ */
410
+ findText(text, options = {}) {
411
+ var _options$occurrence, _this$findAllText$occ;
412
+ const occurrence = (_options$occurrence = options.occurrence) !== null && _options$occurrence !== void 0 ? _options$occurrence : 0;
413
+ if (!Number.isInteger(occurrence) || occurrence < 0) throw new RangeError("Text occurrence must be a non-negative integer.");
414
+ return (_this$findAllText$occ = this.findAllText(text, options)[occurrence]) !== null && _this$findAllText$occ !== void 0 ? _this$findAllText$occ : null;
415
+ }
416
+ /**
417
+ * Finds every non-overlapping literal text occurrence inside this paragraph.
418
+ *
419
+ * Results are ordered from the start of the paragraph. The returned ranges
420
+ * are fixed when created; use them immediately and resolve new ranges after
421
+ * edits that change earlier document content.
422
+ *
423
+ * @param {string} text Literal text to find. It must not be empty.
424
+ * @param {Omit<IFDocumentFindTextOptions, 'occurrence'>} [options] Case-sensitivity option.
425
+ * @returns {FDocumentTextRange[]} All matching fixed text ranges, or an empty array when no matches exist.
426
+ * @example
427
+ * ```ts
428
+ * const univerAPI = FUniver.newAPI(univer);
429
+ * const document = univerAPI.getActiveDocument();
430
+ * if (!document) throw new Error('No active document');
431
+ *
432
+ * const paragraph = document.findParagraphByText('x plus x');
433
+ * if (!paragraph) throw new Error('Target paragraph not found');
434
+ *
435
+ * const matches = paragraph.findAllText('x');
436
+ * console.log(matches.map((range) => range.describe()));
437
+ * ```
438
+ */
439
+ findAllText(text, options = {}) {
440
+ var _options$matchCase;
441
+ if (text.length === 0) throw new TypeError("Text to find must not be empty.");
442
+ const matchCase = (_options$matchCase = options.matchCase) !== null && _options$matchCase !== void 0 ? _options$matchCase : true;
443
+ const paragraphText = this.getText();
444
+ const matcher = _univerjs_core.regexp.createLiteralRegExp(text, matchCase ? "gu" : "giu");
445
+ const { startOffset } = this.getInfo();
446
+ const matches = [];
447
+ for (const match of paragraphText.matchAll(matcher)) {
448
+ const matchStartOffset = startOffset + match.index;
449
+ matches.push(this._injector.createInstance(FDocumentTextRange, this._document, matchStartOffset, matchStartOffset + match[0].length, this._segmentId, this._injector));
450
+ }
451
+ return matches;
452
+ }
453
+ /**
386
454
  * Get this paragraph's plain text.
387
455
  * @returns {string} The paragraph text without the trailing paragraph break.
388
456
  * @example
@@ -434,59 +502,65 @@ var FDocumentParagraph = class {
434
502
  return this._document.insertText(endOffset, text, this._segmentId);
435
503
  }
436
504
  /**
437
- * Apply paragraph style to a paragraph handle or text range.
505
+ * Applies a paragraph and optional text-style patch through one document command.
506
+ *
507
+ * Pagination values use `BooleanNumber.TRUE` or `BooleanNumber.FALSE`; explicit
508
+ * false is preserved and overrides inherited true. The paragraph and text-style
509
+ * changes share one undo/redo item. A stale paragraph handle returns `false`
510
+ * without applying a partial update.
511
+ *
512
+ * The Traditional renderer applies these Word-compatible pagination rules:
513
+ * use `pageBreakBefore` for a hard chapter-page boundary, `keepLines` for a
514
+ * short paragraph that should stay intact, `keepNext` for a heading or caption
515
+ * that should accompany the next paragraph, and `widowControl` for natural
516
+ * multi-line body text. Do not enable every rule on every paragraph. Modern
517
+ * and Unspecified Docs preserve the values in the model but do not apply them
518
+ * to physical pages.
519
+ *
438
520
  * `style.textStyle.fs` is a font size in points (pt), not CSS pixels.
439
521
  * @param {IParagraphStyle} style The Univer paragraph style patch.
440
- * @returns {boolean} `true` if the style was applied.
522
+ * @returns {boolean} `true` when the complete patch was applied; otherwise `false`.
441
523
  * @example
442
524
  * ```ts
443
- * const fDocument = univerAPI.getActiveDocument();
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,
525
+ * const document = univerAPI.getActiveDocument();
526
+ * if (!document) {
527
+ * throw new Error('No active document');
528
+ * }
529
+ * if (!document.isTraditional()) {
530
+ * throw new Error('Traditional document pagination is required');
531
+ * }
532
+ * const heading = document.findParagraphByText('Appendix');
533
+ * const following = document.findParagraphByText('Supporting details');
534
+ * if (!heading || !following) {
535
+ * throw new Error('Expected paragraphs were not found');
536
+ * }
537
+ *
538
+ * const headingUpdated = heading.setStyle({
539
+ * pageBreakBefore: univerAPI.Enum.BooleanNumber.TRUE,
540
+ * keepLines: univerAPI.Enum.BooleanNumber.TRUE,
541
+ * keepNext: univerAPI.Enum.BooleanNumber.TRUE,
454
542
  * });
455
- * console.log(paragraph?.getInfo().paragraph.paragraphStyle);
543
+ * const followingUpdated = following.setStyle({
544
+ * // Explicit FALSE terminates this authored keepNext chain even if a named
545
+ * // style or document default enables it.
546
+ * keepNext: univerAPI.Enum.BooleanNumber.FALSE,
547
+ * widowControl: univerAPI.Enum.BooleanNumber.TRUE,
548
+ * });
549
+ * if (!headingUpdated || !followingUpdated) {
550
+ * throw new Error('Failed to update paragraph pagination');
551
+ * }
456
552
  * ```
457
553
  */
458
554
  setStyle(style) {
459
- const { paragraph, startOffset, endOffset } = this.getInfo();
460
- let result = true;
461
- if (style.textStyle && startOffset < endOffset) result = retainBodyRange({
555
+ const { startOffset, endOffset } = this.getInfo();
556
+ return this._commandService.syncExecuteCommand(_univerjs_docs.UpdateDocumentParagraphStyleCommand.id, {
557
+ unitId: this._document.getId(),
558
+ segmentId: this._segmentId,
559
+ paragraphId: this._paragraphId,
462
560
  startOffset,
463
561
  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);
473
- const updateBody = {
474
- dataStream: "",
475
- paragraphs: [{
476
- ...paragraph,
477
- startIndex: 0,
478
- paragraphStyle: {
479
- ...paragraph.paragraphStyle,
480
- ...style
481
- }
482
- }]
483
- };
484
- this._preserveExplicitParagraphIds(updateBody);
485
- return retainBodyRange({
486
- startOffset: endOffset,
487
- endOffset: endOffset + 1,
488
- segmentId: this._segmentId
489
- }, updateBody, _univerjs_core.UpdateDocsAttributeType.REPLACE, this._document.getDocumentDataModel(), this._injector) && result;
562
+ style
563
+ });
490
564
  }
491
565
  /**
492
566
  * Check whether this paragraph is a bullet, ordered, or checklist item.
@@ -578,6 +652,7 @@ var FDocumentParagraph = class {
578
652
  body[_univerjs_core.RESTORE_INSERTED_PARAGRAPH_IDS] = true;
579
653
  }
580
654
  };
655
+ FDocumentParagraph = __decorate([__decorateParam(4, _univerjs_core.ICommandService)], FDocumentParagraph);
581
656
  function isParagraphFacade(value) {
582
657
  if (typeof value !== "object" || value === null) return false;
583
658
  return typeof value.getId === "function" && typeof value.getSegmentId === "function" && typeof value.getInfo === "function" && typeof value.getRange === "function";
@@ -585,29 +660,30 @@ function isParagraphFacade(value) {
585
660
 
586
661
  //#endregion
587
662
  //#region src/facade/f-document-section.ts
588
- /** Error thrown when traditional section APIs are used to mutate a modern document. */
663
+ function validatePageSetup(pageSetup) {
664
+ const { pageNumberStart, pageSize, pageOrient, marginTop, marginBottom, marginLeft, marginRight } = pageSetup;
665
+ if (pageNumberStart != null && (!Number.isInteger(pageNumberStart) || pageNumberStart < 1)) throw new RangeError("Section page number start must be a positive integer.");
666
+ if (pageSize && [pageSize.width, pageSize.height].some((size) => size != null && (!Number.isFinite(size) || size <= 0))) throw new RangeError("Section page size must be finite and positive.");
667
+ if (pageOrient != null && !Object.values(_univerjs_core.PageOrientType).includes(pageOrient)) throw new RangeError("Invalid section page orientation.");
668
+ if ([
669
+ marginTop,
670
+ marginBottom,
671
+ marginLeft,
672
+ marginRight
673
+ ].some((margin) => margin != null && (!Number.isFinite(margin) || margin < 0))) throw new RangeError("Section page margins must be finite and non-negative.");
674
+ }
675
+ /** Error thrown when a Traditional-only section API is used with another document flavor. */
589
676
  var DocsSectionUnsupportedDocumentFlavorError = class extends Error {
590
677
  constructor() {
591
- super("Section column APIs are supported only in traditional documents. Use ColumnGroup APIs for modern documents.");
678
+ super("Section column APIs are supported only in traditional documents. Use ColumnGroup APIs for modern documents, or resolve an unspecified document flavor first.");
592
679
  this.name = "DocsSectionUnsupportedDocumentFlavorError";
593
680
  }
594
681
  };
595
- /**
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
- * ```
605
- */
606
- var FDocumentSection = class {
607
- constructor(_document, _sectionId, _injector) {
682
+ let FDocumentSection = class FDocumentSection {
683
+ constructor(_document, _sectionId, _commandService) {
608
684
  this._document = _document;
609
685
  this._sectionId = _sectionId;
610
- this._injector = _injector;
686
+ this._commandService = _commandService;
611
687
  }
612
688
  /**
613
689
  * Returns the persisted section id.
@@ -640,8 +716,7 @@ var FDocumentSection = class {
640
716
  * ```
641
717
  */
642
718
  getConfig() {
643
- const { sectionBreak } = this._resolve();
644
- return _univerjs_core.Tools.deepClone(sectionBreak);
719
+ return this._getConfigSnapshot();
645
720
  }
646
721
  /**
647
722
  * Returns the section content range, excluding its terminating section-break token.
@@ -652,17 +727,11 @@ var FDocumentSection = class {
652
727
  * ```
653
728
  */
654
729
  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
- };
730
+ return this._getRange(this._resolve().index);
662
731
  }
663
732
  /**
664
733
  * Returns the explicit columns. An empty array means the normal single-column layout.
665
- * Column widths and trailing spaces are in points (pt).
734
+ * Column widths and trailing spaces are in 96-DPI layout pixels.
666
735
  * @example
667
736
  * ```ts
668
737
  * const fDocument = univerAPI.getActiveDocument();
@@ -670,8 +739,8 @@ var FDocumentSection = class {
670
739
  * ```
671
740
  */
672
741
  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 : []);
742
+ var _this$_getConfigSnaps;
743
+ return _univerjs_core.Tools.deepClone((_this$_getConfigSnaps = this._getConfigSnapshot().columnProperties) !== null && _this$_getConfigSnaps !== void 0 ? _this$_getConfigSnaps : []);
675
744
  }
676
745
  /**
677
746
  * Returns a compact serializable section summary.
@@ -683,7 +752,8 @@ var FDocumentSection = class {
683
752
  */
684
753
  describe() {
685
754
  var _config$columnPropert, _config$columnSeparat, _config$sectionType;
686
- const config = this.getConfig();
755
+ const { index } = this._resolve();
756
+ const config = this._getConfigSnapshot();
687
757
  const columns = (_config$columnPropert = config.columnProperties) !== null && _config$columnPropert !== void 0 ? _config$columnPropert : [];
688
758
  const headerFooter = {
689
759
  defaultHeader: this._describeHeaderFooterReference("header", "default"),
@@ -695,8 +765,8 @@ var FDocumentSection = class {
695
765
  };
696
766
  return {
697
767
  sectionId: this._sectionId,
698
- index: this.getIndex(),
699
- range: this.getRange(),
768
+ index,
769
+ range: this._getRange(index),
700
770
  columnCount: columns.length || 1,
701
771
  columns: _univerjs_core.Tools.deepClone(columns),
702
772
  columnSeparatorType: (_config$columnSeparat = config.columnSeparatorType) !== null && _config$columnSeparat !== void 0 ? _config$columnSeparat : _univerjs_core.ColumnSeparatorType.NONE,
@@ -708,11 +778,11 @@ var FDocumentSection = class {
708
778
  /**
709
779
  * Sets equal or explicitly sized columns for this traditional section.
710
780
  * Use `columnCount = 1` to restore normal single-column layout.
711
- * `gap` and `widths` are in points (pt).
781
+ * `gap` and `widths` are in 96-DPI layout pixels.
712
782
  * @example
713
783
  * ```ts
714
784
  * const fDocument = univerAPI.getActiveDocument();
715
- * if (fDocument && !fDocument.isModern()) {
785
+ * if (fDocument?.isTraditional()) {
716
786
  * fDocument.getSection(0)?.setColumns(2, { gap: 18, separator: true });
717
787
  * }
718
788
  * ```
@@ -722,22 +792,23 @@ var FDocumentSection = class {
722
792
  this._assertTraditionalDocument();
723
793
  if (!Number.isInteger(columnCount) || columnCount < 1) throw new RangeError("Section column count must be a positive integer.");
724
794
  if (options.widths && options.widths.length !== columnCount) throw new RangeError("Section column widths must match the column count.");
795
+ if (options.gap != null && (!Number.isFinite(options.gap) || options.gap < 0)) throw new RangeError("Section column gap must be finite and non-negative.");
725
796
  const gap = Math.max(0, (_options$gap = options.gap) !== null && _options$gap !== void 0 ? _options$gap : 18);
726
- const config = this.getConfig();
797
+ const config = this._getConfigSnapshot();
727
798
  const columns = (0, _univerjs_docs.createSectionColumnProperties)(this._document.getDocumentDataModel().getSnapshot().documentStyle, config, columnCount, gap, options.widths);
728
799
  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;
800
+ if (!Object.values(_univerjs_core.ColumnSeparatorType).includes(separator)) throw new RangeError("Invalid section column separator type.");
729
801
  return this._update({
730
802
  columnProperties: columns,
731
- columnSeparatorType: separator,
732
- ...options.sectionType == null ? {} : { sectionType: options.sectionType }
803
+ columnSeparatorType: separator
733
804
  });
734
805
  }
735
806
  /**
736
- * Sets explicit OOXML-compatible column width and trailing-space values in points (pt).
807
+ * Sets explicit OOXML-compatible column width and trailing-space values in 96-DPI layout pixels.
737
808
  * @example
738
809
  * ```ts
739
810
  * const fDocument = univerAPI.getActiveDocument();
740
- * if (fDocument && !fDocument.isModern()) {
811
+ * if (fDocument?.isTraditional()) {
741
812
  * fDocument.getSection(0)?.setColumnProperties([
742
813
  * { width: 240, paddingEnd: 18 },
743
814
  * { width: 240, paddingEnd: 0 },
@@ -747,32 +818,163 @@ var FDocumentSection = class {
747
818
  */
748
819
  setColumnProperties(columns, separator = _univerjs_core.ColumnSeparatorType.NONE) {
749
820
  this._assertTraditionalDocument();
750
- if (columns.some(({ width, paddingEnd }) => width < 0 || paddingEnd < 0)) throw new RangeError("Section column widths and padding must be non-negative.");
821
+ if (!Object.values(_univerjs_core.ColumnSeparatorType).includes(separator)) throw new RangeError("Invalid section column separator type.");
822
+ if (columns.some(({ width, paddingEnd }) => !Number.isFinite(width) || !Number.isFinite(paddingEnd) || width < 0 || paddingEnd < 0)) throw new RangeError("Section column widths and padding must be finite and non-negative.");
823
+ const contentWidth = (0, _univerjs_docs.getSectionContentWidth)(this._document.getDocumentDataModel().getSnapshot().documentStyle, this._getConfigSnapshot());
824
+ if (columns.reduce((sum, { width, paddingEnd }) => sum + width + paddingEnd, 0) > contentWidth) throw new RangeError("Section columns exceed the available page content width.");
751
825
  return this._update({
752
826
  columnProperties: _univerjs_core.Tools.deepClone(columns),
753
827
  columnSeparatorType: separator
754
828
  });
755
829
  }
756
830
  /**
757
- * Sets how the next section begins.
831
+ * Sets how this section begins relative to the previous section.
832
+ *
833
+ * The first section has no preceding boundary, so setting its type does not
834
+ * create an initial blank page. Prefer `FDocument.insertSectionBreak` with
835
+ * `nextSectionType` when creating a new boundary; use this method when
836
+ * updating an existing section after resolving it again from the document.
837
+ *
838
+ * @param {SectionType} sectionType How this section begins.
839
+ * @returns {boolean} `true` when the section command was applied.
758
840
  * @example
759
841
  * ```ts
760
- * const fDocument = univerAPI.getActiveDocument();
761
- * if (fDocument && !fDocument.isModern()) {
762
- * fDocument.getSection(0)?.setSectionType(univerAPI.Enum.SectionType.NEXT_PAGE);
842
+ * const document = univerAPI.getActiveDocument();
843
+ * if (!document?.isTraditional()) {
844
+ * throw new Error('A Traditional document is required');
845
+ * }
846
+ *
847
+ * const secondSection = document.getSection(1);
848
+ * if (!secondSection) {
849
+ * throw new Error('The second section does not exist');
850
+ * }
851
+ * if (!secondSection.setSectionType(univerAPI.Enum.SectionType.NEXT_PAGE)) {
852
+ * throw new Error('Failed to update the second section');
763
853
  * }
764
854
  * ```
765
855
  */
766
856
  setSectionType(sectionType) {
767
857
  this._assertTraditionalDocument();
858
+ if (!Object.values(_univerjs_core.SectionType).includes(sectionType)) throw new RangeError("Invalid section type.");
768
859
  return this._update({ sectionType });
769
860
  }
770
861
  /**
862
+ * Returns this section's explicit page setup overrides.
863
+ * Missing values inherit from the document style. Geometry values use 96-DPI layout pixels.
864
+ *
865
+ * Use `getEffectivePageSetup()` when an agent needs resolved page and content
866
+ * dimensions rather than only the overrides stored on this section.
867
+ *
868
+ * @returns {FDocumentSectionPageSetup} A cloned object containing only explicit section overrides.
869
+ * @example
870
+ * ```ts
871
+ * const document = univerAPI.getActiveDocument();
872
+ * const section = document?.getSection(0);
873
+ * console.log(section?.getPageSetup());
874
+ * ```
875
+ */
876
+ getPageSetup() {
877
+ const { pageNumberStart, pageSize, pageOrient, marginTop, marginBottom, marginLeft, marginRight } = this._getConfigSnapshot();
878
+ return _univerjs_core.Tools.deepClone({
879
+ pageNumberStart,
880
+ pageSize,
881
+ pageOrient,
882
+ marginTop,
883
+ marginBottom,
884
+ marginLeft,
885
+ marginRight
886
+ });
887
+ }
888
+ /**
889
+ * Returns nominal page geometry after resolving this section's overrides
890
+ * against document defaults. All geometry values use 96-DPI layout pixels.
891
+ *
892
+ * This synchronous model-only API works without `engine-render`. It does not
893
+ * report physical page count, remaining page space, or final coordinates.
894
+ *
895
+ * @returns {IEffectiveSectionPageSetup} A cloned, serializable page setup.
896
+ * @example
897
+ * ```ts
898
+ * const document = univerAPI.getActiveDocument();
899
+ * if (!document) {
900
+ * throw new Error('No active document');
901
+ * }
902
+ * if (!document.isTraditional()) {
903
+ * throw new Error('Traditional document sections are required');
904
+ * }
905
+ *
906
+ * const section = document.getSection(0);
907
+ * if (!section) {
908
+ * throw new Error('The document has no traditional section');
909
+ * }
910
+ *
911
+ * const layout = section.getEffectivePageSetup();
912
+ * console.log({
913
+ * pageWidth: layout.pageSize.width,
914
+ * pageHeight: layout.pageSize.height,
915
+ * contentWidth: layout.contentSize.width,
916
+ * contentHeight: layout.contentSize.height,
917
+ * margins: layout.margins,
918
+ * });
919
+ * ```
920
+ */
921
+ getEffectivePageSetup() {
922
+ this._assertTraditionalDocument();
923
+ const documentStyle = this._document.getDocumentDataModel().getSnapshot().documentStyle;
924
+ return _univerjs_core.Tools.deepClone((0, _univerjs_docs.getEffectiveSectionPageSetup)(documentStyle, this._getConfigSnapshot()));
925
+ }
926
+ /**
927
+ * Updates this section's page setup through the document section command.
928
+ * Geometry values use 96-DPI layout pixels.
929
+ *
930
+ * This method changes static page geometry; it does not choose where the
931
+ * section begins. Use `setSectionType()` for an existing boundary, or
932
+ * `insertSectionBreak(..., { nextSectionType })` while creating one.
933
+ *
934
+ * @param {FDocumentSectionPageSetup} pageSetup Explicit section overrides to patch.
935
+ * @returns {boolean} `true` when the section command was applied.
936
+ * @example
937
+ * ```ts
938
+ * const document = univerAPI.getActiveDocument();
939
+ * if (!document?.isTraditional()) {
940
+ * throw new Error('A Traditional document is required');
941
+ * }
942
+ *
943
+ * const section = document.getSection(1);
944
+ * if (!section) {
945
+ * throw new Error('The second section does not exist');
946
+ * }
947
+ * const updated = section.setPageSetup({
948
+ * pageSize: { width: 816, height: 1056 },
949
+ * marginTop: 96,
950
+ * marginBottom: 96,
951
+ * marginLeft: 96,
952
+ * marginRight: 96,
953
+ * });
954
+ * if (!updated) {
955
+ * throw new Error('Failed to update section page setup');
956
+ * }
957
+ * console.log(section.getEffectivePageSetup());
958
+ * ```
959
+ */
960
+ setPageSetup(pageSetup) {
961
+ this._assertTraditionalDocument();
962
+ validatePageSetup(pageSetup);
963
+ const definedPageSetup = _univerjs_core.Tools.deepClone(pageSetup);
964
+ _univerjs_core.Tools.removeNull(definedPageSetup);
965
+ const documentStyle = this._document.getDocumentDataModel().getSnapshot().documentStyle;
966
+ (0, _univerjs_docs.getEffectiveSectionPageSetup)(documentStyle, {
967
+ ...this._getConfigSnapshot(),
968
+ ...definedPageSetup
969
+ });
970
+ return this._update(definedPageSetup);
971
+ }
972
+ /**
771
973
  * Ensures a header segment linked specifically to this section.
772
974
  * @example
773
975
  * ```ts
774
976
  * const fDocument = univerAPI.getActiveDocument();
775
- * if (fDocument && !fDocument.isModern()) {
977
+ * if (fDocument?.isTraditional()) {
776
978
  * const segmentId = fDocument.getSection(0)?.ensureHeader();
777
979
  * if (segmentId) {
778
980
  * fDocument.insertText(0, 'Quarterly report', segmentId);
@@ -788,7 +990,7 @@ var FDocumentSection = class {
788
990
  * @example
789
991
  * ```ts
790
992
  * const fDocument = univerAPI.getActiveDocument();
791
- * if (fDocument && !fDocument.isModern()) {
993
+ * if (fDocument?.isTraditional()) {
792
994
  * const segmentId = fDocument.getSection(0)?.ensureFooter('first');
793
995
  * if (segmentId) {
794
996
  * fDocument.insertText(0, 'Confidential', segmentId);
@@ -850,7 +1052,7 @@ var FDocumentSection = class {
850
1052
  * @example
851
1053
  * ```ts
852
1054
  * const fDocument = univerAPI.getActiveDocument();
853
- * if (fDocument && !fDocument.isModern()) {
1055
+ * if (fDocument?.isTraditional()) {
854
1056
  * fDocument.getSection(1)?.setHeaderLinkedToPrevious(false, 'default');
855
1057
  * }
856
1058
  * ```
@@ -863,7 +1065,7 @@ var FDocumentSection = class {
863
1065
  * @example
864
1066
  * ```ts
865
1067
  * const fDocument = univerAPI.getActiveDocument();
866
- * if (fDocument && !fDocument.isModern()) {
1068
+ * if (fDocument?.isTraditional()) {
867
1069
  * fDocument.getSection(1)?.setFooterLinkedToPrevious(true, 'even');
868
1070
  * }
869
1071
  * ```
@@ -873,11 +1075,11 @@ var FDocumentSection = class {
873
1075
  }
874
1076
  /**
875
1077
  * Updates header/footer switches and margins on this section break.
876
- * `marginHeader` and `marginFooter` are in points (pt).
1078
+ * `marginHeader` and `marginFooter` are in 96-DPI layout pixels.
877
1079
  * @example
878
1080
  * ```ts
879
1081
  * const fDocument = univerAPI.getActiveDocument();
880
- * if (fDocument && !fDocument.isModern()) {
1082
+ * if (fDocument?.isTraditional()) {
881
1083
  * fDocument.getSection(0)?.setHeaderFooterOptions({
882
1084
  * marginHeader: 36,
883
1085
  * marginFooter: 36,
@@ -895,7 +1097,7 @@ var FDocumentSection = class {
895
1097
  * @example
896
1098
  * ```ts
897
1099
  * const fDocument = univerAPI.getActiveDocument();
898
- * if (fDocument && !fDocument.isModern()) {
1100
+ * if (fDocument?.isTraditional()) {
899
1101
  * const sections = fDocument.getSections();
900
1102
  * if (sections.length > 1) {
901
1103
  * sections[0].remove();
@@ -905,14 +1107,14 @@ var FDocumentSection = class {
905
1107
  */
906
1108
  remove() {
907
1109
  this._assertTraditionalDocument();
908
- return this._injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.DeleteDocumentSectionBreakCommand.id, {
1110
+ return this._commandService.syncExecuteCommand(_univerjs_docs.DeleteDocumentSectionBreakCommand.id, {
909
1111
  unitId: this._document.getId(),
910
1112
  sectionId: this._sectionId
911
1113
  });
912
1114
  }
913
1115
  _update(patch) {
914
1116
  const { sectionId: _sectionId, startIndex: _startIndex, ...config } = patch;
915
- return this._injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.UpdateDocumentSectionCommand.id, {
1117
+ return this._commandService.syncExecuteCommand(_univerjs_docs.UpdateDocumentSectionCommand.id, {
916
1118
  unitId: this._document.getId(),
917
1119
  updates: [{
918
1120
  sectionId: this._sectionId,
@@ -923,11 +1125,11 @@ var FDocumentSection = class {
923
1125
  _ensureHeaderFooter(kind, variant) {
924
1126
  this._assertTraditionalDocument();
925
1127
  const { index } = this._resolve();
926
- const existing = this.getConfig()[(0, _univerjs_core.getSectionHeaderFooterReferenceKey)(kind, variant)];
1128
+ const existing = this._getConfigSnapshot()[(0, _univerjs_core.getSectionHeaderFooterReferenceKey)(kind, variant)];
927
1129
  if (typeof existing === "string" && existing) return existing;
928
1130
  if (index > 0) {
929
1131
  const segmentId = (0, _univerjs_core.generateRandomId)(6);
930
- if (!this._injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.SetSectionHeaderFooterLinkCommand.id, {
1132
+ if (!this._commandService.syncExecuteCommand(_univerjs_docs.SetSectionHeaderFooterLinkCommand.id, {
931
1133
  unitId: this._document.getId(),
932
1134
  sectionId: this._sectionId,
933
1135
  kind,
@@ -943,7 +1145,7 @@ var FDocumentSection = class {
943
1145
  even: kind === "header" ? _univerjs_docs.HeaderFooterType.EVEN_PAGE_HEADER : _univerjs_docs.HeaderFooterType.EVEN_PAGE_FOOTER
944
1146
  };
945
1147
  const segmentId = (0, _univerjs_core.generateRandomId)(6);
946
- if (!this._injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.CreateHeaderFooterCommand.id, {
1148
+ if (!this._commandService.syncExecuteCommand(_univerjs_docs.CreateHeaderFooterCommand.id, {
947
1149
  unitId: this._document.getId(),
948
1150
  segmentId,
949
1151
  createType: types[variant],
@@ -965,7 +1167,7 @@ var FDocumentSection = class {
965
1167
  }
966
1168
  _setHeaderFooterLinkedToPrevious(kind, variant, linkedToPrevious) {
967
1169
  this._assertTraditionalDocument();
968
- return this._injector.get(_univerjs_core.ICommandService).syncExecuteCommand(_univerjs_docs.SetSectionHeaderFooterLinkCommand.id, {
1170
+ return this._commandService.syncExecuteCommand(_univerjs_docs.SetSectionHeaderFooterLinkCommand.id, {
969
1171
  unitId: this._document.getId(),
970
1172
  sectionId: this._sectionId,
971
1173
  kind,
@@ -977,6 +1179,17 @@ var FDocumentSection = class {
977
1179
  _assertTraditionalDocument() {
978
1180
  if (this._document.getDocumentDataModel().getSnapshot().documentStyle.documentFlavor !== _univerjs_core.DocumentFlavor.TRADITIONAL) throw new DocsSectionUnsupportedDocumentFlavorError();
979
1181
  }
1182
+ _getConfigSnapshot() {
1183
+ return _univerjs_core.Tools.deepClone(this._resolve().sectionBreak);
1184
+ }
1185
+ _getRange(index) {
1186
+ const sectionBreaks = (0, _univerjs_docs.getTopLevelSectionBreaks)(this._document.getBody());
1187
+ return {
1188
+ startOffset: index === 0 ? 0 : sectionBreaks[index - 1].startIndex + 1,
1189
+ endOffset: sectionBreaks[index].startIndex,
1190
+ segmentId: ""
1191
+ };
1192
+ }
980
1193
  _resolve() {
981
1194
  this._assertTraditionalDocument();
982
1195
  const sectionBreaks = (0, _univerjs_docs.getTopLevelSectionBreaks)(this._document.getBody());
@@ -988,9 +1201,10 @@ var FDocumentSection = class {
988
1201
  };
989
1202
  }
990
1203
  };
1204
+ FDocumentSection = __decorate([__decorateParam(2, _univerjs_core.ICommandService)], FDocumentSection);
991
1205
 
992
1206
  //#endregion
993
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/typeof.js
1207
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/typeof.js
994
1208
  function _typeof(o) {
995
1209
  "@babel/helpers - typeof";
996
1210
  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
@@ -1001,7 +1215,7 @@ function _typeof(o) {
1001
1215
  }
1002
1216
 
1003
1217
  //#endregion
1004
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPrimitive.js
1218
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/toPrimitive.js
1005
1219
  function toPrimitive(t, r) {
1006
1220
  if ("object" != _typeof(t) || !t) return t;
1007
1221
  var e = t[Symbol.toPrimitive];
@@ -1014,14 +1228,14 @@ function toPrimitive(t, r) {
1014
1228
  }
1015
1229
 
1016
1230
  //#endregion
1017
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPropertyKey.js
1231
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/toPropertyKey.js
1018
1232
  function toPropertyKey(t) {
1019
1233
  var i = toPrimitive(t, "string");
1020
1234
  return "symbol" == _typeof(i) ? i : i + "";
1021
1235
  }
1022
1236
 
1023
1237
  //#endregion
1024
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/defineProperty.js
1238
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/defineProperty.js
1025
1239
  function _defineProperty(e, r, t) {
1026
1240
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
1027
1241
  value: t,
@@ -1031,23 +1245,6 @@ function _defineProperty(e, r, t) {
1031
1245
  }) : e[r] = t, e;
1032
1246
  }
1033
1247
 
1034
- //#endregion
1035
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/decorateParam.js
1036
- function __decorateParam(paramIndex, decorator) {
1037
- return function(target, key) {
1038
- decorator(target, key, paramIndex);
1039
- };
1040
- }
1041
-
1042
- //#endregion
1043
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/decorate.js
1044
- function __decorate(decorators, target, key, desc) {
1045
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1046
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1047
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1048
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1049
- }
1050
-
1051
1248
  //#endregion
1052
1249
  //#region src/facade/f-document.ts
1053
1250
  let FDocument = class FDocument extends _univerjs_core_facade.FBaseInitialable {
@@ -1128,16 +1325,73 @@ let FDocument = class FDocument extends _univerjs_core_facade.FBaseInitialable {
1128
1325
  return this._documentDataModel.getTitle() || "";
1129
1326
  }
1130
1327
  /**
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.
1328
+ * Returns the document's explicit layout flavor.
1329
+ *
1330
+ * Use this method when all three states matter. Do not infer a Traditional
1331
+ * document from `!isModern()`: that expression is also true for
1332
+ * `DocumentFlavor.UNSPECIFIED`.
1333
+ *
1334
+ * @returns {DocumentFlavor} `TRADITIONAL`, `MODERN`, or `UNSPECIFIED`.
1335
+ * @example
1336
+ * ```typescript
1337
+ * const document = univerAPI.getActiveDocument();
1338
+ * if (!document) {
1339
+ * throw new Error('No active document');
1340
+ * }
1341
+ *
1342
+ * switch (document.getDocumentFlavor()) {
1343
+ * case univerAPI.Enum.DocumentFlavor.TRADITIONAL:
1344
+ * console.log('Word-compatible physical pagination is available');
1345
+ * break;
1346
+ * case univerAPI.Enum.DocumentFlavor.MODERN:
1347
+ * console.log('Use Modern Doc layout APIs such as ColumnGroup');
1348
+ * break;
1349
+ * default:
1350
+ * console.log('Resolve the unspecified flavor before using flavor-specific APIs');
1351
+ * }
1352
+ * ```
1353
+ */
1354
+ getDocumentFlavor() {
1355
+ return this._resolveDocumentFlavor();
1356
+ }
1357
+ /**
1358
+ * Whether this is a Traditional document with Word-compatible physical pagination.
1359
+ *
1360
+ * Prefer this positive guard before calling section, column-break, page-setup,
1361
+ * or paragraph-pagination APIs.
1362
+ *
1363
+ * @returns {boolean} `true` only for `DocumentFlavor.TRADITIONAL`.
1364
+ * @example
1365
+ * ```typescript
1366
+ * const document = univerAPI.getActiveDocument();
1367
+ * if (document?.isTraditional()) {
1368
+ * console.log(document.getSection(0)?.getEffectivePageSetup());
1369
+ * }
1370
+ * ```
1371
+ */
1372
+ isTraditional() {
1373
+ return this._resolveDocumentFlavor() === _univerjs_core.DocumentFlavor.TRADITIONAL;
1374
+ }
1375
+ /**
1376
+ * Whether this is a Modern document.
1377
+ *
1378
+ * A `false` result can mean either Traditional or Unspecified. Use
1379
+ * `isTraditional()` before Traditional-only APIs, or `getDocumentFlavor()`
1380
+ * when all three states matter.
1381
+ *
1382
+ * @returns {boolean} `true` only for `DocumentFlavor.MODERN`.
1133
1383
  * @example
1134
1384
  * ```typescript
1135
1385
  * const fDocument = univerAPI.getActiveDocument();
1136
- * console.log(fDocument.isModern());
1386
+ * console.log(fDocument?.isModern());
1137
1387
  * ```
1138
1388
  */
1139
1389
  isModern() {
1140
- return this._documentDataModel.getSnapshot().documentStyle.documentFlavor === _univerjs_core.DocumentFlavor.MODERN;
1390
+ return this._resolveDocumentFlavor() === _univerjs_core.DocumentFlavor.MODERN;
1391
+ }
1392
+ _resolveDocumentFlavor() {
1393
+ var _this$_documentDataMo2;
1394
+ return (_this$_documentDataMo2 = this._documentDataModel.getSnapshot().documentStyle.documentFlavor) !== null && _this$_documentDataMo2 !== void 0 ? _this$_documentDataMo2 : _univerjs_core.DocumentFlavor.UNSPECIFIED;
1141
1395
  }
1142
1396
  /**
1143
1397
  * Save the document snapshot data, including the document content and resource data, etc.
@@ -1231,7 +1485,7 @@ let FDocument = class FDocument extends _univerjs_core_facade.FBaseInitialable {
1231
1485
  }, buildPlainTextInsertBody(text), this._documentDataModel, this._injector);
1232
1486
  }
1233
1487
  /**
1234
- * Returns document-level header/footer switches and margins. Margin values are in points (pt).
1488
+ * Returns document-level header/footer switches and margins. Margin values use 96-DPI layout pixels.
1235
1489
  * @example
1236
1490
  * ```ts
1237
1491
  * const fDocument = univerAPI.getActiveDocument();
@@ -1248,12 +1502,18 @@ let FDocument = class FDocument extends _univerjs_core_facade.FBaseInitialable {
1248
1502
  };
1249
1503
  }
1250
1504
  /**
1251
- * Updates document-level header/footer switches and margins in a traditional document.
1252
- * `marginHeader` and `marginFooter` are in points (pt).
1505
+ * Updates document-level header/footer switches and margins.
1506
+ *
1507
+ * Traditional and Unspecified documents keep the legacy header/footer
1508
+ * behavior. Modern documents reject this API. `marginHeader` and
1509
+ * `marginFooter` use 96-DPI layout pixels.
1253
1510
  * @example
1254
1511
  * ```ts
1255
1512
  * const fDocument = univerAPI.getActiveDocument();
1256
- * if (fDocument && !fDocument.isModern()) {
1513
+ * if (
1514
+ * fDocument &&
1515
+ * fDocument.getDocumentFlavor() !== univerAPI.Enum.DocumentFlavor.MODERN
1516
+ * ) {
1257
1517
  * fDocument.setHeaderFooterOptions({ marginHeader: 36, marginFooter: 36 });
1258
1518
  * }
1259
1519
  * ```
@@ -1294,7 +1554,7 @@ let FDocument = class FDocument extends _univerjs_core_facade.FBaseInitialable {
1294
1554
  */
1295
1555
  getSections() {
1296
1556
  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));
1557
+ return (0, _univerjs_docs.getTopLevelSectionBreaks)(this.getBody()).map((sectionBreak) => this._injector.createInstance(FDocumentSection, this, sectionBreak.sectionId));
1298
1558
  }
1299
1559
  /**
1300
1560
  * Returns a traditional section by zero-based index, or `null` in modern documents.
@@ -1324,42 +1584,83 @@ let FDocument = class FDocument extends _univerjs_core_facade.FBaseInitialable {
1324
1584
  var _this$getSections$fin;
1325
1585
  return (_this$getSections$fin = this.getSections().find((section) => {
1326
1586
  const range = section.getRange();
1327
- return offset >= range.startOffset && offset <= range.endOffset;
1587
+ return offset >= range.startOffset && offset < range.endOffset;
1328
1588
  })) !== null && _this$getSections$fin !== void 0 ? _this$getSections$fin : null;
1329
1589
  }
1330
1590
  /**
1331
1591
  * 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).
1592
+ *
1593
+ * `options` configures the section created before the inserted break.
1594
+ * Set `options.nextSectionType` to control how the existing section after the
1595
+ * break begins. For example, use `SectionType.NEXT_PAGE` to start a chapter on
1596
+ * a new physical page. Both changes are executed by one command and are
1597
+ * undone or redone together.
1598
+ *
1599
+ * The offset must be a top-level document position. To insert a break before
1600
+ * a table or block such as a callout, use that object's start offset instead
1601
+ * of an offset inside the object.
1602
+ *
1603
+ * Modern documents must use ColumnGroup. Unspecified documents must resolve
1604
+ * their flavor first. Both throw `DocsSectionUnsupportedDocumentFlavorError`.
1605
+ * Numeric layout values in `options` are in 96-DPI layout pixels.
1606
+ *
1607
+ * @param {number} offset Top-level data-stream offset where the section break is inserted.
1608
+ * @param {IFDocumentInsertSectionBreakOptions} [options] Section properties and the optional type of the following section.
1609
+ * @returns {FDocumentSection | null} The section created before the break, or `null` when the command rejects the insertion.
1334
1610
  * @example
1335
1611
  * ```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());
1612
+ * const document = univerAPI.getActiveDocument();
1613
+ * if (!document) {
1614
+ * throw new Error('No active document');
1615
+ * }
1616
+ * if (!document.isTraditional()) {
1617
+ * throw new Error('Traditional document sections are required');
1342
1618
  * }
1619
+ *
1620
+ * const chapter = document.findParagraphByText('Chapter 2');
1621
+ * if (!chapter) {
1622
+ * throw new Error('Chapter heading not found');
1623
+ * }
1624
+ *
1625
+ * // Insert the boundary immediately before the chapter heading. The command
1626
+ * // also marks the following section as NEXT_PAGE, so the two model changes
1627
+ * // share one undo/redo step.
1628
+ * const sectionBeforeChapter = document.insertSectionBreak(
1629
+ * chapter.getInfo().startOffset,
1630
+ * { nextSectionType: univerAPI.Enum.SectionType.NEXT_PAGE }
1631
+ * );
1632
+ * if (!sectionBeforeChapter) {
1633
+ * throw new Error('The chapter heading is not at a valid top-level offset');
1634
+ * }
1635
+ *
1636
+ * console.log({
1637
+ * insertedSection: sectionBeforeChapter.describe(),
1638
+ * chapterSection: document.getSectionAt(chapter.getInfo().startOffset)?.describe(),
1639
+ * });
1343
1640
  * ```
1344
1641
  */
1345
- insertSectionBreak(offset, config = {}) {
1642
+ insertSectionBreak(offset, options = {}) {
1346
1643
  var _this$getBody$section;
1347
1644
  if (this._documentDataModel.getSnapshot().documentStyle.documentFlavor !== _univerjs_core.DocumentFlavor.TRADITIONAL) throw new DocsSectionUnsupportedDocumentFlavorError();
1645
+ const { nextSectionType, ...config } = options;
1348
1646
  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
1647
  return this._commandService.syncExecuteCommand(_univerjs_docs.InsertDocumentSectionBreakCommand.id, {
1350
1648
  unitId: this.getId(),
1351
1649
  offset,
1352
1650
  sectionId,
1353
- config
1354
- }) ? this._injector.createInstance(FDocumentSection, this, sectionId, this._injector) : null;
1651
+ config,
1652
+ nextSectionType
1653
+ }) ? this._injector.createInstance(FDocumentSection, this, sectionId) : null;
1355
1654
  }
1356
1655
  /**
1357
1656
  * Inserts a column-break token in a traditional document.
1358
- * Modern documents must use ColumnGroup and throw `DocsSectionUnsupportedDocumentFlavorError`.
1657
+ * In a single-column section, the traditional renderer advances to the next physical page.
1658
+ * Modern documents must use ColumnGroup. Unspecified documents must resolve
1659
+ * their flavor first. Both throw `DocsSectionUnsupportedDocumentFlavorError`.
1359
1660
  * @example
1360
1661
  * ```ts
1361
1662
  * const fDocument = univerAPI.getActiveDocument();
1362
- * if (fDocument && !fDocument.isModern()) {
1663
+ * if (fDocument?.isTraditional()) {
1363
1664
  * const paragraph = fDocument.findParagraphByText('Continue in next column');
1364
1665
  * const offset = paragraph?.getInfo().startOffset;
1365
1666
  * if (offset != null) {
@@ -1370,7 +1671,10 @@ let FDocument = class FDocument extends _univerjs_core_facade.FBaseInitialable {
1370
1671
  */
1371
1672
  insertColumnBreak(offset) {
1372
1673
  if (this._documentDataModel.getSnapshot().documentStyle.documentFlavor !== _univerjs_core.DocumentFlavor.TRADITIONAL) throw new DocsSectionUnsupportedDocumentFlavorError();
1373
- return this.insertText(offset, _univerjs_core.DataStreamTreeTokenType.COLUMN_BREAK);
1674
+ return this._commandService.syncExecuteCommand(_univerjs_docs.InsertDocumentColumnBreakCommand.id, {
1675
+ unitId: this.getId(),
1676
+ offset
1677
+ });
1374
1678
  }
1375
1679
  /**
1376
1680
  * Inserts a horizontal rule using the existing paragraph `borderBottom` mechanism.
@@ -1671,6 +1975,9 @@ _univerjs_core_facade.FUniver.extend(FUniverDocsMixin);
1671
1975
  * limitations under the License.
1672
1976
  */
1673
1977
  var FDocsEnumMixin = class extends _univerjs_core_facade.FEnum {
1978
+ get DocumentFlavor() {
1979
+ return _univerjs_core.DocumentFlavor;
1980
+ }
1674
1981
  get SectionType() {
1675
1982
  return _univerjs_core.SectionType;
1676
1983
  }
@@ -1689,8 +1996,18 @@ Object.defineProperty(exports, 'FDocument', {
1689
1996
  return FDocument;
1690
1997
  }
1691
1998
  });
1692
- exports.FDocumentParagraph = FDocumentParagraph;
1693
- exports.FDocumentSection = FDocumentSection;
1999
+ Object.defineProperty(exports, 'FDocumentParagraph', {
2000
+ enumerable: true,
2001
+ get: function () {
2002
+ return FDocumentParagraph;
2003
+ }
2004
+ });
2005
+ Object.defineProperty(exports, 'FDocumentSection', {
2006
+ enumerable: true,
2007
+ get: function () {
2008
+ return FDocumentSection;
2009
+ }
2010
+ });
1694
2011
  exports.FDocumentTextRange = FDocumentTextRange;
1695
2012
  exports.isParagraphFacade = isParagraphFacade;
1696
2013
  exports.stripBlockTokens = stripBlockTokens;