@univerjs/docs 1.0.0-alpha.2 → 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.
- package/lib/cjs/facade.js +812 -4
- package/lib/cjs/index.js +578 -22
- package/lib/es/facade.js +812 -8
- package/lib/es/index.js +560 -23
- package/lib/facade.js +812 -8
- package/lib/index.js +560 -23
- package/lib/types/commands/commands/create-header-footer.command.d.ts +5 -1
- package/lib/types/commands/commands/set-document-default-paragraph-style.command.d.ts +24 -0
- package/lib/types/commands/commands/set-section-header-footer-link.command.d.ts +26 -0
- package/lib/types/commands/commands/update-document-section.command.d.ts +38 -0
- package/lib/types/embed-host-anchor.d.ts +61 -0
- package/lib/types/facade/f-document-paragraph.d.ts +14 -0
- package/lib/types/facade/f-document-section.d.ts +281 -0
- package/lib/types/facade/f-document-text-range.d.ts +136 -0
- package/lib/types/facade/f-document.d.ts +120 -1
- package/lib/types/facade/f-enum.d.ts +32 -0
- package/lib/types/facade/f-types.d.ts +16 -0
- package/lib/types/facade/index.d.ts +7 -0
- package/lib/types/index.d.ts +13 -2
- package/lib/types/utils/paragraphs.d.ts +18 -0
- package/lib/types/utils/section-columns.d.ts +18 -0
- package/lib/types/utils/sections.d.ts +18 -0
- package/lib/umd/facade.js +2 -2
- package/lib/umd/index.js +2 -2
- package/package.json +5 -5
package/lib/facade.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BooleanNumber, DataStreamTreeTokenType, DocumentFlavor, ICommandService, IResourceLoaderService, IUniverInstanceService, Inject, Injector, JSONX, PresetListType, RESTORE_INSERTED_PARAGRAPH_IDS, RedoCommand, TextX, TextXActionType, UndoCommand, UniverInstanceType, UpdateDocsAttributeType, createParagraphId, generateRandomId, getRichTextEditPath } from "@univerjs/core";
|
|
2
|
-
import { FBaseInitialable, FUniver } from "@univerjs/core/facade";
|
|
3
|
-
import { CreateHeaderFooterCommand, HeaderFooterType, RichTextEditingMutation } from "@univerjs/docs";
|
|
1
|
+
import { BooleanNumber, ColumnSeparatorType, DashStyleType, DataStreamTreeTokenType, DocumentFlavor, ICommandService, IResourceLoaderService, IUniverInstanceService, Inject, Injector, JSONX, PresetListType, RESTORE_INSERTED_PARAGRAPH_IDS, RedoCommand, SectionType, TextX, TextXActionType, Tools, UndoCommand, UniverInstanceType, UpdateDocsAttributeType, createParagraphId, createSectionId, generateRandomId, getParagraphContentStartOffset, getRichTextEditPath, getSectionHeaderFooterReferenceKey, resolveSectionHeaderFooterReference } from "@univerjs/core";
|
|
2
|
+
import { FBaseInitialable, FEnum, FUniver } from "@univerjs/core/facade";
|
|
3
|
+
import { CreateHeaderFooterCommand, DeleteDocumentSectionBreakCommand, HeaderFooterType, InsertDocumentSectionBreakCommand, RichTextEditingMutation, SetSectionHeaderFooterLinkCommand, UpdateDocumentSectionCommand, createSectionColumnProperties, generateParagraphs, getTopLevelSectionBreaks } from "@univerjs/docs";
|
|
4
4
|
|
|
5
5
|
//#region src/facade/utils.ts
|
|
6
6
|
function cloneParagraphStyle(paragraphStyle) {
|
|
@@ -97,6 +97,184 @@ function stripBlockTokens(text) {
|
|
|
97
97
|
return Array.from(text).map((char) => char === DataStreamTreeTokenType.PARAGRAPH ? "\n" : char).filter((char) => char !== DataStreamTreeTokenType.BLOCK_START && char !== DataStreamTreeTokenType.BLOCK_END && char !== DataStreamTreeTokenType.SECTION_BREAK).join("").replace(/\n$/, "");
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/facade/f-document-text-range.ts
|
|
102
|
+
/**
|
|
103
|
+
* Facade wrapper for reading and styling a fixed document text range.
|
|
104
|
+
*
|
|
105
|
+
* Offsets are fixed when the wrapper is created. Create a new range after edits
|
|
106
|
+
* that insert or remove content before it.
|
|
107
|
+
* @hideconstructor
|
|
108
|
+
*/
|
|
109
|
+
var FDocumentTextRange = class {
|
|
110
|
+
constructor(_document, _startOffset, _endOffset, _segmentId, _injector) {
|
|
111
|
+
this._document = _document;
|
|
112
|
+
this._startOffset = _startOffset;
|
|
113
|
+
this._endOffset = _endOffset;
|
|
114
|
+
this._segmentId = _segmentId;
|
|
115
|
+
this._injector = _injector;
|
|
116
|
+
this._validateRange();
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Returns the serializable document range.
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
123
|
+
* const range = fDocument?.findParagraphByText('Launch')?.getTextRange();
|
|
124
|
+
* console.log(range?.getRange());
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
getRange() {
|
|
128
|
+
return {
|
|
129
|
+
startOffset: this._startOffset,
|
|
130
|
+
endOffset: this._endOffset,
|
|
131
|
+
segmentId: this._segmentId
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Returns the plain data-stream text in this range.
|
|
136
|
+
* @example
|
|
137
|
+
* ```ts
|
|
138
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
139
|
+
* const range = fDocument?.findParagraphByText('Launch')?.getTextRange();
|
|
140
|
+
* console.log(range?.getText());
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
getText() {
|
|
144
|
+
return this._document.getBody(this._segmentId).dataStream.slice(this._startOffset, this._endOffset);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Returns explicit text-style runs intersecting this range.
|
|
148
|
+
* Returned offsets are clipped to the range and remain document-relative.
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
152
|
+
* const range = fDocument?.findParagraphByText('Launch')?.getTextRange();
|
|
153
|
+
* console.log(range?.getExplicitTextStyleRuns());
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
getExplicitTextStyleRuns() {
|
|
157
|
+
const { textRuns = [] } = this._document.getBody(this._segmentId);
|
|
158
|
+
return textRuns.filter((run) => run.st < this._endOffset && run.ed > this._startOffset).map((run) => {
|
|
159
|
+
var _run$ts;
|
|
160
|
+
return {
|
|
161
|
+
startOffset: Math.max(run.st, this._startOffset),
|
|
162
|
+
endOffset: Math.min(run.ed, this._endOffset),
|
|
163
|
+
textStyle: Tools.deepClone((_run$ts = run.ts) !== null && _run$ts !== void 0 ? _run$ts : {})
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/** @deprecated Use `getExplicitTextStyleRuns()` to distinguish stored styles from effective styles. */
|
|
168
|
+
getTextStyleRuns() {
|
|
169
|
+
return this.getExplicitTextStyleRuns();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Returns top-level style properties that have the same explicit value
|
|
173
|
+
* across the complete range. Unstyled gaps make a property non-common.
|
|
174
|
+
* @example
|
|
175
|
+
* ```ts
|
|
176
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
177
|
+
* const range = fDocument?.findParagraphByText('Launch')?.getTextRange();
|
|
178
|
+
* console.log(range?.getCommonExplicitTextStyle());
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
getCommonExplicitTextStyle() {
|
|
182
|
+
if (this._startOffset === this._endOffset) return {};
|
|
183
|
+
const [first, ...rest] = this._getStyleSegments();
|
|
184
|
+
const common = Tools.deepClone(first.textStyle);
|
|
185
|
+
for (const key of Object.keys(common)) if (rest.some((run) => !isDeepEqual(run.textStyle[key], common[key]))) delete common[key];
|
|
186
|
+
return common;
|
|
187
|
+
}
|
|
188
|
+
/** @deprecated Use `getCommonExplicitTextStyle()` to distinguish stored styles from effective styles. */
|
|
189
|
+
getCommonTextStyle() {
|
|
190
|
+
return this.getCommonExplicitTextStyle();
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Returns a serializable summary suitable for an agent/tool response.
|
|
194
|
+
* @example
|
|
195
|
+
* ```ts
|
|
196
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
197
|
+
* const range = fDocument?.findParagraphByText('Launch')?.getTextRange();
|
|
198
|
+
* console.log(range?.describe());
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
describe() {
|
|
202
|
+
const explicitTextStyleRuns = this.getExplicitTextStyleRuns();
|
|
203
|
+
const commonExplicitTextStyle = this.getCommonExplicitTextStyle();
|
|
204
|
+
return {
|
|
205
|
+
...this.getRange(),
|
|
206
|
+
text: this.getText(),
|
|
207
|
+
length: this._endOffset - this._startOffset,
|
|
208
|
+
explicitTextStyleRuns,
|
|
209
|
+
commonExplicitTextStyle,
|
|
210
|
+
textStyleRuns: explicitTextStyleRuns,
|
|
211
|
+
commonTextStyle: commonExplicitTextStyle
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Merges a text-style patch into every character in the range.
|
|
216
|
+
* Existing text-run splitting, merging, and normalization are handled by
|
|
217
|
+
* the document mutation pipeline.
|
|
218
|
+
* `style.fs` is a font size in points (pt), not CSS pixels.
|
|
219
|
+
* @example
|
|
220
|
+
* ```ts
|
|
221
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
222
|
+
* const range = fDocument?.findParagraphByText('Launch')?.getTextRange();
|
|
223
|
+
* range?.setTextStyle({ fs: 10.5, bl: univerAPI.Enum.BooleanNumber.TRUE });
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
setTextStyle(style) {
|
|
227
|
+
if (this._startOffset === this._endOffset) return false;
|
|
228
|
+
return retainBodyRange(this.getRange(), {
|
|
229
|
+
dataStream: "",
|
|
230
|
+
textRuns: [{
|
|
231
|
+
st: 0,
|
|
232
|
+
ed: this._endOffset - this._startOffset,
|
|
233
|
+
ts: Tools.deepClone(style)
|
|
234
|
+
}]
|
|
235
|
+
}, UpdateDocsAttributeType.COVER, this._document.getDocumentDataModel(), this._injector);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Replaces the range with plain text while preserving document mutation semantics.
|
|
239
|
+
* @example
|
|
240
|
+
* ```ts
|
|
241
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
242
|
+
* const range = fDocument?.findParagraphByText('Draft')?.getTextRange();
|
|
243
|
+
* range?.setText('Final');
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
setText(text) {
|
|
247
|
+
return replaceBodyRange(this.getRange(), buildPlainTextInsertBody(text), this._document.getDocumentDataModel(), this._injector);
|
|
248
|
+
}
|
|
249
|
+
_validateRange() {
|
|
250
|
+
const bodyLength = this._document.getBody(this._segmentId).dataStream.length;
|
|
251
|
+
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}.`);
|
|
252
|
+
}
|
|
253
|
+
_getStyleSegments() {
|
|
254
|
+
const explicitRuns = this.getExplicitTextStyleRuns();
|
|
255
|
+
const segments = [];
|
|
256
|
+
let offset = this._startOffset;
|
|
257
|
+
for (const run of explicitRuns) {
|
|
258
|
+
if (offset < run.startOffset) segments.push({
|
|
259
|
+
startOffset: offset,
|
|
260
|
+
endOffset: run.startOffset,
|
|
261
|
+
textStyle: {}
|
|
262
|
+
});
|
|
263
|
+
segments.push(run);
|
|
264
|
+
offset = run.endOffset;
|
|
265
|
+
}
|
|
266
|
+
if (offset < this._endOffset) segments.push({
|
|
267
|
+
startOffset: offset,
|
|
268
|
+
endOffset: this._endOffset,
|
|
269
|
+
textStyle: {}
|
|
270
|
+
});
|
|
271
|
+
return segments;
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
function isDeepEqual(left, right) {
|
|
275
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
276
|
+
}
|
|
277
|
+
|
|
100
278
|
//#endregion
|
|
101
279
|
//#region src/facade/f-document-paragraph.ts
|
|
102
280
|
/**
|
|
@@ -154,7 +332,8 @@ var FDocumentParagraph = class {
|
|
|
154
332
|
* ```
|
|
155
333
|
*/
|
|
156
334
|
getInfo() {
|
|
157
|
-
const
|
|
335
|
+
const body = this._document.getBody(this._segmentId);
|
|
336
|
+
const { paragraphs = [] } = body;
|
|
158
337
|
const matches = paragraphs.map((paragraph, paragraphIndex) => ({
|
|
159
338
|
paragraph,
|
|
160
339
|
paragraphIndex
|
|
@@ -165,7 +344,7 @@ var FDocumentParagraph = class {
|
|
|
165
344
|
return {
|
|
166
345
|
paragraph,
|
|
167
346
|
paragraphIndex,
|
|
168
|
-
startOffset:
|
|
347
|
+
startOffset: getParagraphContentStartOffset(body, paragraph),
|
|
169
348
|
endOffset: paragraph.startIndex
|
|
170
349
|
};
|
|
171
350
|
}
|
|
@@ -188,6 +367,21 @@ var FDocumentParagraph = class {
|
|
|
188
367
|
};
|
|
189
368
|
}
|
|
190
369
|
/**
|
|
370
|
+
* Returns an agent-friendly facade for reading and styling this paragraph's text.
|
|
371
|
+
* @returns {FDocumentTextRange} The paragraph text range, excluding the trailing paragraph break.
|
|
372
|
+
* @example
|
|
373
|
+
* ```ts
|
|
374
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
375
|
+
* const paragraph = fDocument?.findParagraphByText('Launch');
|
|
376
|
+
* const range = paragraph?.getTextRange();
|
|
377
|
+
* console.log(range?.describe());
|
|
378
|
+
* ```
|
|
379
|
+
*/
|
|
380
|
+
getTextRange() {
|
|
381
|
+
const { startOffset, endOffset } = this.getInfo();
|
|
382
|
+
return this._injector.createInstance(FDocumentTextRange, this._document, startOffset, endOffset, this._segmentId, this._injector);
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
191
385
|
* Get this paragraph's plain text.
|
|
192
386
|
* @returns {string} The paragraph text without the trailing paragraph break.
|
|
193
387
|
* @example
|
|
@@ -240,6 +434,7 @@ var FDocumentParagraph = class {
|
|
|
240
434
|
}
|
|
241
435
|
/**
|
|
242
436
|
* Apply paragraph style to a paragraph handle or text range.
|
|
437
|
+
* `style.textStyle.fs` is a font size in points (pt), not CSS pixels.
|
|
243
438
|
* @param {IParagraphStyle} style The Univer paragraph style patch.
|
|
244
439
|
* @returns {boolean} `true` if the style was applied.
|
|
245
440
|
* @example
|
|
@@ -387,6 +582,412 @@ function isParagraphFacade(value) {
|
|
|
387
582
|
return typeof value.getId === "function" && typeof value.getSegmentId === "function" && typeof value.getInfo === "function" && typeof value.getRange === "function";
|
|
388
583
|
}
|
|
389
584
|
|
|
585
|
+
//#endregion
|
|
586
|
+
//#region src/facade/f-document-section.ts
|
|
587
|
+
/** Error thrown when traditional section APIs are used to mutate a modern document. */
|
|
588
|
+
var DocsSectionUnsupportedDocumentFlavorError = class extends Error {
|
|
589
|
+
constructor() {
|
|
590
|
+
super("Section column APIs are supported only in traditional documents. Use ColumnGroup APIs for modern documents.");
|
|
591
|
+
this.name = "DocsSectionUnsupportedDocumentFlavorError";
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
/**
|
|
595
|
+
* Facade wrapper for an OOXML-compatible traditional document section.
|
|
596
|
+
* Modern documents use ColumnGroup APIs and cannot mutate this facade.
|
|
597
|
+
* @example
|
|
598
|
+
* ```ts
|
|
599
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
600
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
601
|
+
* console.log(fDocument.getSection(0)?.describe());
|
|
602
|
+
* }
|
|
603
|
+
* ```
|
|
604
|
+
*/
|
|
605
|
+
var FDocumentSection = class {
|
|
606
|
+
constructor(_document, _sectionId, _injector) {
|
|
607
|
+
this._document = _document;
|
|
608
|
+
this._sectionId = _sectionId;
|
|
609
|
+
this._injector = _injector;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Returns the persisted section id.
|
|
613
|
+
* @example
|
|
614
|
+
* ```ts
|
|
615
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
616
|
+
* console.log(fDocument?.getSection(0)?.getId());
|
|
617
|
+
* ```
|
|
618
|
+
*/
|
|
619
|
+
getId() {
|
|
620
|
+
return this._sectionId;
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Returns the current zero-based section index.
|
|
624
|
+
* @example
|
|
625
|
+
* ```ts
|
|
626
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
627
|
+
* console.log(fDocument?.getSection(0)?.getIndex());
|
|
628
|
+
* ```
|
|
629
|
+
*/
|
|
630
|
+
getIndex() {
|
|
631
|
+
return this._resolve().index;
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Returns the section break snapshot that terminates this section.
|
|
635
|
+
* @example
|
|
636
|
+
* ```ts
|
|
637
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
638
|
+
* console.log(fDocument?.getSection(0)?.getConfig());
|
|
639
|
+
* ```
|
|
640
|
+
*/
|
|
641
|
+
getConfig() {
|
|
642
|
+
const { sectionBreak } = this._resolve();
|
|
643
|
+
return Tools.deepClone(sectionBreak);
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Returns the section content range, excluding its terminating section-break token.
|
|
647
|
+
* @example
|
|
648
|
+
* ```ts
|
|
649
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
650
|
+
* console.log(fDocument?.getSection(0)?.getRange());
|
|
651
|
+
* ```
|
|
652
|
+
*/
|
|
653
|
+
getRange() {
|
|
654
|
+
const sectionBreaks = getTopLevelSectionBreaks(this._document.getBody());
|
|
655
|
+
const { index, sectionBreak } = this._resolve();
|
|
656
|
+
return {
|
|
657
|
+
startOffset: index === 0 ? 0 : sectionBreaks[index - 1].startIndex + 1,
|
|
658
|
+
endOffset: sectionBreak.startIndex,
|
|
659
|
+
segmentId: ""
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Returns the explicit columns. An empty array means the normal single-column layout.
|
|
664
|
+
* Column widths and trailing spaces are in points (pt).
|
|
665
|
+
* @example
|
|
666
|
+
* ```ts
|
|
667
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
668
|
+
* console.log(fDocument?.getSection(0)?.getColumns());
|
|
669
|
+
* ```
|
|
670
|
+
*/
|
|
671
|
+
getColumns() {
|
|
672
|
+
var _this$getConfig$colum;
|
|
673
|
+
return Tools.deepClone((_this$getConfig$colum = this.getConfig().columnProperties) !== null && _this$getConfig$colum !== void 0 ? _this$getConfig$colum : []);
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Returns a compact serializable section summary.
|
|
677
|
+
* @example
|
|
678
|
+
* ```ts
|
|
679
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
680
|
+
* console.log(fDocument?.getSection(0)?.describe());
|
|
681
|
+
* ```
|
|
682
|
+
*/
|
|
683
|
+
describe() {
|
|
684
|
+
var _config$columnPropert, _config$columnSeparat, _config$sectionType;
|
|
685
|
+
const config = this.getConfig();
|
|
686
|
+
const columns = (_config$columnPropert = config.columnProperties) !== null && _config$columnPropert !== void 0 ? _config$columnPropert : [];
|
|
687
|
+
const headerFooter = {
|
|
688
|
+
defaultHeader: this._describeHeaderFooterReference("header", "default"),
|
|
689
|
+
defaultFooter: this._describeHeaderFooterReference("footer", "default"),
|
|
690
|
+
firstHeader: this._describeHeaderFooterReference("header", "first"),
|
|
691
|
+
firstFooter: this._describeHeaderFooterReference("footer", "first"),
|
|
692
|
+
evenHeader: this._describeHeaderFooterReference("header", "even"),
|
|
693
|
+
evenFooter: this._describeHeaderFooterReference("footer", "even")
|
|
694
|
+
};
|
|
695
|
+
return {
|
|
696
|
+
sectionId: this._sectionId,
|
|
697
|
+
index: this.getIndex(),
|
|
698
|
+
range: this.getRange(),
|
|
699
|
+
columnCount: columns.length || 1,
|
|
700
|
+
columns: Tools.deepClone(columns),
|
|
701
|
+
columnSeparatorType: (_config$columnSeparat = config.columnSeparatorType) !== null && _config$columnSeparat !== void 0 ? _config$columnSeparat : ColumnSeparatorType.NONE,
|
|
702
|
+
sectionType: (_config$sectionType = config.sectionType) !== null && _config$sectionType !== void 0 ? _config$sectionType : SectionType.SECTION_TYPE_UNSPECIFIED,
|
|
703
|
+
headerFooter,
|
|
704
|
+
config
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Sets equal or explicitly sized columns for this traditional section.
|
|
709
|
+
* Use `columnCount = 1` to restore normal single-column layout.
|
|
710
|
+
* `gap` and `widths` are in points (pt).
|
|
711
|
+
* @example
|
|
712
|
+
* ```ts
|
|
713
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
714
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
715
|
+
* fDocument.getSection(0)?.setColumns(2, { gap: 18, separator: true });
|
|
716
|
+
* }
|
|
717
|
+
* ```
|
|
718
|
+
*/
|
|
719
|
+
setColumns(columnCount, options = {}) {
|
|
720
|
+
var _options$gap, _options$separator;
|
|
721
|
+
this._assertTraditionalDocument();
|
|
722
|
+
if (!Number.isInteger(columnCount) || columnCount < 1) throw new RangeError("Section column count must be a positive integer.");
|
|
723
|
+
if (options.widths && options.widths.length !== columnCount) throw new RangeError("Section column widths must match the column count.");
|
|
724
|
+
const gap = Math.max(0, (_options$gap = options.gap) !== null && _options$gap !== void 0 ? _options$gap : 18);
|
|
725
|
+
const config = this.getConfig();
|
|
726
|
+
const columns = createSectionColumnProperties(this._document.getDocumentDataModel().getSnapshot().documentStyle, config, columnCount, gap, options.widths);
|
|
727
|
+
const separator = typeof options.separator === "boolean" ? options.separator ? ColumnSeparatorType.BETWEEN_EACH_COLUMN : ColumnSeparatorType.NONE : (_options$separator = options.separator) !== null && _options$separator !== void 0 ? _options$separator : ColumnSeparatorType.NONE;
|
|
728
|
+
return this._update({
|
|
729
|
+
columnProperties: columns,
|
|
730
|
+
columnSeparatorType: separator,
|
|
731
|
+
...options.sectionType == null ? {} : { sectionType: options.sectionType }
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Sets explicit OOXML-compatible column width and trailing-space values in points (pt).
|
|
736
|
+
* @example
|
|
737
|
+
* ```ts
|
|
738
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
739
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
740
|
+
* fDocument.getSection(0)?.setColumnProperties([
|
|
741
|
+
* { width: 240, paddingEnd: 18 },
|
|
742
|
+
* { width: 240, paddingEnd: 0 },
|
|
743
|
+
* ], univerAPI.Enum.ColumnSeparatorType.BETWEEN_EACH_COLUMN);
|
|
744
|
+
* }
|
|
745
|
+
* ```
|
|
746
|
+
*/
|
|
747
|
+
setColumnProperties(columns, separator = ColumnSeparatorType.NONE) {
|
|
748
|
+
this._assertTraditionalDocument();
|
|
749
|
+
if (columns.some(({ width, paddingEnd }) => width < 0 || paddingEnd < 0)) throw new RangeError("Section column widths and padding must be non-negative.");
|
|
750
|
+
return this._update({
|
|
751
|
+
columnProperties: Tools.deepClone(columns),
|
|
752
|
+
columnSeparatorType: separator
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Sets how the next section begins.
|
|
757
|
+
* @example
|
|
758
|
+
* ```ts
|
|
759
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
760
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
761
|
+
* fDocument.getSection(0)?.setSectionType(univerAPI.Enum.SectionType.NEXT_PAGE);
|
|
762
|
+
* }
|
|
763
|
+
* ```
|
|
764
|
+
*/
|
|
765
|
+
setSectionType(sectionType) {
|
|
766
|
+
this._assertTraditionalDocument();
|
|
767
|
+
return this._update({ sectionType });
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* Ensures a header segment linked specifically to this section.
|
|
771
|
+
* @example
|
|
772
|
+
* ```ts
|
|
773
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
774
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
775
|
+
* const segmentId = fDocument.getSection(0)?.ensureHeader();
|
|
776
|
+
* if (segmentId) {
|
|
777
|
+
* fDocument.insertText(0, 'Quarterly report', segmentId);
|
|
778
|
+
* }
|
|
779
|
+
* }
|
|
780
|
+
* ```
|
|
781
|
+
*/
|
|
782
|
+
ensureHeader(variant = "default") {
|
|
783
|
+
return this._ensureHeaderFooter("header", variant);
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* Ensures a footer segment linked specifically to this section.
|
|
787
|
+
* @example
|
|
788
|
+
* ```ts
|
|
789
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
790
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
791
|
+
* const segmentId = fDocument.getSection(0)?.ensureFooter('first');
|
|
792
|
+
* if (segmentId) {
|
|
793
|
+
* fDocument.insertText(0, 'Confidential', segmentId);
|
|
794
|
+
* }
|
|
795
|
+
* }
|
|
796
|
+
* ```
|
|
797
|
+
*/
|
|
798
|
+
ensureFooter(variant = "default") {
|
|
799
|
+
return this._ensureHeaderFooter("footer", variant);
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Returns the effective header id after resolving links to previous sections.
|
|
803
|
+
* @example
|
|
804
|
+
* ```ts
|
|
805
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
806
|
+
* console.log(fDocument?.getSection(0)?.getHeaderId('default'));
|
|
807
|
+
* ```
|
|
808
|
+
*/
|
|
809
|
+
getHeaderId(variant = "default") {
|
|
810
|
+
var _this$_getHeaderFoote;
|
|
811
|
+
return (_this$_getHeaderFoote = this._getHeaderFooterReference("header", variant).segmentId) !== null && _this$_getHeaderFoote !== void 0 ? _this$_getHeaderFoote : null;
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Returns the effective footer id after resolving links to previous sections.
|
|
815
|
+
* @example
|
|
816
|
+
* ```ts
|
|
817
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
818
|
+
* console.log(fDocument?.getSection(0)?.getFooterId('first'));
|
|
819
|
+
* ```
|
|
820
|
+
*/
|
|
821
|
+
getFooterId(variant = "default") {
|
|
822
|
+
var _this$_getHeaderFoote2;
|
|
823
|
+
return (_this$_getHeaderFoote2 = this._getHeaderFooterReference("footer", variant).segmentId) !== null && _this$_getHeaderFoote2 !== void 0 ? _this$_getHeaderFoote2 : null;
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* Whether this header variant inherits the previous section's reference.
|
|
827
|
+
* @example
|
|
828
|
+
* ```ts
|
|
829
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
830
|
+
* console.log(fDocument?.getSection(1)?.isHeaderLinkedToPrevious());
|
|
831
|
+
* ```
|
|
832
|
+
*/
|
|
833
|
+
isHeaderLinkedToPrevious(variant = "default") {
|
|
834
|
+
return this._getHeaderFooterReference("header", variant).linkedToPrevious;
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* Whether this footer variant inherits the previous section's reference.
|
|
838
|
+
* @example
|
|
839
|
+
* ```ts
|
|
840
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
841
|
+
* console.log(fDocument?.getSection(1)?.isFooterLinkedToPrevious('even'));
|
|
842
|
+
* ```
|
|
843
|
+
*/
|
|
844
|
+
isFooterLinkedToPrevious(variant = "default") {
|
|
845
|
+
return this._getHeaderFooterReference("footer", variant).linkedToPrevious;
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Links or unlinks this header variant. Unlinking clones the inherited header.
|
|
849
|
+
* @example
|
|
850
|
+
* ```ts
|
|
851
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
852
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
853
|
+
* fDocument.getSection(1)?.setHeaderLinkedToPrevious(false, 'default');
|
|
854
|
+
* }
|
|
855
|
+
* ```
|
|
856
|
+
*/
|
|
857
|
+
setHeaderLinkedToPrevious(linkedToPrevious, variant = "default") {
|
|
858
|
+
return this._setHeaderFooterLinkedToPrevious("header", variant, linkedToPrevious);
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Links or unlinks this footer variant. Unlinking clones the inherited footer.
|
|
862
|
+
* @example
|
|
863
|
+
* ```ts
|
|
864
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
865
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
866
|
+
* fDocument.getSection(1)?.setFooterLinkedToPrevious(true, 'even');
|
|
867
|
+
* }
|
|
868
|
+
* ```
|
|
869
|
+
*/
|
|
870
|
+
setFooterLinkedToPrevious(linkedToPrevious, variant = "default") {
|
|
871
|
+
return this._setHeaderFooterLinkedToPrevious("footer", variant, linkedToPrevious);
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* Updates header/footer switches and margins on this section break.
|
|
875
|
+
* `marginHeader` and `marginFooter` are in points (pt).
|
|
876
|
+
* @example
|
|
877
|
+
* ```ts
|
|
878
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
879
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
880
|
+
* fDocument.getSection(0)?.setHeaderFooterOptions({
|
|
881
|
+
* marginHeader: 36,
|
|
882
|
+
* marginFooter: 36,
|
|
883
|
+
* useFirstPageHeaderFooter: univerAPI.Enum.BooleanNumber.TRUE,
|
|
884
|
+
* });
|
|
885
|
+
* }
|
|
886
|
+
* ```
|
|
887
|
+
*/
|
|
888
|
+
setHeaderFooterOptions(options) {
|
|
889
|
+
this._assertTraditionalDocument();
|
|
890
|
+
return this._update(options);
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* Deletes this section break. The final top-level section break cannot be removed.
|
|
894
|
+
* @example
|
|
895
|
+
* ```ts
|
|
896
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
897
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
898
|
+
* const sections = fDocument.getSections();
|
|
899
|
+
* if (sections.length > 1) {
|
|
900
|
+
* sections[0].remove();
|
|
901
|
+
* }
|
|
902
|
+
* }
|
|
903
|
+
* ```
|
|
904
|
+
*/
|
|
905
|
+
remove() {
|
|
906
|
+
this._assertTraditionalDocument();
|
|
907
|
+
return this._injector.get(ICommandService).syncExecuteCommand(DeleteDocumentSectionBreakCommand.id, {
|
|
908
|
+
unitId: this._document.getId(),
|
|
909
|
+
sectionId: this._sectionId
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
_update(patch) {
|
|
913
|
+
const { sectionId: _sectionId, startIndex: _startIndex, ...config } = patch;
|
|
914
|
+
return this._injector.get(ICommandService).syncExecuteCommand(UpdateDocumentSectionCommand.id, {
|
|
915
|
+
unitId: this._document.getId(),
|
|
916
|
+
updates: [{
|
|
917
|
+
sectionId: this._sectionId,
|
|
918
|
+
config
|
|
919
|
+
}]
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
_ensureHeaderFooter(kind, variant) {
|
|
923
|
+
this._assertTraditionalDocument();
|
|
924
|
+
const { index } = this._resolve();
|
|
925
|
+
const existing = this.getConfig()[getSectionHeaderFooterReferenceKey(kind, variant)];
|
|
926
|
+
if (typeof existing === "string" && existing) return existing;
|
|
927
|
+
if (index > 0) {
|
|
928
|
+
const segmentId = generateRandomId(6);
|
|
929
|
+
if (!this._injector.get(ICommandService).syncExecuteCommand(SetSectionHeaderFooterLinkCommand.id, {
|
|
930
|
+
unitId: this._document.getId(),
|
|
931
|
+
sectionId: this._sectionId,
|
|
932
|
+
kind,
|
|
933
|
+
variant,
|
|
934
|
+
linkedToPrevious: false,
|
|
935
|
+
segmentId
|
|
936
|
+
})) throw new Error(`Failed to create section ${kind}.`);
|
|
937
|
+
return segmentId;
|
|
938
|
+
}
|
|
939
|
+
const types = {
|
|
940
|
+
default: kind === "header" ? HeaderFooterType.DEFAULT_HEADER : HeaderFooterType.DEFAULT_FOOTER,
|
|
941
|
+
first: kind === "header" ? HeaderFooterType.FIRST_PAGE_HEADER : HeaderFooterType.FIRST_PAGE_FOOTER,
|
|
942
|
+
even: kind === "header" ? HeaderFooterType.EVEN_PAGE_HEADER : HeaderFooterType.EVEN_PAGE_FOOTER
|
|
943
|
+
};
|
|
944
|
+
const segmentId = generateRandomId(6);
|
|
945
|
+
if (!this._injector.get(ICommandService).syncExecuteCommand(CreateHeaderFooterCommand.id, {
|
|
946
|
+
unitId: this._document.getId(),
|
|
947
|
+
segmentId,
|
|
948
|
+
createType: types[variant],
|
|
949
|
+
sectionId: this._sectionId
|
|
950
|
+
})) throw new Error(`Failed to create section ${kind}.`);
|
|
951
|
+
return segmentId;
|
|
952
|
+
}
|
|
953
|
+
_getHeaderFooterReference(kind, variant) {
|
|
954
|
+
const { index } = this._resolve();
|
|
955
|
+
return resolveSectionHeaderFooterReference(this._document.getDocumentDataModel().getSnapshot().documentStyle, getTopLevelSectionBreaks(this._document.getBody()), index, getSectionHeaderFooterReferenceKey(kind, variant));
|
|
956
|
+
}
|
|
957
|
+
_describeHeaderFooterReference(kind, variant) {
|
|
958
|
+
var _reference$segmentId;
|
|
959
|
+
const reference = this._getHeaderFooterReference(kind, variant);
|
|
960
|
+
return {
|
|
961
|
+
segmentId: (_reference$segmentId = reference.segmentId) !== null && _reference$segmentId !== void 0 ? _reference$segmentId : null,
|
|
962
|
+
linkedToPrevious: reference.linkedToPrevious
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
_setHeaderFooterLinkedToPrevious(kind, variant, linkedToPrevious) {
|
|
966
|
+
this._assertTraditionalDocument();
|
|
967
|
+
return this._injector.get(ICommandService).syncExecuteCommand(SetSectionHeaderFooterLinkCommand.id, {
|
|
968
|
+
unitId: this._document.getId(),
|
|
969
|
+
sectionId: this._sectionId,
|
|
970
|
+
kind,
|
|
971
|
+
variant,
|
|
972
|
+
linkedToPrevious,
|
|
973
|
+
...linkedToPrevious ? {} : { segmentId: generateRandomId(6) }
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
_assertTraditionalDocument() {
|
|
977
|
+
if (this._document.getDocumentDataModel().getSnapshot().documentStyle.documentFlavor !== DocumentFlavor.TRADITIONAL) throw new DocsSectionUnsupportedDocumentFlavorError();
|
|
978
|
+
}
|
|
979
|
+
_resolve() {
|
|
980
|
+
this._assertTraditionalDocument();
|
|
981
|
+
const sectionBreaks = getTopLevelSectionBreaks(this._document.getBody());
|
|
982
|
+
const index = sectionBreaks.findIndex((section) => section.sectionId === this._sectionId);
|
|
983
|
+
if (index < 0) throw new Error(`Document section with id ${this._sectionId} not found.`);
|
|
984
|
+
return {
|
|
985
|
+
index,
|
|
986
|
+
sectionBreak: sectionBreaks[index]
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
};
|
|
990
|
+
|
|
390
991
|
//#endregion
|
|
391
992
|
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/typeof.js
|
|
392
993
|
function _typeof(o) {
|
|
@@ -629,6 +1230,180 @@ let FDocument = class FDocument extends FBaseInitialable {
|
|
|
629
1230
|
}, buildPlainTextInsertBody(text), this._documentDataModel, this._injector);
|
|
630
1231
|
}
|
|
631
1232
|
/**
|
|
1233
|
+
* Returns document-level header/footer switches and margins. Margin values are in points (pt).
|
|
1234
|
+
* @example
|
|
1235
|
+
* ```ts
|
|
1236
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
1237
|
+
* console.log(fDocument?.getHeaderFooterOptions());
|
|
1238
|
+
* ```
|
|
1239
|
+
*/
|
|
1240
|
+
getHeaderFooterOptions() {
|
|
1241
|
+
const style = this._documentDataModel.getSnapshot().documentStyle;
|
|
1242
|
+
return {
|
|
1243
|
+
marginHeader: style.marginHeader,
|
|
1244
|
+
marginFooter: style.marginFooter,
|
|
1245
|
+
useFirstPageHeaderFooter: style.useFirstPageHeaderFooter,
|
|
1246
|
+
evenAndOddHeaders: style.evenAndOddHeaders
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1249
|
+
/**
|
|
1250
|
+
* Updates document-level header/footer switches and margins in a traditional document.
|
|
1251
|
+
* `marginHeader` and `marginFooter` are in points (pt).
|
|
1252
|
+
* @example
|
|
1253
|
+
* ```ts
|
|
1254
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
1255
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
1256
|
+
* fDocument.setHeaderFooterOptions({ marginHeader: 36, marginFooter: 36 });
|
|
1257
|
+
* }
|
|
1258
|
+
* ```
|
|
1259
|
+
*/
|
|
1260
|
+
setHeaderFooterOptions(options) {
|
|
1261
|
+
if (this.isModern()) throw new Error("The document is a modern document, header/footer is not supported.");
|
|
1262
|
+
return this._commandService.syncExecuteCommand(CreateHeaderFooterCommand.id, {
|
|
1263
|
+
unitId: this.getId(),
|
|
1264
|
+
headerFooterProps: options
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
/**
|
|
1268
|
+
* Creates a facade for reading and styling a document text range.
|
|
1269
|
+
* The end offset is exclusive, and offsets are scoped to the selected body segment.
|
|
1270
|
+
* @param {number} startOffset The inclusive start offset.
|
|
1271
|
+
* @param {number} endOffset The exclusive end offset.
|
|
1272
|
+
* @param {string} segmentId The header/footer segment id, or an empty string for the main body.
|
|
1273
|
+
* @returns {FDocumentTextRange} A fixed text-range facade.
|
|
1274
|
+
* @example
|
|
1275
|
+
* ```ts
|
|
1276
|
+
* const range = univerAPI.getActiveDocument()?.getTextRange(0, 5);
|
|
1277
|
+
* console.log(range?.describe());
|
|
1278
|
+
* range?.setTextStyle({ bl: 1 });
|
|
1279
|
+
* ```
|
|
1280
|
+
*/
|
|
1281
|
+
getTextRange(startOffset, endOffset, segmentId = "") {
|
|
1282
|
+
return this._injector.createInstance(FDocumentTextRange, this, startOffset, endOffset, segmentId, this._injector);
|
|
1283
|
+
}
|
|
1284
|
+
/**
|
|
1285
|
+
* Returns traditional document sections backed by persisted SectionBreak ids.
|
|
1286
|
+
* Modern documents use ColumnGroup instead and return an empty array from this read API.
|
|
1287
|
+
* @example
|
|
1288
|
+
* ```ts
|
|
1289
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
1290
|
+
* const sections = fDocument?.getSections() ?? [];
|
|
1291
|
+
* console.log(sections.map((section) => section.describe()));
|
|
1292
|
+
* ```
|
|
1293
|
+
*/
|
|
1294
|
+
getSections() {
|
|
1295
|
+
if (this._documentDataModel.getSnapshot().documentStyle.documentFlavor !== DocumentFlavor.TRADITIONAL) return [];
|
|
1296
|
+
return getTopLevelSectionBreaks(this.getBody()).map((sectionBreak) => this._injector.createInstance(FDocumentSection, this, sectionBreak.sectionId, this._injector));
|
|
1297
|
+
}
|
|
1298
|
+
/**
|
|
1299
|
+
* Returns a traditional section by zero-based index, or `null` in modern documents.
|
|
1300
|
+
* @example
|
|
1301
|
+
* ```ts
|
|
1302
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
1303
|
+
* const firstSection = fDocument?.getSection(0);
|
|
1304
|
+
* console.log(firstSection?.describe());
|
|
1305
|
+
* ```
|
|
1306
|
+
*/
|
|
1307
|
+
getSection(index) {
|
|
1308
|
+
var _this$getSections$ind;
|
|
1309
|
+
return (_this$getSections$ind = this.getSections()[index]) !== null && _this$getSections$ind !== void 0 ? _this$getSections$ind : null;
|
|
1310
|
+
}
|
|
1311
|
+
/**
|
|
1312
|
+
* Returns the traditional section containing a data-stream offset, or `null` in modern documents.
|
|
1313
|
+
* @example
|
|
1314
|
+
* ```ts
|
|
1315
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
1316
|
+
* const paragraph = fDocument?.findParagraphByText('Launch');
|
|
1317
|
+
* const offset = paragraph?.getInfo().startOffset;
|
|
1318
|
+
* const section = offset == null ? null : fDocument?.getSectionAt(offset);
|
|
1319
|
+
* console.log(section?.getId());
|
|
1320
|
+
* ```
|
|
1321
|
+
*/
|
|
1322
|
+
getSectionAt(offset) {
|
|
1323
|
+
var _this$getSections$fin;
|
|
1324
|
+
return (_this$getSections$fin = this.getSections().find((section) => {
|
|
1325
|
+
const range = section.getRange();
|
|
1326
|
+
return offset >= range.startOffset && offset <= range.endOffset;
|
|
1327
|
+
})) !== null && _this$getSections$fin !== void 0 ? _this$getSections$fin : null;
|
|
1328
|
+
}
|
|
1329
|
+
/**
|
|
1330
|
+
* Inserts a traditional document section break and returns its stable facade.
|
|
1331
|
+
* Modern documents must use ColumnGroup and throw `DocsSectionUnsupportedDocumentFlavorError`.
|
|
1332
|
+
* Numeric layout values in `config` are in points (pt).
|
|
1333
|
+
* @example
|
|
1334
|
+
* ```ts
|
|
1335
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
1336
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
1337
|
+
* const paragraph = fDocument.findParagraphByText('Appendix');
|
|
1338
|
+
* const offset = paragraph?.getInfo().startOffset;
|
|
1339
|
+
* const section = offset == null ? null : fDocument.insertSectionBreak(offset);
|
|
1340
|
+
* console.log(section?.getId());
|
|
1341
|
+
* }
|
|
1342
|
+
* ```
|
|
1343
|
+
*/
|
|
1344
|
+
insertSectionBreak(offset, config = {}) {
|
|
1345
|
+
var _this$getBody$section;
|
|
1346
|
+
if (this._documentDataModel.getSnapshot().documentStyle.documentFlavor !== DocumentFlavor.TRADITIONAL) throw new DocsSectionUnsupportedDocumentFlavorError();
|
|
1347
|
+
const sectionId = createSectionId(new Set(((_this$getBody$section = this.getBody().sectionBreaks) !== null && _this$getBody$section !== void 0 ? _this$getBody$section : []).map((section) => section.sectionId)));
|
|
1348
|
+
return this._commandService.syncExecuteCommand(InsertDocumentSectionBreakCommand.id, {
|
|
1349
|
+
unitId: this.getId(),
|
|
1350
|
+
offset,
|
|
1351
|
+
sectionId,
|
|
1352
|
+
config
|
|
1353
|
+
}) ? this._injector.createInstance(FDocumentSection, this, sectionId, this._injector) : null;
|
|
1354
|
+
}
|
|
1355
|
+
/**
|
|
1356
|
+
* Inserts a column-break token in a traditional document.
|
|
1357
|
+
* Modern documents must use ColumnGroup and throw `DocsSectionUnsupportedDocumentFlavorError`.
|
|
1358
|
+
* @example
|
|
1359
|
+
* ```ts
|
|
1360
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
1361
|
+
* if (fDocument && !fDocument.isModern()) {
|
|
1362
|
+
* const paragraph = fDocument.findParagraphByText('Continue in next column');
|
|
1363
|
+
* const offset = paragraph?.getInfo().startOffset;
|
|
1364
|
+
* if (offset != null) {
|
|
1365
|
+
* fDocument.insertColumnBreak(offset);
|
|
1366
|
+
* }
|
|
1367
|
+
* }
|
|
1368
|
+
* ```
|
|
1369
|
+
*/
|
|
1370
|
+
insertColumnBreak(offset) {
|
|
1371
|
+
if (this._documentDataModel.getSnapshot().documentStyle.documentFlavor !== DocumentFlavor.TRADITIONAL) throw new DocsSectionUnsupportedDocumentFlavorError();
|
|
1372
|
+
return this.insertText(offset, DataStreamTreeTokenType.COLUMN_BREAK);
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* Inserts a horizontal rule using the existing paragraph `borderBottom` mechanism.
|
|
1376
|
+
* The returned paragraph can be inspected or removed with normal paragraph APIs.
|
|
1377
|
+
* Border width and padding are in points (pt).
|
|
1378
|
+
* @example
|
|
1379
|
+
* ```ts
|
|
1380
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
1381
|
+
* const paragraph = fDocument?.findParagraphByText('Summary');
|
|
1382
|
+
* const offset = paragraph?.getInfo().startOffset;
|
|
1383
|
+
* const rule = offset == null ? null : fDocument?.insertHorizontalRule(offset);
|
|
1384
|
+
* console.log(rule?.getId());
|
|
1385
|
+
* ```
|
|
1386
|
+
*/
|
|
1387
|
+
insertHorizontalRule(offset, border = {
|
|
1388
|
+
padding: 5,
|
|
1389
|
+
color: { rgb: "#CDD0D8" },
|
|
1390
|
+
width: 1,
|
|
1391
|
+
dashStyle: DashStyleType.SOLID
|
|
1392
|
+
}, segmentId = "") {
|
|
1393
|
+
var _body$paragraphs;
|
|
1394
|
+
const body = this.getBody(segmentId);
|
|
1395
|
+
const paragraphs = generateParagraphs(DataStreamTreeTokenType.PARAGRAPH, void 0, border, (_body$paragraphs = body.paragraphs) === null || _body$paragraphs === void 0 ? void 0 : _body$paragraphs.map((paragraph) => paragraph.paragraphId));
|
|
1396
|
+
const paragraphId = paragraphs[0].paragraphId;
|
|
1397
|
+
return replaceBodyRange({
|
|
1398
|
+
startOffset: offset,
|
|
1399
|
+
endOffset: offset,
|
|
1400
|
+
segmentId
|
|
1401
|
+
}, {
|
|
1402
|
+
dataStream: DataStreamTreeTokenType.PARAGRAPH,
|
|
1403
|
+
paragraphs
|
|
1404
|
+
}, this._documentDataModel, this._injector) ? this.getParagraph(paragraphId, segmentId) : null;
|
|
1405
|
+
}
|
|
1406
|
+
/**
|
|
632
1407
|
* Get all paragraphs in the document body or header/footer body by the segment id.
|
|
633
1408
|
* @param {string} segmentId The segment id of the body. Defaults to an empty string for the main body.
|
|
634
1409
|
* @returns {FDocumentParagraph[]} An array of paragraph facade instances.
|
|
@@ -748,6 +1523,7 @@ let FDocument = class FDocument extends FBaseInitialable {
|
|
|
748
1523
|
/**
|
|
749
1524
|
* Append a plain-text paragraph at the end of the body.
|
|
750
1525
|
* @param {string} text The paragraph text. Defaults to an empty paragraph.
|
|
1526
|
+
* @param {string} segmentId The segment id of the body. Defaults to an empty string for the main body.
|
|
751
1527
|
* @returns {FDocumentParagraph} The appended paragraph wrapper.
|
|
752
1528
|
* @example
|
|
753
1529
|
* ```ts
|
|
@@ -797,10 +1573,11 @@ let FDocument = class FDocument extends FBaseInitialable {
|
|
|
797
1573
|
}
|
|
798
1574
|
_getParagraphInsertOffset(index, segmentId = "") {
|
|
799
1575
|
if (index <= 0) return 0;
|
|
800
|
-
const
|
|
1576
|
+
const body = this.getBody(segmentId);
|
|
1577
|
+
const { dataStream, paragraphs = [] } = body;
|
|
801
1578
|
if (paragraphs.length === 0) return Math.max(0, dataStream.length - 1);
|
|
802
1579
|
if (index >= paragraphs.length) return paragraphs[paragraphs.length - 1].startIndex + 1;
|
|
803
|
-
return paragraphs[index
|
|
1580
|
+
return getParagraphContentStartOffset(body, paragraphs[index]);
|
|
804
1581
|
}
|
|
805
1582
|
_ensureHeaderFooter(kind, pageIndex) {
|
|
806
1583
|
if (this.isModern()) throw new Error("The document is a modern document, header/footer is not supported.");
|
|
@@ -876,4 +1653,31 @@ var FUniverDocsMixin = class extends FUniver {
|
|
|
876
1653
|
FUniver.extend(FUniverDocsMixin);
|
|
877
1654
|
|
|
878
1655
|
//#endregion
|
|
879
|
-
|
|
1656
|
+
//#region src/facade/f-enum.ts
|
|
1657
|
+
/**
|
|
1658
|
+
* Copyright 2023-present DreamNum Co., Ltd.
|
|
1659
|
+
*
|
|
1660
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1661
|
+
* you may not use this file except in compliance with the License.
|
|
1662
|
+
* You may obtain a copy of the License at
|
|
1663
|
+
*
|
|
1664
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1665
|
+
*
|
|
1666
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1667
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1668
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1669
|
+
* See the License for the specific language governing permissions and
|
|
1670
|
+
* limitations under the License.
|
|
1671
|
+
*/
|
|
1672
|
+
var FDocsEnumMixin = class extends FEnum {
|
|
1673
|
+
get SectionType() {
|
|
1674
|
+
return SectionType;
|
|
1675
|
+
}
|
|
1676
|
+
get ColumnSeparatorType() {
|
|
1677
|
+
return ColumnSeparatorType;
|
|
1678
|
+
}
|
|
1679
|
+
};
|
|
1680
|
+
FEnum.extend(FDocsEnumMixin);
|
|
1681
|
+
|
|
1682
|
+
//#endregion
|
|
1683
|
+
export { DocsSectionUnsupportedDocumentFlavorError, FDocsEnumMixin, FDocument, FDocumentParagraph, FDocumentSection, FDocumentTextRange, isParagraphFacade, stripBlockTokens };
|