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