@univerjs/docs 1.0.0-alpha.0 → 1.0.0-alpha.1
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 +834 -1405
- package/lib/cjs/index.js +30 -1
- package/lib/es/facade.js +831 -1400
- package/lib/es/index.js +30 -2
- package/lib/facade.js +831 -1400
- package/lib/index.js +30 -2
- package/lib/types/facade/f-document-block-range.d.ts +132 -0
- package/lib/types/facade/f-document-body.d.ts +276 -0
- package/lib/types/facade/f-document-custom-block.d.ts +57 -0
- package/lib/types/facade/f-document-element.d.ts +193 -0
- package/lib/types/facade/f-document-paragraph.d.ts +231 -0
- package/lib/types/facade/f-document-table.d.ts +57 -0
- package/lib/types/facade/f-document.d.ts +12 -94
- package/lib/types/facade/index.d.ts +6 -8
- package/lib/types/facade/utils.d.ts +2 -4
- package/lib/types/index.d.ts +2 -0
- package/lib/types/services/doc-block-move-validator.service.d.ts +46 -0
- package/lib/umd/facade.js +1 -5
- package/lib/umd/index.js +1 -1
- package/package.json +4 -4
- package/lib/types/facade/doc-element-registry.d.ts +0 -84
- package/lib/types/facade/f-doc-block-range.d.ts +0 -139
- package/lib/types/facade/f-doc-body.d.ts +0 -535
- package/lib/types/facade/f-doc-custom-block.d.ts +0 -94
- package/lib/types/facade/f-doc-element.d.ts +0 -177
- package/lib/types/facade/f-doc-paragraph.d.ts +0 -194
- package/lib/types/facade/f-doc-table.d.ts +0 -94
package/lib/es/facade.js
CHANGED
|
@@ -1,365 +1,244 @@
|
|
|
1
|
-
import { ICommandService, IResourceLoaderService, IUniverInstanceService, Inject, Injector, JSONX, PresetListType, RedoCommand, TextX, TextXActionType, UndoCommand, UniverInstanceType, UpdateDocsAttributeType, createParagraphId, getRichTextEditPath } from "@univerjs/core";
|
|
2
|
-
import { FBaseInitialable, FUniver } from "@univerjs/core/facade";
|
|
3
|
-
import {
|
|
1
|
+
import { DocumentBlockType, ICommandService, IResourceLoaderService, IUniverInstanceService, Inject, Injector, JSONX, PresetListType, RESTORE_INSERTED_PARAGRAPH_IDS, RedoCommand, TextX, TextXActionType, UndoCommand, UniverInstanceType, UpdateDocsAttributeType, createParagraphId, getRichTextEditPath } from "@univerjs/core";
|
|
2
|
+
import { FBase, FBaseInitialable, FUniver } from "@univerjs/core/facade";
|
|
3
|
+
import { RichTextEditingMutation } from "@univerjs/docs";
|
|
4
4
|
|
|
5
|
-
//#region src/facade/
|
|
6
|
-
const PARAGRAPH_REGISTRY_MIGRATION_ERROR = "DocElementRegistry no longer tracks paragraph identity; use paragraphId.";
|
|
5
|
+
//#region src/facade/f-document-element.ts
|
|
7
6
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* A stale paragraph usually means the paragraph was deleted, or the document no
|
|
11
|
-
* longer contains exactly one paragraph with the requested `paragraphId`.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* const doc = univerAPI.getActiveDocument();
|
|
16
|
-
* if (!doc) throw new Error('No active document');
|
|
17
|
-
*
|
|
18
|
-
* const paragraph = doc.getBody().getChild(0).asParagraph();
|
|
19
|
-
* paragraph.removeFromParent();
|
|
20
|
-
*
|
|
21
|
-
* try {
|
|
22
|
-
* paragraph.getText();
|
|
23
|
-
* } catch (error) {
|
|
24
|
-
* if (error instanceof DocElementStaleError) {
|
|
25
|
-
* console.log('The paragraph handle is stale.');
|
|
26
|
-
* }
|
|
27
|
-
* }
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
var DocElementStaleError = class extends Error {
|
|
31
|
-
/**
|
|
32
|
-
* Create a stale element error.
|
|
33
|
-
* @param {string} message The error message.
|
|
34
|
-
*/
|
|
35
|
-
constructor(message = "Doc element is stale") {
|
|
36
|
-
super(message);
|
|
37
|
-
this.name = "DocElementStaleError";
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* @deprecated Paragraph facade identity is now resolved directly from persisted
|
|
42
|
-
* `paragraphId` values. This class remains as a compatibility shell for callers
|
|
43
|
-
* that constructed document facade internals directly.
|
|
7
|
+
* A generic top-level document body element.
|
|
44
8
|
*
|
|
45
|
-
*
|
|
46
|
-
|
|
47
|
-
var DocElementRegistry = class {
|
|
48
|
-
/**
|
|
49
|
-
* @deprecated Paragraph facade identity is now the persisted `paragraphId`.
|
|
50
|
-
* @throws {Error} Always throws; use `paragraph.paragraphId` instead.
|
|
51
|
-
*/
|
|
52
|
-
getParagraphKey(_segmentId, _body, _paragraphIndex) {
|
|
53
|
-
throw new Error(PARAGRAPH_REGISTRY_MIGRATION_ERROR);
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* @deprecated Paragraph facade identity is now the persisted `paragraphId`.
|
|
57
|
-
* @throws {Error} Always throws; resolve paragraph handles by `paragraphId` instead.
|
|
58
|
-
*/
|
|
59
|
-
resolveParagraphStartIndex(_segmentId, _key) {
|
|
60
|
-
throw new Error(PARAGRAPH_REGISTRY_MIGRATION_ERROR);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* @deprecated Paragraph facade identity is now the persisted `paragraphId`.
|
|
64
|
-
* @throws {Error} Always throws; resolve paragraph handles by `paragraphId` instead.
|
|
65
|
-
*/
|
|
66
|
-
syncParagraph(_segmentId, _key, _body) {
|
|
67
|
-
throw new Error(PARAGRAPH_REGISTRY_MIGRATION_ERROR);
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* @deprecated Paragraph facade identity is now the persisted `paragraphId`.
|
|
71
|
-
* @throws {Error} Always throws; stale state is detected from live `paragraphId` lookups.
|
|
72
|
-
*/
|
|
73
|
-
markStale(_segmentId, _key) {
|
|
74
|
-
throw new Error(PARAGRAPH_REGISTRY_MIGRATION_ERROR);
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* @deprecated Paragraph facade identity is now the persisted `paragraphId`.
|
|
78
|
-
* @throws {Error} Always throws; text edits no longer need registry offset tracking.
|
|
79
|
-
*/
|
|
80
|
-
beforeTextEdit(_segmentId, _startOffset, _endOffset, _insertLength) {
|
|
81
|
-
throw new Error(PARAGRAPH_REGISTRY_MIGRATION_ERROR);
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
//#endregion
|
|
86
|
-
//#region src/facade/utils.ts
|
|
87
|
-
function cloneParagraphStyle(paragraphStyle) {
|
|
88
|
-
return paragraphStyle == null ? paragraphStyle : JSON.parse(JSON.stringify(paragraphStyle));
|
|
89
|
-
}
|
|
90
|
-
function normalizePlainTextDataStream(dataStream) {
|
|
91
|
-
return dataStream.replace(/\r\n/g, "\r").replace(/\n/g, "\r");
|
|
92
|
-
}
|
|
93
|
-
function getRemovedLeadingParagraphBreakLength(dataStream, removeLeadingParagraphBreak) {
|
|
94
|
-
const normalized = normalizePlainTextDataStream(dataStream);
|
|
95
|
-
if (removeLeadingParagraphBreak && normalized.length > 1 && normalized.startsWith("\r")) return 1;
|
|
96
|
-
return 0;
|
|
97
|
-
}
|
|
98
|
-
function getNormalizedPlainTextCursorOffset(dataStream, cursorOffset, removeLeadingParagraphBreak) {
|
|
99
|
-
const normalizedPrefixLength = normalizePlainTextDataStream(dataStream.slice(0, cursorOffset)).length;
|
|
100
|
-
return Math.max(0, normalizedPrefixLength - getRemovedLeadingParagraphBreakLength(dataStream, removeLeadingParagraphBreak));
|
|
101
|
-
}
|
|
102
|
-
function getParagraphStyleAtOffset(body, offset) {
|
|
103
|
-
var _body$paragraphs, _paragraphs$find;
|
|
104
|
-
const paragraphs = (_body$paragraphs = body.paragraphs) !== null && _body$paragraphs !== void 0 ? _body$paragraphs : [];
|
|
105
|
-
const paragraph = (_paragraphs$find = paragraphs.find((item) => item.startIndex >= offset)) !== null && _paragraphs$find !== void 0 ? _paragraphs$find : paragraphs[paragraphs.length - 1];
|
|
106
|
-
return paragraph === null || paragraph === void 0 ? void 0 : paragraph.paragraphStyle;
|
|
107
|
-
}
|
|
108
|
-
function buildPlainTextInsertBody(dataStream, options = {}) {
|
|
109
|
-
const normalizedDataStream = normalizePlainTextDataStream(dataStream).slice(getRemovedLeadingParagraphBreakLength(dataStream, options.removeLeadingParagraphBreak));
|
|
110
|
-
const body = {
|
|
111
|
-
dataStream: normalizedDataStream,
|
|
112
|
-
customDecorations: [],
|
|
113
|
-
customRanges: [],
|
|
114
|
-
textRuns: []
|
|
115
|
-
};
|
|
116
|
-
const paragraphs = [];
|
|
117
|
-
const existingParagraphIds = /* @__PURE__ */ new Set();
|
|
118
|
-
for (let index = 0; index < normalizedDataStream.length; index++) if (normalizedDataStream[index] === "\r") paragraphs.push({
|
|
119
|
-
startIndex: index,
|
|
120
|
-
paragraphId: createParagraphId(existingParagraphIds),
|
|
121
|
-
...options.paragraphStyle == null ? {} : { paragraphStyle: cloneParagraphStyle(options.paragraphStyle) }
|
|
122
|
-
});
|
|
123
|
-
if (paragraphs.length > 0) body.paragraphs = paragraphs;
|
|
124
|
-
return body;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
//#endregion
|
|
128
|
-
//#region src/facade/f-doc-block-range.ts
|
|
129
|
-
/**
|
|
130
|
-
* A facade wrapper for document block ranges, such as callout, quote, and code blocks.
|
|
9
|
+
* Use this wrapper when you need to inspect an element type first, navigate to
|
|
10
|
+
* neighboring elements, or cast the element to a more specific facade wrapper.
|
|
131
11
|
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
12
|
+
* Paragraph keys are persisted `paragraphId` values. Tables, block ranges, and
|
|
13
|
+
* custom blocks use their persisted ids.
|
|
134
14
|
*
|
|
135
15
|
* @hideconstructor
|
|
136
16
|
*/
|
|
137
|
-
var
|
|
138
|
-
constructor(_body,
|
|
17
|
+
var FDocumentElement = class extends FBase {
|
|
18
|
+
constructor(_body, _bodyEdit, _info, _injector) {
|
|
19
|
+
super();
|
|
139
20
|
this._body = _body;
|
|
140
|
-
this.
|
|
21
|
+
this._bodyEdit = _bodyEdit;
|
|
22
|
+
this._info = _info;
|
|
23
|
+
this._injector = _injector;
|
|
141
24
|
}
|
|
142
25
|
/**
|
|
143
26
|
* Get the document element type.
|
|
144
|
-
* @returns {
|
|
27
|
+
* @returns {DocumentBlockType} The element type, such as `paragraph`, `table`, `blockRange`, or `customBlock`.
|
|
145
28
|
* @example
|
|
146
29
|
* ```ts
|
|
147
|
-
* const
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* console.log(blockRange.getType());
|
|
30
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
31
|
+
* const fDocumentBody = fDocument.getBody();
|
|
32
|
+
* const element = fDocumentBody.getElement(0);
|
|
33
|
+
* console.log(element?.getType());
|
|
152
34
|
* ```
|
|
153
35
|
*/
|
|
154
36
|
getType() {
|
|
155
|
-
return
|
|
37
|
+
return this._info.type;
|
|
156
38
|
}
|
|
157
39
|
/**
|
|
158
|
-
*
|
|
159
|
-
* @returns {
|
|
40
|
+
* Whether this element is a paragraph.
|
|
41
|
+
* @returns {boolean} `true` if this element is a paragraph.
|
|
160
42
|
* @example
|
|
161
43
|
* ```ts
|
|
162
|
-
* const
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* console.log(blockRange.getKey());
|
|
44
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
45
|
+
* const fDocumentBody = fDocument.getBody();
|
|
46
|
+
* const element = fDocumentBody.getElement(0);
|
|
47
|
+
* console.log(element?.isParagraph());
|
|
167
48
|
* ```
|
|
168
49
|
*/
|
|
169
|
-
|
|
170
|
-
return this.
|
|
50
|
+
isParagraph() {
|
|
51
|
+
return this._info.type === DocumentBlockType.PARAGRAPH;
|
|
171
52
|
}
|
|
172
53
|
/**
|
|
173
|
-
*
|
|
174
|
-
* @returns {
|
|
54
|
+
* Whether this element is a table.
|
|
55
|
+
* @returns {boolean} `true` if this element is a table.
|
|
175
56
|
* @example
|
|
176
57
|
* ```ts
|
|
177
|
-
* const
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* console.log(blockRange.getParent().getChildIndex(blockRange));
|
|
58
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
59
|
+
* const fDocumentBody = fDocument.getBody();
|
|
60
|
+
* const element = fDocumentBody.getElement(0);
|
|
61
|
+
* console.log(element?.isTable());
|
|
182
62
|
* ```
|
|
183
63
|
*/
|
|
184
|
-
|
|
185
|
-
return this.
|
|
64
|
+
isTable() {
|
|
65
|
+
return this._info.type === DocumentBlockType.TABLE;
|
|
186
66
|
}
|
|
187
67
|
/**
|
|
188
|
-
*
|
|
189
|
-
* @returns {boolean} `true` if
|
|
68
|
+
* Whether this element is a block range, such as a callout, quote, or code block.
|
|
69
|
+
* @returns {boolean} `true` if this element is a block range.
|
|
190
70
|
* @example
|
|
191
71
|
* ```ts
|
|
192
|
-
* const
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
* blockRange.removeFromParent();
|
|
72
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
73
|
+
* const fDocumentBody = fDocument.getBody();
|
|
74
|
+
* const element = fDocumentBody.getElement(0);
|
|
75
|
+
* console.log(element?.isBlockRange());
|
|
197
76
|
* ```
|
|
198
77
|
*/
|
|
199
|
-
|
|
200
|
-
return this.
|
|
78
|
+
isBlockRange() {
|
|
79
|
+
return this._info.type === DocumentBlockType.BLOCK_RANGE;
|
|
201
80
|
}
|
|
202
81
|
/**
|
|
203
|
-
*
|
|
204
|
-
* @returns {
|
|
82
|
+
* Whether this element is a custom block.
|
|
83
|
+
* @returns {boolean} `true` if this element is a custom block.
|
|
205
84
|
* @example
|
|
206
85
|
* ```ts
|
|
207
|
-
* const
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
* console.log(blockRange.getBlockType());
|
|
86
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
87
|
+
* const fDocumentBody = fDocument.getBody();
|
|
88
|
+
* const element = fDocumentBody.getElement(0);
|
|
89
|
+
* console.log(element?.isCustomBlock());
|
|
212
90
|
* ```
|
|
213
91
|
*/
|
|
214
|
-
|
|
215
|
-
return this.
|
|
92
|
+
isCustomBlock() {
|
|
93
|
+
return this._info.type === DocumentBlockType.CUSTOM_BLOCK;
|
|
216
94
|
}
|
|
217
95
|
/**
|
|
218
|
-
* Get the
|
|
219
|
-
* @returns {string} The block
|
|
96
|
+
* Get the facade key used to resolve this element.
|
|
97
|
+
* @returns {string} The paragraph `paragraphId` or persisted table/block/custom block id.
|
|
220
98
|
* @example
|
|
221
99
|
* ```ts
|
|
222
|
-
* const
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
* console.log(blockRange.getText());
|
|
100
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
101
|
+
* const fDocumentBody = fDocument.getBody();
|
|
102
|
+
* const element = fDocumentBody.getElement(0);
|
|
103
|
+
* console.log(element?.getKey());
|
|
227
104
|
* ```
|
|
228
105
|
*/
|
|
229
|
-
|
|
230
|
-
return this.
|
|
106
|
+
getKey() {
|
|
107
|
+
return this._info.key;
|
|
231
108
|
}
|
|
232
109
|
/**
|
|
233
|
-
*
|
|
234
|
-
* @
|
|
235
|
-
* @returns {boolean} `true` if the block range text was replaced.
|
|
110
|
+
* Get the parent body facade that owns this element.
|
|
111
|
+
* @returns {FDocumentBody} The document body facade.
|
|
236
112
|
* @example
|
|
237
113
|
* ```ts
|
|
238
|
-
* const
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
* blockRange.setText('Updated block text');
|
|
114
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
115
|
+
* const fDocumentBody = fDocument.getBody();
|
|
116
|
+
* const element = fDocumentBody.getElement(0);
|
|
117
|
+
* console.log(element?.getParent());
|
|
243
118
|
* ```
|
|
244
119
|
*/
|
|
245
|
-
|
|
246
|
-
return this._body
|
|
120
|
+
getParent() {
|
|
121
|
+
return this._body;
|
|
247
122
|
}
|
|
248
123
|
/**
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
* This currently removes the block range and its content, matching
|
|
252
|
-
* `removeFromParent()`.
|
|
253
|
-
*
|
|
254
|
-
* @returns {boolean} `true` if the block range content was removed.
|
|
124
|
+
* Get the resolved element info for this wrapper.
|
|
125
|
+
* @returns {IFDocumentElementInfo} The resolved element info, including type, key, position, and priority.
|
|
255
126
|
* @example
|
|
256
127
|
* ```ts
|
|
257
|
-
* const
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
* blockRange.unwrap();
|
|
128
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
129
|
+
* const fDocumentBody = fDocument.getBody();
|
|
130
|
+
* const element = fDocumentBody.getElement(0);
|
|
131
|
+
* console.log(element?.getResolvedInfo());
|
|
262
132
|
* ```
|
|
263
133
|
*/
|
|
264
|
-
|
|
265
|
-
return this.
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
//#endregion
|
|
270
|
-
//#region src/facade/f-doc-custom-block.ts
|
|
271
|
-
/**
|
|
272
|
-
* A facade wrapper for a document custom block, such as an embedded drawing or widget.
|
|
273
|
-
*
|
|
274
|
-
* Custom block identity is backed by the persisted `ICustomBlock.blockId`, so the
|
|
275
|
-
* wrapper can be re-resolved after text is inserted before the custom block.
|
|
276
|
-
*
|
|
277
|
-
* @hideconstructor
|
|
278
|
-
*/
|
|
279
|
-
var FDocCustomBlock = class {
|
|
280
|
-
constructor(_body, _key) {
|
|
281
|
-
this._body = _body;
|
|
282
|
-
this._key = _key;
|
|
134
|
+
getResolvedInfo() {
|
|
135
|
+
return this._info;
|
|
283
136
|
}
|
|
284
137
|
/**
|
|
285
|
-
* Get the
|
|
286
|
-
* @returns {
|
|
138
|
+
* Get the next sibling element in the current body order.
|
|
139
|
+
* @returns {FDocumentElement | null} The next sibling wrapper, or `null` when this is the last child.
|
|
287
140
|
* @example
|
|
288
141
|
* ```ts
|
|
289
|
-
* const
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
* console.log(customBlock.getType());
|
|
142
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
143
|
+
* const fDocumentBody = fDocument.getBody();
|
|
144
|
+
* const element = fDocumentBody.getElement(0);
|
|
145
|
+
* console.log(element?.getNextSibling());
|
|
294
146
|
* ```
|
|
295
147
|
*/
|
|
296
|
-
|
|
297
|
-
return
|
|
148
|
+
getNextSibling() {
|
|
149
|
+
return this._createSibling(1);
|
|
298
150
|
}
|
|
299
151
|
/**
|
|
300
|
-
* Get the
|
|
301
|
-
* @returns {
|
|
152
|
+
* Get the previous sibling element in the current body order.
|
|
153
|
+
* @returns {FDocumentElement | null} The previous sibling wrapper, or `null` when this is the first child.
|
|
302
154
|
* @example
|
|
303
155
|
* ```ts
|
|
304
|
-
* const
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
* console.log(customBlock.getKey());
|
|
156
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
157
|
+
* const fDocumentBody = fDocument.getBody();
|
|
158
|
+
* const element = fDocumentBody.getElement(1);
|
|
159
|
+
* console.log(element?.getPreviousSibling());
|
|
309
160
|
* ```
|
|
310
161
|
*/
|
|
311
|
-
|
|
312
|
-
return this.
|
|
162
|
+
getPreviousSibling() {
|
|
163
|
+
return this._createSibling(-1);
|
|
313
164
|
}
|
|
314
165
|
/**
|
|
315
|
-
* Get the
|
|
316
|
-
* @
|
|
166
|
+
* Get the sibling element at a relative offset from this element.
|
|
167
|
+
* @param {number} offset The relative offset from this element. Use `1` for the next sibling, `-1` for the previous sibling, and so on.
|
|
168
|
+
* @returns {FDocumentElement | null} The sibling wrapper at the specified offset, or `null` when the offset is out of range.
|
|
317
169
|
* @example
|
|
318
170
|
* ```ts
|
|
319
|
-
* const
|
|
320
|
-
*
|
|
171
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
172
|
+
* const fDocumentBody = fDocument.getBody();
|
|
173
|
+
* const element = fDocumentBody.getElement(0);
|
|
321
174
|
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
175
|
+
* // Get the third sibling after this element
|
|
176
|
+
* const nextThirdSibling = element?.getSibling(3);
|
|
177
|
+
* console.log(nextThirdSibling?.getType());
|
|
324
178
|
* ```
|
|
325
179
|
*/
|
|
326
|
-
|
|
327
|
-
return this.
|
|
180
|
+
getSibling(offset) {
|
|
181
|
+
return this._createSibling(offset);
|
|
328
182
|
}
|
|
329
183
|
/**
|
|
330
|
-
* Remove this
|
|
331
|
-
* @returns {boolean} `true` if the
|
|
184
|
+
* Remove this element from its parent body.
|
|
185
|
+
* @returns {boolean} `true` if the element content was removed.
|
|
332
186
|
* @example
|
|
333
187
|
* ```ts
|
|
334
|
-
* const
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
* const
|
|
338
|
-
*
|
|
188
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
189
|
+
* const fDocumentBody = fDocument.getBody();
|
|
190
|
+
* const element = fDocumentBody.getElement(0);
|
|
191
|
+
* const removed = element?.remove();
|
|
192
|
+
* console.log(removed);
|
|
339
193
|
* ```
|
|
340
194
|
*/
|
|
341
|
-
|
|
342
|
-
return this._body.
|
|
195
|
+
remove() {
|
|
196
|
+
if (this.isParagraph()) return this._body.removeParagraph(this.asParagraph());
|
|
197
|
+
if (this.isBlockRange()) return this._body.removeBlockRange(this.asBlockRange());
|
|
198
|
+
if (this.isTable()) return this._body.removeTable(this.asTable());
|
|
199
|
+
return this._body.removeCustomBlock(this.asCustomBlock());
|
|
343
200
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
* ```ts
|
|
349
|
-
* const doc = univerAPI.getActiveDocument();
|
|
350
|
-
* if (!doc) throw new Error('No active document');
|
|
351
|
-
*
|
|
352
|
-
* const customBlock = doc.getBody().getChild(0).asCustomBlock();
|
|
353
|
-
* console.log(customBlock.getBlockId());
|
|
354
|
-
* ```
|
|
355
|
-
*/
|
|
356
|
-
getBlockId() {
|
|
357
|
-
return this._body.getCustomBlock(this._key).blockId;
|
|
201
|
+
_createSibling(offset) {
|
|
202
|
+
if (offset === 0) throw new Error("Offset cannot be zero.");
|
|
203
|
+
const index = this._body.getElementIndex(this);
|
|
204
|
+
return this._body.getElement(index + offset);
|
|
358
205
|
}
|
|
359
206
|
};
|
|
360
207
|
|
|
361
208
|
//#endregion
|
|
362
|
-
//#region src/facade/
|
|
209
|
+
//#region src/facade/utils.ts
|
|
210
|
+
function cloneParagraphStyle(paragraphStyle) {
|
|
211
|
+
return paragraphStyle == null ? paragraphStyle : JSON.parse(JSON.stringify(paragraphStyle));
|
|
212
|
+
}
|
|
213
|
+
function normalizePlainTextDataStream(dataStream) {
|
|
214
|
+
return dataStream.replace(/\r\n/g, "\r").replace(/\n/g, "\r");
|
|
215
|
+
}
|
|
216
|
+
function getRemovedLeadingParagraphBreakLength(dataStream, removeLeadingParagraphBreak) {
|
|
217
|
+
const normalized = normalizePlainTextDataStream(dataStream);
|
|
218
|
+
if (removeLeadingParagraphBreak && normalized.length > 1 && normalized.startsWith("\r")) return 1;
|
|
219
|
+
return 0;
|
|
220
|
+
}
|
|
221
|
+
function buildPlainTextInsertBody(dataStream, options = {}) {
|
|
222
|
+
const normalizedDataStream = normalizePlainTextDataStream(dataStream).slice(getRemovedLeadingParagraphBreakLength(dataStream, options.removeLeadingParagraphBreak));
|
|
223
|
+
const body = {
|
|
224
|
+
dataStream: normalizedDataStream,
|
|
225
|
+
customDecorations: [],
|
|
226
|
+
customRanges: [],
|
|
227
|
+
textRuns: []
|
|
228
|
+
};
|
|
229
|
+
const paragraphs = [];
|
|
230
|
+
const existingParagraphIds = /* @__PURE__ */ new Set();
|
|
231
|
+
for (let index = 0; index < normalizedDataStream.length; index++) if (normalizedDataStream[index] === "\r") paragraphs.push({
|
|
232
|
+
startIndex: index,
|
|
233
|
+
paragraphId: createParagraphId(existingParagraphIds),
|
|
234
|
+
...options.paragraphStyle == null ? {} : { paragraphStyle: cloneParagraphStyle(options.paragraphStyle) }
|
|
235
|
+
});
|
|
236
|
+
if (paragraphs.length > 0) body.paragraphs = paragraphs;
|
|
237
|
+
return body;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
//#endregion
|
|
241
|
+
//#region src/facade/f-document-paragraph.ts
|
|
363
242
|
/**
|
|
364
243
|
* A paragraph facade wrapper.
|
|
365
244
|
*
|
|
@@ -369,100 +248,107 @@ var FDocCustomBlock = class {
|
|
|
369
248
|
*
|
|
370
249
|
* @hideconstructor
|
|
371
250
|
*/
|
|
372
|
-
var
|
|
373
|
-
constructor(
|
|
374
|
-
|
|
375
|
-
this.
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
* @example
|
|
381
|
-
* ```ts
|
|
382
|
-
* const doc = univerAPI.getActiveDocument();
|
|
383
|
-
* if (!doc) throw new Error('No active document');
|
|
384
|
-
*
|
|
385
|
-
* const paragraph = doc.getBody().getChild(0).asParagraph();
|
|
386
|
-
* console.log(paragraph.getType());
|
|
387
|
-
* ```
|
|
388
|
-
*/
|
|
389
|
-
getType() {
|
|
390
|
-
return "paragraph";
|
|
391
|
-
}
|
|
392
|
-
/**
|
|
393
|
-
* Get the persisted paragraph id.
|
|
394
|
-
* @returns {string} The paragraph id.
|
|
395
|
-
* @example
|
|
396
|
-
* ```ts
|
|
397
|
-
* const doc = univerAPI.getActiveDocument();
|
|
398
|
-
* if (!doc) throw new Error('No active document');
|
|
399
|
-
*
|
|
400
|
-
* const paragraph = doc.getBody().getChild(0).asParagraph();
|
|
401
|
-
* console.log(paragraph.getKey());
|
|
402
|
-
* ```
|
|
403
|
-
*/
|
|
404
|
-
getKey() {
|
|
405
|
-
return this._key;
|
|
251
|
+
var FDocumentParagraph = class extends FDocumentElement {
|
|
252
|
+
constructor(body, bodyEdit, info, injector) {
|
|
253
|
+
super(body, bodyEdit, info, injector);
|
|
254
|
+
this.body = body;
|
|
255
|
+
this.bodyEdit = bodyEdit;
|
|
256
|
+
this.info = info;
|
|
257
|
+
this.injector = injector;
|
|
258
|
+
if (this.getType() !== DocumentBlockType.PARAGRAPH) throw new Error(`Element type is not a paragraph: ${this.getType()}`);
|
|
406
259
|
}
|
|
407
260
|
/**
|
|
408
261
|
* Get the persisted paragraph id.
|
|
409
262
|
* @returns {string} The paragraph id.
|
|
410
263
|
* @example
|
|
411
264
|
* ```ts
|
|
412
|
-
* const
|
|
413
|
-
*
|
|
265
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
266
|
+
* const fDocumentBody = fDocument.getBody();
|
|
267
|
+
* const element = fDocumentBody.getElement(0);
|
|
414
268
|
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
269
|
+
* if (element?.isParagraph()) {
|
|
270
|
+
* const paragraph = element.asParagraph();
|
|
271
|
+
* console.log(paragraph.getParagraphId());
|
|
272
|
+
* }
|
|
417
273
|
* ```
|
|
418
274
|
*/
|
|
419
|
-
|
|
420
|
-
return this.
|
|
275
|
+
getParagraphId() {
|
|
276
|
+
return this.getKey();
|
|
421
277
|
}
|
|
422
278
|
/**
|
|
423
|
-
* Get the
|
|
424
|
-
* @returns {
|
|
279
|
+
* Get the resolved paragraph info for this wrapper.
|
|
280
|
+
* @returns {IFDocumentResolvedParagraph} The resolved paragraph info, including the paragraph object, its index, and its text range.
|
|
425
281
|
* @example
|
|
426
282
|
* ```ts
|
|
427
|
-
* const
|
|
428
|
-
*
|
|
283
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
284
|
+
* const fDocumentBody = fDocument.getBody();
|
|
285
|
+
* const element = fDocumentBody.getElement(0);
|
|
429
286
|
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
287
|
+
* if (element?.isParagraph()) {
|
|
288
|
+
* const paragraph = element.asParagraph();
|
|
289
|
+
* console.log(paragraph.getResolvedParagraphInfo());
|
|
290
|
+
* }
|
|
432
291
|
* ```
|
|
433
292
|
*/
|
|
434
|
-
|
|
435
|
-
|
|
293
|
+
getResolvedParagraphInfo() {
|
|
294
|
+
const { paragraphs = [] } = this._body.getBody();
|
|
295
|
+
const matches = paragraphs.map((paragraph, paragraphIndex) => ({
|
|
296
|
+
paragraph,
|
|
297
|
+
paragraphIndex
|
|
298
|
+
})).filter(({ paragraph }) => paragraph.paragraphId === this.getKey());
|
|
299
|
+
if (matches.length === 0) throw new Error(`Document paragraph with id ${this.getKey()} not found`);
|
|
300
|
+
if (matches.length > 1) throw new Error(`Multiple document paragraphs with id ${this.getKey()} found`);
|
|
301
|
+
const { paragraph, paragraphIndex } = matches[0];
|
|
302
|
+
return {
|
|
303
|
+
paragraph,
|
|
304
|
+
paragraphIndex,
|
|
305
|
+
startOffset: paragraphIndex > 0 ? paragraphs[paragraphIndex - 1].startIndex + 1 : 0,
|
|
306
|
+
endOffset: paragraph.startIndex
|
|
307
|
+
};
|
|
436
308
|
}
|
|
437
309
|
/**
|
|
438
|
-
*
|
|
439
|
-
* @returns {
|
|
310
|
+
* Get the current text range occupied by this paragraph.
|
|
311
|
+
* @returns {IFDocumentTextRange} The paragraph text range, excluding the trailing paragraph break.
|
|
440
312
|
* @example
|
|
441
313
|
* ```ts
|
|
442
|
-
* const
|
|
443
|
-
*
|
|
314
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
315
|
+
* const fDocumentBody = fDocument.getBody();
|
|
316
|
+
* const element = fDocumentBody.getElement(0);
|
|
444
317
|
*
|
|
445
|
-
*
|
|
446
|
-
* paragraph.
|
|
318
|
+
* if (element?.isParagraph()) {
|
|
319
|
+
* const paragraph = element.asParagraph();
|
|
320
|
+
* const range = paragraph.getRange();
|
|
321
|
+
* fDocumentBody.setTextStyle(range, { bl: 1 });
|
|
322
|
+
* }
|
|
447
323
|
* ```
|
|
448
324
|
*/
|
|
449
|
-
|
|
450
|
-
|
|
325
|
+
getRange() {
|
|
326
|
+
const { startOffset, endOffset } = this.getResolvedParagraphInfo();
|
|
327
|
+
return {
|
|
328
|
+
startOffset,
|
|
329
|
+
endOffset,
|
|
330
|
+
segmentId: this._body.getSegmentId()
|
|
331
|
+
};
|
|
451
332
|
}
|
|
452
333
|
/**
|
|
453
334
|
* Get this paragraph's plain text.
|
|
454
335
|
* @returns {string} The paragraph text without the trailing paragraph break.
|
|
455
336
|
* @example
|
|
456
337
|
* ```ts
|
|
457
|
-
* const
|
|
458
|
-
*
|
|
338
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
339
|
+
* const fDocumentBody = fDocument.getBody();
|
|
340
|
+
* const element = fDocumentBody.getElement(0);
|
|
459
341
|
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
342
|
+
* if (element?.isParagraph()) {
|
|
343
|
+
* const paragraph = element.asParagraph();
|
|
344
|
+
* console.log(paragraph.getText());
|
|
345
|
+
* }
|
|
462
346
|
* ```
|
|
463
347
|
*/
|
|
464
348
|
getText() {
|
|
465
|
-
|
|
349
|
+
const { dataStream } = this._body.getBody();
|
|
350
|
+
const { startOffset, endOffset } = this.getResolvedParagraphInfo();
|
|
351
|
+
return dataStream.slice(startOffset, endOffset);
|
|
466
352
|
}
|
|
467
353
|
/**
|
|
468
354
|
* Replace this paragraph's plain text.
|
|
@@ -470,15 +356,23 @@ var FDocParagraph = class {
|
|
|
470
356
|
* @returns {boolean} `true` if the paragraph text was replaced.
|
|
471
357
|
* @example
|
|
472
358
|
* ```ts
|
|
473
|
-
* const
|
|
474
|
-
*
|
|
359
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
360
|
+
* const fDocumentBody = fDocument.getBody();
|
|
361
|
+
* const element = fDocumentBody.getElement(0);
|
|
475
362
|
*
|
|
476
|
-
*
|
|
477
|
-
* paragraph.
|
|
363
|
+
* if (element?.isParagraph()) {
|
|
364
|
+
* const paragraph = element.asParagraph();
|
|
365
|
+
* const success = paragraph.setText('Updated title');
|
|
366
|
+
* console.log(success ? 'Text updated' : 'Failed to update text');
|
|
367
|
+
* }
|
|
478
368
|
* ```
|
|
479
369
|
*/
|
|
480
370
|
setText(text) {
|
|
481
|
-
|
|
371
|
+
const { startOffset, endOffset } = this.getResolvedParagraphInfo();
|
|
372
|
+
return this._bodyEdit.replaceRange({
|
|
373
|
+
startOffset,
|
|
374
|
+
endOffset
|
|
375
|
+
}, buildPlainTextInsertBody(text));
|
|
482
376
|
}
|
|
483
377
|
/**
|
|
484
378
|
* Append plain text before this paragraph's trailing paragraph break.
|
|
@@ -486,63 +380,95 @@ var FDocParagraph = class {
|
|
|
486
380
|
* @returns {boolean} `true` if the text was appended.
|
|
487
381
|
* @example
|
|
488
382
|
* ```ts
|
|
489
|
-
* const
|
|
490
|
-
*
|
|
383
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
384
|
+
* const fDocumentBody = fDocument.getBody();
|
|
385
|
+
* const element = fDocumentBody.getElement(0);
|
|
491
386
|
*
|
|
492
|
-
*
|
|
493
|
-
* paragraph.
|
|
387
|
+
* if (element?.isParagraph()) {
|
|
388
|
+
* const paragraph = element.asParagraph();
|
|
389
|
+
* const success = paragraph.appendText(' Appended text');
|
|
390
|
+
* console.log(success ? 'Text appended' : 'Failed to append text');
|
|
391
|
+
* }
|
|
494
392
|
* ```
|
|
495
393
|
*/
|
|
496
394
|
appendText(text) {
|
|
497
|
-
|
|
395
|
+
const { endOffset } = this.getResolvedParagraphInfo();
|
|
396
|
+
return this._body.insertText(endOffset, text);
|
|
498
397
|
}
|
|
499
398
|
/**
|
|
500
|
-
*
|
|
501
|
-
* @
|
|
399
|
+
* Apply paragraph style to a paragraph handle or text range.
|
|
400
|
+
* @param {IParagraphStyle} style The Univer paragraph style patch.
|
|
401
|
+
* @returns {boolean} `true` if the style was applied.
|
|
502
402
|
* @example
|
|
503
403
|
* ```ts
|
|
504
|
-
* const
|
|
505
|
-
*
|
|
404
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
405
|
+
* const fDocumentBody = fDocument.getBody();
|
|
406
|
+
* const element = fDocumentBody.getElement(0);
|
|
506
407
|
*
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
408
|
+
* if (element?.isParagraph()) {
|
|
409
|
+
* const paragraph = element.asParagraph();
|
|
410
|
+
* paragraph.setStyle({ horizontalAlign: 2 });
|
|
411
|
+
* }
|
|
510
412
|
* ```
|
|
511
413
|
*/
|
|
512
|
-
|
|
513
|
-
|
|
414
|
+
setStyle(style) {
|
|
415
|
+
const { paragraph, endOffset } = this.getResolvedParagraphInfo();
|
|
416
|
+
const updateBody = {
|
|
417
|
+
dataStream: "",
|
|
418
|
+
paragraphs: [{
|
|
419
|
+
...paragraph,
|
|
420
|
+
startIndex: 0,
|
|
421
|
+
paragraphStyle: {
|
|
422
|
+
...paragraph.paragraphStyle,
|
|
423
|
+
...style
|
|
424
|
+
}
|
|
425
|
+
}]
|
|
426
|
+
};
|
|
427
|
+
this._preserveExplicitParagraphIds(updateBody);
|
|
428
|
+
return this._bodyEdit.retainRange({
|
|
429
|
+
startOffset: endOffset,
|
|
430
|
+
endOffset: endOffset + 1
|
|
431
|
+
}, updateBody, UpdateDocsAttributeType.REPLACE);
|
|
514
432
|
}
|
|
515
433
|
/**
|
|
516
434
|
* Check whether this paragraph is a bullet, ordered, or checklist item.
|
|
517
435
|
* @returns {boolean} `true` if the paragraph has list metadata.
|
|
518
436
|
* @example
|
|
519
437
|
* ```ts
|
|
520
|
-
* const
|
|
521
|
-
*
|
|
438
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
439
|
+
* const fDocumentBody = fDocument.getBody();
|
|
440
|
+
* const element = fDocumentBody.getElement(0);
|
|
522
441
|
*
|
|
523
|
-
*
|
|
524
|
-
*
|
|
442
|
+
* if (element?.isParagraph()) {
|
|
443
|
+
* const paragraph = element.asParagraph();
|
|
444
|
+
* console.log(paragraph.isListItem() ? 'This is a list item' : 'This is not a list item');
|
|
445
|
+
* }
|
|
525
446
|
* ```
|
|
526
447
|
*/
|
|
527
448
|
isListItem() {
|
|
528
|
-
|
|
449
|
+
const { paragraph } = this.getResolvedParagraphInfo();
|
|
450
|
+
return Boolean(paragraph.bullet);
|
|
529
451
|
}
|
|
530
452
|
/**
|
|
531
453
|
* Check whether this paragraph is a task/checklist item.
|
|
532
454
|
* @returns {boolean} `true` if this paragraph is an unchecked or checked task item.
|
|
533
455
|
* @example
|
|
534
456
|
* ```ts
|
|
535
|
-
* const
|
|
536
|
-
*
|
|
457
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
458
|
+
* const fDocumentBody = fDocument.getBody();
|
|
459
|
+
* const element = fDocumentBody.getElement(0);
|
|
537
460
|
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
461
|
+
* if (element?.isParagraph()) {
|
|
462
|
+
* const paragraph = element.asParagraph();
|
|
463
|
+
* console.log(paragraph.isTask() ? 'This is a task item' : 'This is not a task item');
|
|
541
464
|
* }
|
|
542
465
|
* ```
|
|
543
466
|
*/
|
|
544
467
|
isTask() {
|
|
545
|
-
|
|
468
|
+
var _paragraph$bullet;
|
|
469
|
+
const { paragraph } = this.getResolvedParagraphInfo();
|
|
470
|
+
const listType = (_paragraph$bullet = paragraph.bullet) === null || _paragraph$bullet === void 0 ? void 0 : _paragraph$bullet.listType;
|
|
471
|
+
return listType === PresetListType.CHECK_LIST || listType === PresetListType.CHECK_LIST_CHECKED;
|
|
546
472
|
}
|
|
547
473
|
/**
|
|
548
474
|
* Set the checked state of this task/checklist paragraph.
|
|
@@ -550,377 +476,196 @@ var FDocParagraph = class {
|
|
|
550
476
|
* @returns {boolean} `true` if the task state was updated, or `false` if this paragraph is not a task item.
|
|
551
477
|
* @example
|
|
552
478
|
* ```ts
|
|
553
|
-
* const
|
|
554
|
-
*
|
|
479
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
480
|
+
* const fDocumentBody = fDocument.getBody();
|
|
481
|
+
* const element = fDocumentBody.getElement(0);
|
|
482
|
+
*
|
|
483
|
+
* if (element?.isParagraph()) {
|
|
484
|
+
* const paragraph = element.asParagraph();
|
|
555
485
|
*
|
|
556
|
-
*
|
|
557
|
-
*
|
|
558
|
-
*
|
|
486
|
+
* if (paragraph.isTask()) {
|
|
487
|
+
* const success = paragraph.setTaskChecked(true);
|
|
488
|
+
* console.log(success ? 'Task checked' : 'Failed to check task');
|
|
489
|
+
* }
|
|
559
490
|
* }
|
|
560
491
|
* ```
|
|
561
492
|
*/
|
|
562
493
|
setTaskChecked(checked) {
|
|
563
|
-
|
|
494
|
+
if (!this.isTask()) return false;
|
|
495
|
+
const { paragraph, endOffset } = this.getResolvedParagraphInfo();
|
|
496
|
+
const bullet = paragraph.bullet;
|
|
497
|
+
const updateBody = {
|
|
498
|
+
dataStream: "",
|
|
499
|
+
paragraphs: [{
|
|
500
|
+
...paragraph,
|
|
501
|
+
startIndex: 0,
|
|
502
|
+
bullet: {
|
|
503
|
+
...bullet,
|
|
504
|
+
listType: checked ? PresetListType.CHECK_LIST_CHECKED : PresetListType.CHECK_LIST
|
|
505
|
+
}
|
|
506
|
+
}]
|
|
507
|
+
};
|
|
508
|
+
this._preserveExplicitParagraphIds(updateBody);
|
|
509
|
+
return this._bodyEdit.retainRange({
|
|
510
|
+
startOffset: endOffset,
|
|
511
|
+
endOffset: endOffset + 1
|
|
512
|
+
}, updateBody, UpdateDocsAttributeType.REPLACE);
|
|
513
|
+
}
|
|
514
|
+
_preserveExplicitParagraphIds(body) {
|
|
515
|
+
body[RESTORE_INSERTED_PARAGRAPH_IDS] = true;
|
|
564
516
|
}
|
|
565
517
|
};
|
|
518
|
+
var FDocumentParagraphMixin = class extends FDocumentElement {
|
|
519
|
+
asParagraph() {
|
|
520
|
+
if (this.getType() !== DocumentBlockType.PARAGRAPH) throw new Error(`Element type is not a paragraph: ${this.getType()}`);
|
|
521
|
+
return this._injector.createInstance(FDocumentParagraph, this._body, this._bodyEdit, this.getResolvedInfo(), this._injector);
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
FDocumentElement.extend(FDocumentParagraphMixin);
|
|
566
525
|
|
|
567
526
|
//#endregion
|
|
568
|
-
//#region
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
* const doc = univerAPI.getActiveDocument();
|
|
588
|
-
* if (!doc) throw new Error('No active document');
|
|
589
|
-
*
|
|
590
|
-
* const table = doc.getBody().getChild(0).asTable();
|
|
591
|
-
* console.log(table.getType());
|
|
592
|
-
* ```
|
|
593
|
-
*/
|
|
594
|
-
getType() {
|
|
595
|
-
return "table";
|
|
596
|
-
}
|
|
597
|
-
/**
|
|
598
|
-
* Get the table key.
|
|
599
|
-
* @returns {string} The persisted `tableId` for this table.
|
|
600
|
-
* @example
|
|
601
|
-
* ```ts
|
|
602
|
-
* const doc = univerAPI.getActiveDocument();
|
|
603
|
-
* if (!doc) throw new Error('No active document');
|
|
604
|
-
*
|
|
605
|
-
* const table = doc.getBody().getChild(0).asTable();
|
|
606
|
-
* console.log(table.getKey());
|
|
607
|
-
* ```
|
|
608
|
-
*/
|
|
609
|
-
getKey() {
|
|
610
|
-
return this._key;
|
|
611
|
-
}
|
|
612
|
-
/**
|
|
613
|
-
* Get the parent body facade that owns this table.
|
|
614
|
-
* @returns {FDocBody} The document body facade.
|
|
615
|
-
* @example
|
|
616
|
-
* ```ts
|
|
617
|
-
* const doc = univerAPI.getActiveDocument();
|
|
618
|
-
* if (!doc) throw new Error('No active document');
|
|
619
|
-
*
|
|
620
|
-
* const table = doc.getBody().getChild(0).asTable();
|
|
621
|
-
* console.log(table.getParent().getChildIndex(table));
|
|
622
|
-
* ```
|
|
623
|
-
*/
|
|
624
|
-
getParent() {
|
|
625
|
-
return this._body;
|
|
626
|
-
}
|
|
627
|
-
/**
|
|
628
|
-
* Remove this table from the parent body.
|
|
629
|
-
* @returns {boolean} `true` if the table range was removed.
|
|
630
|
-
* @example
|
|
631
|
-
* ```ts
|
|
632
|
-
* const doc = univerAPI.getActiveDocument();
|
|
633
|
-
* if (!doc) throw new Error('No active document');
|
|
634
|
-
*
|
|
635
|
-
* const table = doc.getBody().getChild(0).asTable();
|
|
636
|
-
* table.removeFromParent();
|
|
637
|
-
* ```
|
|
638
|
-
*/
|
|
639
|
-
removeFromParent() {
|
|
640
|
-
return this._body.removeTable(this._key);
|
|
641
|
-
}
|
|
642
|
-
/**
|
|
643
|
-
* Get the persisted table id.
|
|
644
|
-
* @returns {string} The `ICustomTable.tableId` value.
|
|
645
|
-
* @example
|
|
646
|
-
* ```ts
|
|
647
|
-
* const doc = univerAPI.getActiveDocument();
|
|
648
|
-
* if (!doc) throw new Error('No active document');
|
|
649
|
-
*
|
|
650
|
-
* const table = doc.getBody().getChild(0).asTable();
|
|
651
|
-
* console.log(table.getTableId());
|
|
652
|
-
* ```
|
|
653
|
-
*/
|
|
654
|
-
getTableId() {
|
|
655
|
-
return this._body.getTable(this._key).tableId;
|
|
527
|
+
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/typeof.js
|
|
528
|
+
function _typeof(o) {
|
|
529
|
+
"@babel/helpers - typeof";
|
|
530
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
531
|
+
return typeof o;
|
|
532
|
+
} : function(o) {
|
|
533
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
534
|
+
}, _typeof(o);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
//#endregion
|
|
538
|
+
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPrimitive.js
|
|
539
|
+
function toPrimitive(t, r) {
|
|
540
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
541
|
+
var e = t[Symbol.toPrimitive];
|
|
542
|
+
if (void 0 !== e) {
|
|
543
|
+
var i = e.call(t, r || "default");
|
|
544
|
+
if ("object" != _typeof(i)) return i;
|
|
545
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
656
546
|
}
|
|
657
|
-
|
|
547
|
+
return ("string" === r ? String : Number)(t);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
//#endregion
|
|
551
|
+
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPropertyKey.js
|
|
552
|
+
function toPropertyKey(t) {
|
|
553
|
+
var i = toPrimitive(t, "string");
|
|
554
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
//#endregion
|
|
558
|
+
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/defineProperty.js
|
|
559
|
+
function _defineProperty(e, r, t) {
|
|
560
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
561
|
+
value: t,
|
|
562
|
+
enumerable: !0,
|
|
563
|
+
configurable: !0,
|
|
564
|
+
writable: !0
|
|
565
|
+
}) : e[r] = t, e;
|
|
566
|
+
}
|
|
658
567
|
|
|
659
568
|
//#endregion
|
|
660
|
-
//#region src/facade/f-
|
|
569
|
+
//#region src/facade/f-document-body.ts
|
|
661
570
|
/**
|
|
662
|
-
* A
|
|
663
|
-
*
|
|
664
|
-
* Use this wrapper when you need to inspect an element type first, navigate to
|
|
665
|
-
* neighboring elements, or cast the element to a more specific facade wrapper.
|
|
571
|
+
* A Facade API object bounded to a document body or header/footer segment.
|
|
572
|
+
* It provides Google Docs-like element access and range editing methods.
|
|
666
573
|
*
|
|
667
|
-
* Paragraph
|
|
574
|
+
* Paragraph elements use their persisted `paragraphId`. Tables, block ranges, and
|
|
668
575
|
* custom blocks use their persisted ids.
|
|
669
576
|
*
|
|
670
577
|
* @hideconstructor
|
|
671
578
|
*/
|
|
672
|
-
var
|
|
673
|
-
constructor(
|
|
674
|
-
this.
|
|
675
|
-
this.
|
|
676
|
-
this.
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
* ```ts
|
|
683
|
-
* const doc = univerAPI.getActiveDocument();
|
|
684
|
-
* if (!doc) throw new Error('No active document');
|
|
685
|
-
*
|
|
686
|
-
* const element = doc.getBody().getChild(0);
|
|
687
|
-
* console.log(element.getType());
|
|
688
|
-
* ```
|
|
689
|
-
*/
|
|
690
|
-
getType() {
|
|
691
|
-
return this._type;
|
|
692
|
-
}
|
|
693
|
-
/**
|
|
694
|
-
* Get the facade key used to resolve this element.
|
|
695
|
-
* @returns {string} The paragraph `paragraphId` or persisted table/block/custom block id.
|
|
696
|
-
* @example
|
|
697
|
-
* ```ts
|
|
698
|
-
* const doc = univerAPI.getActiveDocument();
|
|
699
|
-
* if (!doc) throw new Error('No active document');
|
|
700
|
-
*
|
|
701
|
-
* const body = doc.getBody();
|
|
702
|
-
* const element = body.getChild(0);
|
|
703
|
-
* console.log(element.getKey());
|
|
704
|
-
* ```
|
|
705
|
-
*/
|
|
706
|
-
getKey() {
|
|
707
|
-
return this._key;
|
|
708
|
-
}
|
|
709
|
-
/**
|
|
710
|
-
* Get the parent body facade that owns this element.
|
|
711
|
-
* @returns {FDocBody} The document body facade.
|
|
712
|
-
* @example
|
|
713
|
-
* ```ts
|
|
714
|
-
* const doc = univerAPI.getActiveDocument();
|
|
715
|
-
* if (!doc) throw new Error('No active document');
|
|
716
|
-
*
|
|
717
|
-
* const element = doc.getBody().getChild(0);
|
|
718
|
-
* console.log(element.getParent().getNumChildren());
|
|
719
|
-
* ```
|
|
720
|
-
*/
|
|
721
|
-
getParent() {
|
|
722
|
-
return this._body;
|
|
723
|
-
}
|
|
724
|
-
/**
|
|
725
|
-
* Get the next sibling element in the current body order.
|
|
726
|
-
* @returns {FDocElement | null} The next sibling wrapper, or `null` when this is the last child.
|
|
727
|
-
* @example
|
|
728
|
-
* ```ts
|
|
729
|
-
* const doc = univerAPI.getActiveDocument();
|
|
730
|
-
* if (!doc) throw new Error('No active document');
|
|
731
|
-
*
|
|
732
|
-
* const first = doc.getBody().getChild(0);
|
|
733
|
-
* const next = first.getNextSibling();
|
|
734
|
-
* console.log(next?.getType());
|
|
735
|
-
* ```
|
|
736
|
-
*/
|
|
737
|
-
getNextSibling() {
|
|
738
|
-
return this._body.createSibling(this._type, this._key, 1);
|
|
739
|
-
}
|
|
740
|
-
/**
|
|
741
|
-
* Get the previous sibling element in the current body order.
|
|
742
|
-
* @returns {FDocElement | null} The previous sibling wrapper, or `null` when this is the first child.
|
|
743
|
-
* @example
|
|
744
|
-
* ```ts
|
|
745
|
-
* const doc = univerAPI.getActiveDocument();
|
|
746
|
-
* if (!doc) throw new Error('No active document');
|
|
747
|
-
*
|
|
748
|
-
* const second = doc.getBody().getChild(1);
|
|
749
|
-
* const previous = second.getPreviousSibling();
|
|
750
|
-
* console.log(previous?.getType());
|
|
751
|
-
* ```
|
|
752
|
-
*/
|
|
753
|
-
getPreviousSibling() {
|
|
754
|
-
return this._body.createSibling(this._type, this._key, -1);
|
|
755
|
-
}
|
|
756
|
-
/**
|
|
757
|
-
* Remove this element from its parent body.
|
|
758
|
-
* @returns {boolean} `true` if the element content was removed.
|
|
759
|
-
* @example
|
|
760
|
-
* ```ts
|
|
761
|
-
* const doc = univerAPI.getActiveDocument();
|
|
762
|
-
* if (!doc) throw new Error('No active document');
|
|
763
|
-
*
|
|
764
|
-
* const body = doc.getBody();
|
|
765
|
-
* const element = body.getChild(0);
|
|
766
|
-
* element.removeFromParent();
|
|
767
|
-
* ```
|
|
768
|
-
*/
|
|
769
|
-
removeFromParent() {
|
|
770
|
-
if (this._type === "paragraph") return this._body.removeParagraph(this._key);
|
|
771
|
-
if (this._type === "blockRange") return this._body.removeBlockRange(this._key);
|
|
772
|
-
if (this._type === "table") return this._body.removeTable(this._key);
|
|
773
|
-
return this._body.removeCustomBlock(this._key);
|
|
774
|
-
}
|
|
775
|
-
/**
|
|
776
|
-
* Cast this generic element to a paragraph facade.
|
|
777
|
-
* @returns {FDocParagraph} The paragraph facade wrapper.
|
|
778
|
-
* @throws {TypeError} If the element is not a paragraph.
|
|
779
|
-
* @example
|
|
780
|
-
* ```ts
|
|
781
|
-
* const doc = univerAPI.getActiveDocument();
|
|
782
|
-
* if (!doc) throw new Error('No active document');
|
|
783
|
-
*
|
|
784
|
-
* const paragraph = doc.getBody().getChild(0).asParagraph();
|
|
785
|
-
* console.log(paragraph.getText());
|
|
786
|
-
* ```
|
|
787
|
-
*/
|
|
788
|
-
asParagraph() {
|
|
789
|
-
this._assertType("paragraph");
|
|
790
|
-
return new FDocParagraph(this._body, this._key);
|
|
791
|
-
}
|
|
792
|
-
/**
|
|
793
|
-
* Cast this generic element to a table facade.
|
|
794
|
-
* @returns {FDocTable} The table facade wrapper.
|
|
795
|
-
* @throws {TypeError} If the element is not a table.
|
|
796
|
-
* @example
|
|
797
|
-
* ```ts
|
|
798
|
-
* const doc = univerAPI.getActiveDocument();
|
|
799
|
-
* if (!doc) throw new Error('No active document');
|
|
800
|
-
*
|
|
801
|
-
* const table = doc.getBody().getChild(0).asTable();
|
|
802
|
-
* console.log(table.getTableId());
|
|
803
|
-
* ```
|
|
804
|
-
*/
|
|
805
|
-
asTable() {
|
|
806
|
-
this._assertType("table");
|
|
807
|
-
return new FDocTable(this._body, this._key);
|
|
579
|
+
var FDocumentBody = class {
|
|
580
|
+
constructor(_documentDataModel, _injector, _segmentId = "") {
|
|
581
|
+
this._documentDataModel = _documentDataModel;
|
|
582
|
+
this._injector = _injector;
|
|
583
|
+
this._segmentId = _segmentId;
|
|
584
|
+
_defineProperty(this, "_bodyEdit", void 0);
|
|
585
|
+
this._bodyEdit = {
|
|
586
|
+
replaceRange: this._replaceBodyRange.bind(this),
|
|
587
|
+
retainRange: this._retainBodyRange.bind(this)
|
|
588
|
+
};
|
|
808
589
|
}
|
|
809
590
|
/**
|
|
810
|
-
*
|
|
811
|
-
*
|
|
812
|
-
*
|
|
591
|
+
* Get the segment id of this document body facade.
|
|
592
|
+
* The main body has an empty string segment id.
|
|
593
|
+
* The header and footer FDocumentBody instances have their respective segment ids.
|
|
594
|
+
* @returns {string} The segment id of this document body facade.
|
|
813
595
|
* @example
|
|
814
596
|
* ```ts
|
|
815
|
-
* const
|
|
816
|
-
*
|
|
817
|
-
*
|
|
818
|
-
* const blockRange = doc.getBody().getChild(0).asBlockRange();
|
|
819
|
-
* console.log(blockRange.getBlockType());
|
|
597
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
598
|
+
* const fDocumentBody = fDocument.getBody();
|
|
599
|
+
* console.log(fDocumentBody.getSegmentId());
|
|
820
600
|
* ```
|
|
821
601
|
*/
|
|
822
|
-
|
|
823
|
-
this.
|
|
824
|
-
return new FDocBlockRange(this._body, this._key);
|
|
602
|
+
getSegmentId() {
|
|
603
|
+
return this._segmentId;
|
|
825
604
|
}
|
|
826
605
|
/**
|
|
827
|
-
*
|
|
828
|
-
* @returns {
|
|
829
|
-
* @throws {TypeError} If the element is not a custom block.
|
|
606
|
+
* Get the underlying document body snapshot.
|
|
607
|
+
* @returns {IDocumentBody} The document body snapshot.
|
|
830
608
|
* @example
|
|
831
609
|
* ```ts
|
|
832
|
-
* const
|
|
833
|
-
*
|
|
834
|
-
*
|
|
835
|
-
* const customBlock = doc.getBody().getChild(0).asCustomBlock();
|
|
836
|
-
* console.log(customBlock.getBlockId());
|
|
610
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
611
|
+
* const fDocumentBody = fDocument.getBody();
|
|
612
|
+
* console.log(fDocumentBody.getBody());
|
|
837
613
|
* ```
|
|
838
614
|
*/
|
|
839
|
-
|
|
840
|
-
this.
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
_assertType(type) {
|
|
844
|
-
if (this._type !== type) throw new TypeError(`Cannot cast ${this._type} to ${type}.`);
|
|
845
|
-
}
|
|
846
|
-
};
|
|
847
|
-
|
|
848
|
-
//#endregion
|
|
849
|
-
//#region src/facade/f-doc-body.ts
|
|
850
|
-
function isRichTextLike(value) {
|
|
851
|
-
return typeof value === "object" && value !== null && "getData" in value && typeof value.getData === "function";
|
|
852
|
-
}
|
|
853
|
-
const FACADE_TRIGGER = "doc-facade";
|
|
854
|
-
const RESTORE_INSERTED_PARAGRAPH_IDS = "__textXRestoreParagraphIds";
|
|
855
|
-
/**
|
|
856
|
-
* A Facade API object bounded to a document body or header/footer segment.
|
|
857
|
-
* It provides Google Docs-like element access and range editing methods.
|
|
858
|
-
*
|
|
859
|
-
* Paragraph elements use their persisted `paragraphId`. Tables, block ranges, and
|
|
860
|
-
* custom blocks use their persisted ids.
|
|
861
|
-
*
|
|
862
|
-
* @hideconstructor
|
|
863
|
-
*/
|
|
864
|
-
var FDocBody = class {
|
|
865
|
-
constructor(_documentDataModel, _commandService, _registry, _segmentId = "") {
|
|
866
|
-
this._documentDataModel = _documentDataModel;
|
|
867
|
-
this._commandService = _commandService;
|
|
868
|
-
this._segmentId = _segmentId;
|
|
615
|
+
getBody() {
|
|
616
|
+
const body = this._documentDataModel.getSelfOrHeaderFooterModel(this._segmentId).getBody();
|
|
617
|
+
if (!body) throw new Error("The document body is empty");
|
|
618
|
+
return body;
|
|
869
619
|
}
|
|
870
620
|
/**
|
|
871
|
-
* Get
|
|
872
|
-
* @returns {
|
|
621
|
+
* Get a list of top-level child elements in the body.
|
|
622
|
+
* @returns {FDocumentElement[]} The list of top-level document elements.
|
|
873
623
|
* @example
|
|
874
624
|
* ```ts
|
|
875
|
-
* const
|
|
876
|
-
*
|
|
877
|
-
*
|
|
878
|
-
*
|
|
879
|
-
* console.log(body.getNumChildren());
|
|
625
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
626
|
+
* const fDocumentBody = fDocument.getBody();
|
|
627
|
+
* const elements = fDocumentBody.getElements();
|
|
628
|
+
* console.log(elements);
|
|
880
629
|
* ```
|
|
881
630
|
*/
|
|
882
|
-
|
|
883
|
-
return this._getChildren().
|
|
631
|
+
getElements() {
|
|
632
|
+
return this._getChildren().map((child) => {
|
|
633
|
+
return this._injector.createInstance(FDocumentElement, this, this._bodyEdit, child, this._injector);
|
|
634
|
+
});
|
|
884
635
|
}
|
|
885
636
|
/**
|
|
886
637
|
* Get a top-level child element by child index.
|
|
887
638
|
* @param {number} index The zero-based child index.
|
|
888
|
-
* @returns {
|
|
639
|
+
* @returns {FDocumentElement} The top-level child element wrapper.
|
|
889
640
|
* @example
|
|
890
641
|
* ```ts
|
|
891
|
-
* const
|
|
892
|
-
*
|
|
893
|
-
*
|
|
894
|
-
*
|
|
895
|
-
* const firstChild = body.getChild(0);
|
|
896
|
-
* console.log(firstChild.getType());
|
|
642
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
643
|
+
* const fDocumentBody = fDocument.getBody();
|
|
644
|
+
* const element = fDocumentBody.getElement(0);
|
|
645
|
+
* console.log(element);
|
|
897
646
|
* ```
|
|
898
647
|
*/
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
return this._createElement(child.type, child.key);
|
|
648
|
+
getElement(index) {
|
|
649
|
+
var _this$getElements$ind;
|
|
650
|
+
return (_this$getElements$ind = this.getElements()[index]) !== null && _this$getElements$ind !== void 0 ? _this$getElements$ind : null;
|
|
903
651
|
}
|
|
904
652
|
/**
|
|
905
653
|
* Get the current child index of an element handle.
|
|
906
654
|
* The index is resolved from the element key, so a paragraph handle keeps pointing
|
|
907
655
|
* to the same paragraph after facade edits insert content before it.
|
|
908
|
-
* @param {
|
|
656
|
+
* @param {FDocumentElement} element The element handle to locate.
|
|
909
657
|
* @returns {number} The current zero-based child index.
|
|
910
658
|
* @example
|
|
911
659
|
* ```ts
|
|
912
|
-
* const
|
|
913
|
-
*
|
|
914
|
-
*
|
|
915
|
-
*
|
|
916
|
-
* const paragraph = body.getChild(1).asParagraph();
|
|
917
|
-
* body.insertParagraph(0, 'Intro');
|
|
918
|
-
* console.log(body.getChildIndex(paragraph));
|
|
660
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
661
|
+
* const fDocumentBody = fDocument.getBody();
|
|
662
|
+
* const element = fDocumentBody.getElement(0);
|
|
663
|
+
* console.log(fDocumentBody.getElementIndex(element));
|
|
919
664
|
* ```
|
|
920
665
|
*/
|
|
921
|
-
|
|
922
|
-
const
|
|
923
|
-
const index = this._getChildren().findIndex((child) => child.type ===
|
|
666
|
+
getElementIndex(element) {
|
|
667
|
+
const { type, key } = element.getResolvedInfo();
|
|
668
|
+
const index = this._getChildren().findIndex((child) => child.type === type && child.key === key);
|
|
924
669
|
if (index < 0) throw new Error("Doc element is stale");
|
|
925
670
|
return index;
|
|
926
671
|
}
|
|
@@ -931,11 +676,9 @@ var FDocBody = class {
|
|
|
931
676
|
* @returns {boolean} `true` if the edit was applied.
|
|
932
677
|
* @example
|
|
933
678
|
* ```ts
|
|
934
|
-
* const
|
|
935
|
-
*
|
|
936
|
-
*
|
|
937
|
-
* const body = doc.getBody();
|
|
938
|
-
* body.insertText(0, 'Hello ');
|
|
679
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
680
|
+
* const fDocumentBody = fDocument.getBody();
|
|
681
|
+
* fDocumentBody.insertText(0, 'Hello ');
|
|
939
682
|
* ```
|
|
940
683
|
*/
|
|
941
684
|
insertText(index, text) {
|
|
@@ -945,103 +688,15 @@ var FDocBody = class {
|
|
|
945
688
|
}, buildPlainTextInsertBody(text));
|
|
946
689
|
}
|
|
947
690
|
/**
|
|
948
|
-
* Insert a plain-text paragraph before the paragraph at the given paragraph index.
|
|
949
|
-
* @param {number} index The zero-based paragraph insertion index.
|
|
950
|
-
* @param {string} text The paragraph text. Defaults to an empty paragraph.
|
|
951
|
-
* @returns {FDocParagraph} The inserted paragraph wrapper.
|
|
952
|
-
* @example
|
|
953
|
-
* ```ts
|
|
954
|
-
* const doc = univerAPI.getActiveDocument();
|
|
955
|
-
* if (!doc) throw new Error('No active document');
|
|
956
|
-
*
|
|
957
|
-
* const body = doc.getBody();
|
|
958
|
-
* const paragraph = body.insertParagraph(0, 'Document title');
|
|
959
|
-
* paragraph.appendText(' suffix');
|
|
960
|
-
* ```
|
|
961
|
-
*/
|
|
962
|
-
insertParagraph(index, text = "") {
|
|
963
|
-
var _this$_getBody$paragr;
|
|
964
|
-
const offset = this._getParagraphInsertOffset(index);
|
|
965
|
-
if (!this._replaceBodyRange({
|
|
966
|
-
startOffset: offset,
|
|
967
|
-
endOffset: offset
|
|
968
|
-
}, buildPlainTextInsertBody(`${text}\r`))) throw new Error("Failed to insert paragraph.");
|
|
969
|
-
const paragraphIndex = this._normalizeInsertedParagraphIndex(index);
|
|
970
|
-
const paragraph = (_this$_getBody$paragr = this._getBody().paragraphs) === null || _this$_getBody$paragr === void 0 ? void 0 : _this$_getBody$paragr[paragraphIndex];
|
|
971
|
-
return new FDocParagraph(this, this._getParagraphId(paragraph, paragraphIndex));
|
|
972
|
-
}
|
|
973
|
-
/**
|
|
974
|
-
* Append a plain-text paragraph at the end of the body.
|
|
975
|
-
* @param {string} text The paragraph text. Defaults to an empty paragraph.
|
|
976
|
-
* @returns {FDocParagraph} The appended paragraph wrapper.
|
|
977
|
-
* @example
|
|
978
|
-
* ```ts
|
|
979
|
-
* const doc = univerAPI.getActiveDocument();
|
|
980
|
-
* if (!doc) throw new Error('No active document');
|
|
981
|
-
*
|
|
982
|
-
* const body = doc.getBody();
|
|
983
|
-
* const paragraph = body.appendParagraph('Summary');
|
|
984
|
-
* console.log(paragraph.getText());
|
|
985
|
-
* ```
|
|
986
|
-
*/
|
|
987
|
-
appendParagraph(text = "") {
|
|
988
|
-
var _this$_getBody$paragr2, _this$_getBody$paragr3;
|
|
989
|
-
return this.insertParagraph((_this$_getBody$paragr2 = (_this$_getBody$paragr3 = this._getBody().paragraphs) === null || _this$_getBody$paragr3 === void 0 ? void 0 : _this$_getBody$paragr3.length) !== null && _this$_getBody$paragr2 !== void 0 ? _this$_getBody$paragr2 : 0, text);
|
|
990
|
-
}
|
|
991
|
-
/**
|
|
992
|
-
* Delete a range from the body.
|
|
993
|
-
* @param {IFDocTextRange} range The text range to delete.
|
|
994
|
-
* @returns {boolean} `true` if the range was deleted.
|
|
995
|
-
* @example
|
|
996
|
-
* ```ts
|
|
997
|
-
* const doc = univerAPI.getActiveDocument();
|
|
998
|
-
* if (!doc) throw new Error('No active document');
|
|
999
|
-
*
|
|
1000
|
-
* const body = doc.getBody();
|
|
1001
|
-
* body.deleteRange({ startOffset: 0, endOffset: 5 });
|
|
1002
|
-
* ```
|
|
1003
|
-
*/
|
|
1004
|
-
deleteRange(range) {
|
|
1005
|
-
return this._replaceBodyRange(range, { dataStream: "" });
|
|
1006
|
-
}
|
|
1007
|
-
/**
|
|
1008
|
-
* Replace a range with plain text or rich text body data.
|
|
1009
|
-
* @param {IFDocTextRange} range The text range to replace.
|
|
1010
|
-
* @param {string | IFDocRichTextLike | { body?: IDocumentBody }} value The replacement text or rich-text-like value.
|
|
1011
|
-
* @returns {boolean} `true` if the replacement was applied.
|
|
1012
|
-
* @example
|
|
1013
|
-
* ```ts
|
|
1014
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1015
|
-
* if (!doc) throw new Error('No active document');
|
|
1016
|
-
*
|
|
1017
|
-
* const body = doc.getBody();
|
|
1018
|
-
* body.replaceRange({ startOffset: 0, endOffset: 5 }, 'Hello');
|
|
1019
|
-
* ```
|
|
1020
|
-
*/
|
|
1021
|
-
replaceRange(range, value) {
|
|
1022
|
-
let body;
|
|
1023
|
-
if (typeof value === "string") body = buildPlainTextInsertBody(value);
|
|
1024
|
-
else if (isRichTextLike(value)) {
|
|
1025
|
-
var _value$getData$body;
|
|
1026
|
-
body = (_value$getData$body = value.getData().body) !== null && _value$getData$body !== void 0 ? _value$getData$body : { dataStream: "" };
|
|
1027
|
-
} else {
|
|
1028
|
-
var _value$body;
|
|
1029
|
-
body = (_value$body = value.body) !== null && _value$body !== void 0 ? _value$body : { dataStream: "" };
|
|
1030
|
-
}
|
|
1031
|
-
return this._replaceBodyRange(range, body);
|
|
1032
|
-
}
|
|
1033
|
-
/**
|
|
1034
691
|
* Apply text style to a body range.
|
|
1035
|
-
* @param {
|
|
692
|
+
* @param {IFDocumentTextRange} range The range to style.
|
|
1036
693
|
* @param {ITextStyle} style The Univer text style patch.
|
|
1037
694
|
* @returns {boolean} `true` if the style was applied.
|
|
1038
695
|
* @example
|
|
1039
696
|
* ```ts
|
|
1040
|
-
* const
|
|
1041
|
-
*
|
|
1042
|
-
*
|
|
1043
|
-
* const body = doc.getBody();
|
|
1044
|
-
* body.setTextStyle({ startOffset: 0, endOffset: 5 }, { bl: 1 });
|
|
697
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
698
|
+
* const fDocumentBody = fDocument.getBody();
|
|
699
|
+
* fDocumentBody.setTextStyle({ startOffset: 0, endOffset: 5 }, { bl: 1 });
|
|
1045
700
|
* ```
|
|
1046
701
|
*/
|
|
1047
702
|
setTextStyle(range, style) {
|
|
@@ -1056,525 +711,235 @@ var FDocBody = class {
|
|
|
1056
711
|
return this._retainBodyRange(range, updateBody, UpdateDocsAttributeType.COVER);
|
|
1057
712
|
}
|
|
1058
713
|
/**
|
|
1059
|
-
*
|
|
1060
|
-
* @param {
|
|
1061
|
-
* @param {
|
|
1062
|
-
* @returns {
|
|
1063
|
-
* @example
|
|
1064
|
-
* ```ts
|
|
1065
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1066
|
-
* if (!doc) throw new Error('No active document');
|
|
1067
|
-
*
|
|
1068
|
-
* const body = doc.getBody();
|
|
1069
|
-
* const paragraph = body.getChild(0).asParagraph();
|
|
1070
|
-
* body.setParagraphStyle(paragraph, { horizontalAlign: 2 });
|
|
1071
|
-
* ```
|
|
1072
|
-
*/
|
|
1073
|
-
setParagraphStyle(paragraph, style) {
|
|
1074
|
-
const resolved = paragraph instanceof FDocElement || paragraph instanceof FDocParagraph ? this.resolveParagraph(paragraph.getKey()) : this._findParagraphByRange(paragraph);
|
|
1075
|
-
const updateBody = {
|
|
1076
|
-
dataStream: "",
|
|
1077
|
-
paragraphs: [{
|
|
1078
|
-
...resolved.paragraph,
|
|
1079
|
-
startIndex: 0,
|
|
1080
|
-
paragraphStyle: {
|
|
1081
|
-
...resolved.paragraph.paragraphStyle,
|
|
1082
|
-
...style
|
|
1083
|
-
}
|
|
1084
|
-
}]
|
|
1085
|
-
};
|
|
1086
|
-
this._preserveExplicitParagraphIds(updateBody);
|
|
1087
|
-
return this._retainBodyRange({
|
|
1088
|
-
startOffset: resolved.endOffset,
|
|
1089
|
-
endOffset: resolved.endOffset + 1
|
|
1090
|
-
}, updateBody, UpdateDocsAttributeType.REPLACE);
|
|
1091
|
-
}
|
|
1092
|
-
/**
|
|
1093
|
-
* Get the text content of a paragraph by paragraph id.
|
|
1094
|
-
* @param {string} key The paragraph id.
|
|
1095
|
-
* @returns {string} The paragraph text without the trailing paragraph break.
|
|
714
|
+
* Insert a plain-text paragraph before the paragraph at the given paragraph index.
|
|
715
|
+
* @param {number} index The zero-based paragraph insertion index.
|
|
716
|
+
* @param {string} text The paragraph text. Defaults to an empty paragraph.
|
|
717
|
+
* @returns {FDocumentParagraph} The inserted paragraph wrapper.
|
|
1096
718
|
* @example
|
|
1097
719
|
* ```ts
|
|
1098
|
-
* const
|
|
1099
|
-
*
|
|
1100
|
-
*
|
|
1101
|
-
*
|
|
1102
|
-
* console.log(doc.getBody().getParagraphText(paragraph.getKey()));
|
|
720
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
721
|
+
* const fDocumentBody = fDocument.getBody();
|
|
722
|
+
* const paragraph = fDocumentBody.insertParagraph(0, 'Document title');
|
|
723
|
+
* paragraph.appendText(' suffix');
|
|
1103
724
|
* ```
|
|
1104
725
|
*/
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
726
|
+
insertParagraph(index, text = "") {
|
|
727
|
+
var _paragraphs;
|
|
728
|
+
const offset = this._getParagraphInsertOffset(index);
|
|
729
|
+
if (!this._replaceBodyRange({
|
|
730
|
+
startOffset: offset,
|
|
731
|
+
endOffset: offset
|
|
732
|
+
}, buildPlainTextInsertBody(`${text}\r`))) throw new Error("Failed to insert paragraph.");
|
|
733
|
+
const { paragraphs = [] } = this.getBody();
|
|
734
|
+
const paragraph = paragraphs[index];
|
|
735
|
+
if (!paragraph) throw new Error("Failed to insert paragraph.");
|
|
736
|
+
const info = this._resolveParagraphInfo(paragraph, index, (_paragraphs = paragraphs[index - 1]) === null || _paragraphs === void 0 ? void 0 : _paragraphs.startIndex);
|
|
737
|
+
return this._injector.createInstance(FDocumentParagraph, this, this._bodyEdit, info, this._injector);
|
|
1108
738
|
}
|
|
1109
739
|
/**
|
|
1110
|
-
*
|
|
1111
|
-
* @param {string}
|
|
1112
|
-
* @
|
|
1113
|
-
* @returns {boolean} `true` if the paragraph text was replaced.
|
|
740
|
+
* Append a plain-text paragraph at the end of the body.
|
|
741
|
+
* @param {string} text The paragraph text. Defaults to an empty paragraph.
|
|
742
|
+
* @returns {FDocumentParagraph} The appended paragraph wrapper.
|
|
1114
743
|
* @example
|
|
1115
744
|
* ```ts
|
|
1116
|
-
* const
|
|
1117
|
-
*
|
|
1118
|
-
*
|
|
1119
|
-
*
|
|
1120
|
-
* doc.getBody().setParagraphText(paragraph.getKey(), 'Updated text');
|
|
745
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
746
|
+
* const fDocumentBody = fDocument.getBody();
|
|
747
|
+
* const paragraph = fDocumentBody.appendParagraph('Summary');
|
|
748
|
+
* console.log(paragraph.getText());
|
|
1121
749
|
* ```
|
|
1122
750
|
*/
|
|
1123
|
-
|
|
1124
|
-
const
|
|
1125
|
-
return this.
|
|
1126
|
-
startOffset: resolved.startOffset,
|
|
1127
|
-
endOffset: resolved.endOffset
|
|
1128
|
-
}, text);
|
|
751
|
+
appendParagraph(text = "") {
|
|
752
|
+
const { paragraphs = [] } = this.getBody();
|
|
753
|
+
return this.insertParagraph(paragraphs.length, text);
|
|
1129
754
|
}
|
|
1130
755
|
/**
|
|
1131
|
-
*
|
|
1132
|
-
* @param {
|
|
1133
|
-
* @
|
|
1134
|
-
* @returns {boolean} `true` if the text was appended.
|
|
756
|
+
* Delete a range from the body.
|
|
757
|
+
* @param {IFDocumentTextRange} range The text range to delete.
|
|
758
|
+
* @returns {boolean} `true` if the range was deleted.
|
|
1135
759
|
* @example
|
|
1136
760
|
* ```ts
|
|
1137
|
-
* const
|
|
1138
|
-
*
|
|
1139
|
-
*
|
|
1140
|
-
* const paragraph = doc.getBody().getChild(0).asParagraph();
|
|
1141
|
-
* doc.getBody().appendParagraphText(paragraph.getKey(), ' suffix');
|
|
761
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
762
|
+
* const fDocumentBody = fDocument.getBody();
|
|
763
|
+
* fDocumentBody.deleteRange({ startOffset: 0, endOffset: 5 });
|
|
1142
764
|
* ```
|
|
1143
765
|
*/
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
return this.insertText(resolved.endOffset, text);
|
|
766
|
+
deleteRange(range) {
|
|
767
|
+
return this._replaceBodyRange(range, { dataStream: "" });
|
|
1147
768
|
}
|
|
1148
769
|
/**
|
|
1149
770
|
* Remove a paragraph by paragraph id.
|
|
1150
|
-
* @param {
|
|
771
|
+
* @param {FDocumentParagraph} paragraph The paragraph handle to remove.
|
|
1151
772
|
* @returns {boolean} `true` if the paragraph was removed.
|
|
1152
773
|
* @example
|
|
1153
774
|
* ```ts
|
|
1154
|
-
* const
|
|
1155
|
-
*
|
|
1156
|
-
*
|
|
1157
|
-
* const paragraph = doc.getBody().getChild(0).asParagraph();
|
|
1158
|
-
* doc.getBody().removeParagraph(paragraph.getKey());
|
|
1159
|
-
* ```
|
|
1160
|
-
*/
|
|
1161
|
-
removeParagraph(key) {
|
|
1162
|
-
const resolved = this.resolveParagraph(key);
|
|
1163
|
-
return this.deleteRange({
|
|
1164
|
-
startOffset: resolved.startOffset,
|
|
1165
|
-
endOffset: resolved.endOffset + 1
|
|
1166
|
-
});
|
|
1167
|
-
}
|
|
1168
|
-
/**
|
|
1169
|
-
* Get a paragraph text range by paragraph id.
|
|
1170
|
-
* @param {string} key The paragraph id.
|
|
1171
|
-
* @returns {IFDocTextRange} The paragraph range excluding the trailing paragraph break.
|
|
1172
|
-
* @example
|
|
1173
|
-
* ```ts
|
|
1174
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1175
|
-
* if (!doc) throw new Error('No active document');
|
|
1176
|
-
*
|
|
1177
|
-
* const paragraph = doc.getBody().getChild(0).asParagraph();
|
|
1178
|
-
* const range = doc.getBody().getParagraphRange(paragraph.getKey());
|
|
1179
|
-
* console.log(range.startOffset, range.endOffset);
|
|
1180
|
-
* ```
|
|
1181
|
-
*/
|
|
1182
|
-
getParagraphRange(key) {
|
|
1183
|
-
const resolved = this.resolveParagraph(key);
|
|
1184
|
-
return {
|
|
1185
|
-
startOffset: resolved.startOffset,
|
|
1186
|
-
endOffset: resolved.endOffset,
|
|
1187
|
-
segmentId: this._segmentId
|
|
1188
|
-
};
|
|
1189
|
-
}
|
|
1190
|
-
/**
|
|
1191
|
-
* Check whether a paragraph has list metadata.
|
|
1192
|
-
* @param {string} key The paragraph id.
|
|
1193
|
-
* @returns {boolean} `true` if the paragraph is a list item.
|
|
1194
|
-
* @example
|
|
1195
|
-
* ```ts
|
|
1196
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1197
|
-
* if (!doc) throw new Error('No active document');
|
|
1198
|
-
*
|
|
1199
|
-
* const paragraph = doc.getBody().getChild(0).asParagraph();
|
|
1200
|
-
* console.log(doc.getBody().isListParagraph(paragraph.getKey()));
|
|
1201
|
-
* ```
|
|
1202
|
-
*/
|
|
1203
|
-
isListParagraph(key) {
|
|
1204
|
-
return Boolean(this.resolveParagraph(key).paragraph.bullet);
|
|
1205
|
-
}
|
|
1206
|
-
/**
|
|
1207
|
-
* Check whether a paragraph is a task/checklist item.
|
|
1208
|
-
* @param {string} key The paragraph id.
|
|
1209
|
-
* @returns {boolean} `true` if the paragraph is an unchecked or checked task item.
|
|
1210
|
-
* @example
|
|
1211
|
-
* ```ts
|
|
1212
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1213
|
-
* if (!doc) throw new Error('No active document');
|
|
1214
|
-
*
|
|
1215
|
-
* const paragraph = doc.getBody().getChild(0).asParagraph();
|
|
1216
|
-
* console.log(doc.getBody().isTaskParagraph(paragraph.getKey()));
|
|
1217
|
-
* ```
|
|
1218
|
-
*/
|
|
1219
|
-
isTaskParagraph(key) {
|
|
1220
|
-
var _this$resolveParagrap;
|
|
1221
|
-
const listType = (_this$resolveParagrap = this.resolveParagraph(key).paragraph.bullet) === null || _this$resolveParagrap === void 0 ? void 0 : _this$resolveParagrap.listType;
|
|
1222
|
-
return listType === PresetListType.CHECK_LIST || listType === PresetListType.CHECK_LIST_CHECKED;
|
|
1223
|
-
}
|
|
1224
|
-
/**
|
|
1225
|
-
* Set the checked state of a task/checklist paragraph.
|
|
1226
|
-
* @param {string} key The paragraph id.
|
|
1227
|
-
* @param {boolean} checked Whether the task should be checked.
|
|
1228
|
-
* @returns {boolean} `true` if the task state was updated, or `false` if the paragraph is not a task item.
|
|
1229
|
-
* @example
|
|
1230
|
-
* ```ts
|
|
1231
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1232
|
-
* if (!doc) throw new Error('No active document');
|
|
1233
|
-
*
|
|
1234
|
-
* const paragraph = doc.getBody().getChild(0).asParagraph();
|
|
1235
|
-
* doc.getBody().setTaskChecked(paragraph.getKey(), true);
|
|
1236
|
-
* ```
|
|
1237
|
-
*/
|
|
1238
|
-
setTaskChecked(key, checked) {
|
|
1239
|
-
const resolved = this.resolveParagraph(key);
|
|
1240
|
-
const bullet = resolved.paragraph.bullet;
|
|
1241
|
-
if (!bullet || !this.isTaskParagraph(key)) return false;
|
|
1242
|
-
const updateBody = {
|
|
1243
|
-
dataStream: "",
|
|
1244
|
-
paragraphs: [{
|
|
1245
|
-
...resolved.paragraph,
|
|
1246
|
-
startIndex: 0,
|
|
1247
|
-
bullet: {
|
|
1248
|
-
...bullet,
|
|
1249
|
-
listType: checked ? PresetListType.CHECK_LIST_CHECKED : PresetListType.CHECK_LIST
|
|
1250
|
-
}
|
|
1251
|
-
}]
|
|
1252
|
-
};
|
|
1253
|
-
this._preserveExplicitParagraphIds(updateBody);
|
|
1254
|
-
return this._retainBodyRange({
|
|
1255
|
-
startOffset: resolved.endOffset,
|
|
1256
|
-
endOffset: resolved.endOffset + 1
|
|
1257
|
-
}, updateBody, UpdateDocsAttributeType.REPLACE);
|
|
1258
|
-
}
|
|
1259
|
-
/**
|
|
1260
|
-
* Resolve a paragraph id to its current paragraph metadata.
|
|
1261
|
-
* @param {string} key The paragraph id.
|
|
1262
|
-
* @returns {IFDocResolvedParagraph} The current paragraph metadata.
|
|
1263
|
-
* @example
|
|
1264
|
-
* ```ts
|
|
1265
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1266
|
-
* if (!doc) throw new Error('No active document');
|
|
1267
|
-
*
|
|
1268
|
-
* const paragraph = doc.getBody().getChild(0).asParagraph();
|
|
1269
|
-
* const resolved = doc.getBody().resolveParagraph(paragraph.getKey());
|
|
1270
|
-
* console.log(resolved.paragraphIndex);
|
|
1271
|
-
* ```
|
|
1272
|
-
*/
|
|
1273
|
-
resolveParagraph(key) {
|
|
1274
|
-
var _body$paragraphs;
|
|
1275
|
-
const body = this._getBody();
|
|
1276
|
-
const matches = ((_body$paragraphs = body.paragraphs) !== null && _body$paragraphs !== void 0 ? _body$paragraphs : []).map((paragraph, paragraphIndex) => ({
|
|
1277
|
-
paragraph,
|
|
1278
|
-
paragraphIndex
|
|
1279
|
-
})).filter(({ paragraph }) => paragraph.paragraphId === key);
|
|
1280
|
-
if (matches.length !== 1) throw new DocElementStaleError(matches.length > 1 ? `Doc paragraph id "${key}" is duplicated.` : `Doc paragraph id "${key}" is stale.`);
|
|
1281
|
-
const { paragraph, paragraphIndex } = matches[0];
|
|
1282
|
-
return {
|
|
1283
|
-
paragraph,
|
|
1284
|
-
paragraphIndex,
|
|
1285
|
-
startOffset: paragraphIndex > 0 ? body.paragraphs[paragraphIndex - 1].startIndex + 1 : 0,
|
|
1286
|
-
endOffset: paragraph.startIndex
|
|
1287
|
-
};
|
|
1288
|
-
}
|
|
1289
|
-
/**
|
|
1290
|
-
* Resolve an element key to its current child metadata.
|
|
1291
|
-
* @param {FDocElementType} type The element type.
|
|
1292
|
-
* @param {string} key The persisted element key.
|
|
1293
|
-
* @returns {object} The current child metadata used by the facade.
|
|
1294
|
-
* @example
|
|
1295
|
-
* ```ts
|
|
1296
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1297
|
-
* if (!doc) throw new Error('No active document');
|
|
1298
|
-
*
|
|
1299
|
-
* const element = doc.getBody().getChild(0);
|
|
1300
|
-
* const resolved = doc.getBody().resolveElement(element.getType(), element.getKey());
|
|
1301
|
-
* console.log(resolved.position);
|
|
1302
|
-
* ```
|
|
1303
|
-
*/
|
|
1304
|
-
resolveElement(type, key) {
|
|
1305
|
-
if (type === "paragraph") return {
|
|
1306
|
-
type,
|
|
1307
|
-
key,
|
|
1308
|
-
position: this.resolveParagraph(key).startOffset,
|
|
1309
|
-
priority: 3
|
|
1310
|
-
};
|
|
1311
|
-
const child = this._getChildren().find((item) => item.type === type && item.key === key);
|
|
1312
|
-
if (!child) throw new Error("Doc element is stale");
|
|
1313
|
-
return child;
|
|
1314
|
-
}
|
|
1315
|
-
/**
|
|
1316
|
-
* Get a callout, quote, or code block range by block id.
|
|
1317
|
-
* @param {string} key The persisted block range id.
|
|
1318
|
-
* @returns {IDocumentBlockRange} The matching block range snapshot.
|
|
1319
|
-
* @example
|
|
1320
|
-
* ```ts
|
|
1321
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1322
|
-
* if (!doc) throw new Error('No active document');
|
|
1323
|
-
*
|
|
1324
|
-
* const block = doc.getBody().getChild(0).asBlockRange();
|
|
1325
|
-
* console.log(doc.getBody().getBlockRange(block.getKey()).blockType);
|
|
1326
|
-
* ```
|
|
1327
|
-
*/
|
|
1328
|
-
getBlockRange(key) {
|
|
1329
|
-
var _this$_getBody$blockR;
|
|
1330
|
-
const blockRange = (_this$_getBody$blockR = this._getBody().blockRanges) === null || _this$_getBody$blockR === void 0 ? void 0 : _this$_getBody$blockR.find((item) => item.blockId === key);
|
|
1331
|
-
if (!blockRange) throw new Error("Doc element is stale");
|
|
1332
|
-
return blockRange;
|
|
1333
|
-
}
|
|
1334
|
-
/**
|
|
1335
|
-
* Get the text inside a callout, quote, or code block range.
|
|
1336
|
-
* @param {string} key The persisted block range id.
|
|
1337
|
-
* @returns {string} The block range text.
|
|
1338
|
-
* @example
|
|
1339
|
-
* ```ts
|
|
1340
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1341
|
-
* if (!doc) throw new Error('No active document');
|
|
1342
|
-
*
|
|
1343
|
-
* const block = doc.getBody().getChild(0).asBlockRange();
|
|
1344
|
-
* console.log(doc.getBody().getBlockRangeText(block.getKey()));
|
|
1345
|
-
* ```
|
|
1346
|
-
*/
|
|
1347
|
-
getBlockRangeText(key) {
|
|
1348
|
-
const blockRange = this.getBlockRange(key);
|
|
1349
|
-
return this._getBody().dataStream.slice(blockRange.startIndex, blockRange.endIndex);
|
|
1350
|
-
}
|
|
1351
|
-
/**
|
|
1352
|
-
* Replace the text inside a callout, quote, or code block range.
|
|
1353
|
-
* @param {string} key The persisted block range id.
|
|
1354
|
-
* @param {string} text The replacement text.
|
|
1355
|
-
* @returns {boolean} `true` if the text was replaced.
|
|
1356
|
-
* @example
|
|
1357
|
-
* ```ts
|
|
1358
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1359
|
-
* if (!doc) throw new Error('No active document');
|
|
1360
|
-
*
|
|
1361
|
-
* const block = doc.getBody().getChild(0).asBlockRange();
|
|
1362
|
-
* doc.getBody().setBlockRangeText(block.getKey(), 'Updated block');
|
|
1363
|
-
* ```
|
|
1364
|
-
*/
|
|
1365
|
-
setBlockRangeText(key, text) {
|
|
1366
|
-
const blockRange = this.getBlockRange(key);
|
|
1367
|
-
const body = buildPlainTextInsertBody(`${text}\r`);
|
|
1368
|
-
body.blockRanges = [{
|
|
1369
|
-
...blockRange,
|
|
1370
|
-
startIndex: 0,
|
|
1371
|
-
endIndex: text.length
|
|
1372
|
-
}];
|
|
1373
|
-
return this.replaceRange({
|
|
1374
|
-
startOffset: blockRange.startIndex,
|
|
1375
|
-
endOffset: blockRange.endIndex + 1
|
|
1376
|
-
}, { body });
|
|
1377
|
-
}
|
|
1378
|
-
/**
|
|
1379
|
-
* Remove a callout, quote, or code block range and its content.
|
|
1380
|
-
* @param {string} key The persisted block range id.
|
|
1381
|
-
* @returns {boolean} `true` if the block range content was removed.
|
|
1382
|
-
* @example
|
|
1383
|
-
* ```ts
|
|
1384
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1385
|
-
* if (!doc) throw new Error('No active document');
|
|
775
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
776
|
+
* const fDocumentBody = fDocument.getBody();
|
|
777
|
+
* const element = fDocumentBody.getElement(0);
|
|
1386
778
|
*
|
|
1387
|
-
*
|
|
1388
|
-
*
|
|
779
|
+
* if (element?.isParagraph()) {
|
|
780
|
+
* const paragraph = element.asParagraph();
|
|
781
|
+
* const removed = fDocumentBody.removeParagraph(paragraph);
|
|
782
|
+
* console.log(removed ? 'Paragraph removed' : 'Failed to remove paragraph');
|
|
783
|
+
* }
|
|
1389
784
|
* ```
|
|
1390
785
|
*/
|
|
1391
|
-
|
|
1392
|
-
const
|
|
786
|
+
removeParagraph(paragraph) {
|
|
787
|
+
const { startOffset, endOffset } = paragraph.getResolvedParagraphInfo();
|
|
1393
788
|
return this.deleteRange({
|
|
1394
|
-
startOffset
|
|
1395
|
-
endOffset:
|
|
1396
|
-
});
|
|
1397
|
-
}
|
|
1398
|
-
/**
|
|
1399
|
-
* Get a table marker by table id.
|
|
1400
|
-
* @param {string} key The persisted table id.
|
|
1401
|
-
* @returns {ICustomTable} The matching table marker.
|
|
1402
|
-
* @example
|
|
1403
|
-
* ```ts
|
|
1404
|
-
* const doc = univerAPI.getActiveDocument();
|
|
1405
|
-
* if (!doc) throw new Error('No active document');
|
|
1406
|
-
*
|
|
1407
|
-
* const table = doc.getBody().getChild(0).asTable();
|
|
1408
|
-
* console.log(doc.getBody().getTable(table.getTableId()));
|
|
1409
|
-
* ```
|
|
1410
|
-
*/
|
|
1411
|
-
getTable(key) {
|
|
1412
|
-
var _this$_getBody$tables;
|
|
1413
|
-
const table = (_this$_getBody$tables = this._getBody().tables) === null || _this$_getBody$tables === void 0 ? void 0 : _this$_getBody$tables.find((item) => item.tableId === key);
|
|
1414
|
-
if (!table) throw new Error("Doc element is stale");
|
|
1415
|
-
return table;
|
|
789
|
+
startOffset,
|
|
790
|
+
endOffset: endOffset + 1
|
|
791
|
+
});
|
|
1416
792
|
}
|
|
1417
793
|
/**
|
|
1418
|
-
* Remove a
|
|
1419
|
-
* @param {
|
|
1420
|
-
* @returns {boolean} `true` if the
|
|
794
|
+
* Remove a callout, quote, or code block range and its content.
|
|
795
|
+
* @param {FDocumentBlockRange} blockRange The block range handle to remove.
|
|
796
|
+
* @returns {boolean} `true` if the block range content was removed.
|
|
1421
797
|
* @example
|
|
1422
798
|
* ```ts
|
|
1423
|
-
* const
|
|
1424
|
-
*
|
|
799
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
800
|
+
* const fDocumentBody = fDocument.getBody();
|
|
801
|
+
* const element = fDocumentBody.getElement(0);
|
|
1425
802
|
*
|
|
1426
|
-
*
|
|
1427
|
-
*
|
|
803
|
+
* if (element?.isBlockRange()) {
|
|
804
|
+
* const blockRange = element.asBlockRange();
|
|
805
|
+
* const removed = fDocumentBody.removeBlockRange(blockRange);
|
|
806
|
+
* console.log(removed ? 'Block range removed' : 'Failed to remove block range');
|
|
807
|
+
* }
|
|
1428
808
|
* ```
|
|
1429
809
|
*/
|
|
1430
|
-
|
|
1431
|
-
const
|
|
810
|
+
removeBlockRange(blockRange) {
|
|
811
|
+
const { startIndex, endIndex } = blockRange.getBlockRange();
|
|
1432
812
|
return this.deleteRange({
|
|
1433
|
-
startOffset:
|
|
1434
|
-
endOffset:
|
|
813
|
+
startOffset: startIndex,
|
|
814
|
+
endOffset: endIndex + 1
|
|
1435
815
|
});
|
|
1436
816
|
}
|
|
1437
817
|
/**
|
|
1438
|
-
*
|
|
1439
|
-
* @
|
|
1440
|
-
* @returns {ICustomBlock} The matching custom block marker.
|
|
818
|
+
* Remove a table marker and its content range.
|
|
819
|
+
* @returns {boolean} `true` if the table range was removed.
|
|
1441
820
|
* @example
|
|
1442
821
|
* ```ts
|
|
1443
|
-
* const
|
|
1444
|
-
*
|
|
822
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
823
|
+
* const fDocumentBody = fDocument.getBody();
|
|
824
|
+
* const element = fDocumentBody.getElement(0);
|
|
1445
825
|
*
|
|
1446
|
-
*
|
|
1447
|
-
*
|
|
826
|
+
* if (element?.isTable()) {
|
|
827
|
+
* const table = element.asTable();
|
|
828
|
+
* const removed = fDocumentBody.removeTable(table);
|
|
829
|
+
* console.log(removed ? 'Table removed' : 'Failed to remove table');
|
|
830
|
+
* }
|
|
1448
831
|
* ```
|
|
1449
832
|
*/
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
833
|
+
removeTable(table) {
|
|
834
|
+
const { startIndex, endIndex } = table.getTable();
|
|
835
|
+
return this.deleteRange({
|
|
836
|
+
startOffset: startIndex,
|
|
837
|
+
endOffset: endIndex + 1
|
|
838
|
+
});
|
|
1455
839
|
}
|
|
1456
840
|
/**
|
|
1457
841
|
* Remove a custom block marker and its placeholder character.
|
|
1458
|
-
* @param {
|
|
842
|
+
* @param {FDocumentCustomBlock} customBlock The custom block handle to remove.
|
|
1459
843
|
* @returns {boolean} `true` if the custom block placeholder was removed.
|
|
1460
844
|
* @example
|
|
1461
845
|
* ```ts
|
|
1462
|
-
* const
|
|
1463
|
-
*
|
|
846
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
847
|
+
* const fDocumentBody = fDocument.getBody();
|
|
848
|
+
* const element = fDocumentBody.getElement(0);
|
|
1464
849
|
*
|
|
1465
|
-
*
|
|
1466
|
-
*
|
|
850
|
+
* if (element?.isCustomBlock()) {
|
|
851
|
+
* const customBlock = element.asCustomBlock();
|
|
852
|
+
* const removed = fDocumentBody.removeCustomBlock(customBlock);
|
|
853
|
+
* console.log(removed ? 'Custom block removed' : 'Failed to remove custom block');
|
|
854
|
+
* }
|
|
1467
855
|
* ```
|
|
1468
856
|
*/
|
|
1469
|
-
removeCustomBlock(
|
|
1470
|
-
const
|
|
857
|
+
removeCustomBlock(customBlock) {
|
|
858
|
+
const { startIndex } = customBlock.getCustomBlock();
|
|
1471
859
|
return this.deleteRange({
|
|
1472
|
-
startOffset:
|
|
1473
|
-
endOffset:
|
|
860
|
+
startOffset: startIndex,
|
|
861
|
+
endOffset: startIndex + 1
|
|
1474
862
|
});
|
|
1475
863
|
}
|
|
1476
864
|
/**
|
|
1477
|
-
*
|
|
1478
|
-
* @param {
|
|
1479
|
-
* @
|
|
1480
|
-
* @param {-1 | 1} direction `-1` for previous sibling, `1` for next sibling.
|
|
1481
|
-
* @returns {FDocElement | null} The sibling wrapper, or `null` if none exists.
|
|
865
|
+
* Resolve an element key to its current child metadata.
|
|
866
|
+
* @param {FDocumentElement} element The element handle to resolve.
|
|
867
|
+
* @returns {IFDocumentElementInfo} The current child metadata used by the facade.
|
|
1482
868
|
* @example
|
|
1483
869
|
* ```ts
|
|
1484
|
-
* const
|
|
1485
|
-
*
|
|
1486
|
-
*
|
|
1487
|
-
* const
|
|
1488
|
-
*
|
|
1489
|
-
* console.log(next?.getType());
|
|
870
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
871
|
+
* const fDocumentBody = fDocument.getBody();
|
|
872
|
+
* const element = fDocumentBody.getElement(0);
|
|
873
|
+
* const resolved = fDocumentBody.resolveElement(element);
|
|
874
|
+
* console.log(resolved);
|
|
1490
875
|
* ```
|
|
1491
876
|
*/
|
|
1492
|
-
|
|
1493
|
-
const
|
|
1494
|
-
const child = this._getChildren()
|
|
1495
|
-
|
|
877
|
+
resolveElement(element) {
|
|
878
|
+
const { type, key } = element.getResolvedInfo();
|
|
879
|
+
const child = this._getChildren().find((item) => item.type === type && item.key === key);
|
|
880
|
+
if (!child) throw new Error("Doc element is stale");
|
|
881
|
+
return child;
|
|
1496
882
|
}
|
|
1497
883
|
_getChildren() {
|
|
1498
|
-
|
|
1499
|
-
const body = this._getBody();
|
|
884
|
+
const { paragraphs, blockRanges, tables, customBlocks } = this.getBody();
|
|
1500
885
|
const children = [];
|
|
1501
|
-
for (let
|
|
1502
|
-
|
|
886
|
+
if (paragraphs) for (let i = 0; i < paragraphs.length; i++) {
|
|
887
|
+
var _paragraphs2;
|
|
888
|
+
const paragraph = paragraphs[i];
|
|
889
|
+
const info = this._resolveParagraphInfo(paragraph, i, (_paragraphs2 = paragraphs[i - 1]) === null || _paragraphs2 === void 0 ? void 0 : _paragraphs2.startIndex);
|
|
890
|
+
children.push(info);
|
|
891
|
+
}
|
|
892
|
+
if (blockRanges) for (let i = 0; i < blockRanges.length; i++) {
|
|
893
|
+
const blockRange = blockRanges[i];
|
|
894
|
+
children.push({
|
|
895
|
+
type: DocumentBlockType.BLOCK_RANGE,
|
|
896
|
+
key: blockRange.blockId,
|
|
897
|
+
position: blockRange.startIndex,
|
|
898
|
+
priority: 0
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
if (tables) for (let i = 0; i < tables.length; i++) {
|
|
902
|
+
const table = tables[i];
|
|
903
|
+
children.push({
|
|
904
|
+
type: DocumentBlockType.TABLE,
|
|
905
|
+
key: table.tableId,
|
|
906
|
+
position: table.startIndex,
|
|
907
|
+
priority: 1
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
if (customBlocks) for (let i = 0; i < customBlocks.length; i++) {
|
|
911
|
+
const customBlock = customBlocks[i];
|
|
1503
912
|
children.push({
|
|
1504
|
-
type:
|
|
1505
|
-
key:
|
|
1506
|
-
position:
|
|
1507
|
-
priority:
|
|
913
|
+
type: DocumentBlockType.CUSTOM_BLOCK,
|
|
914
|
+
key: customBlock.blockId,
|
|
915
|
+
position: customBlock.startIndex,
|
|
916
|
+
priority: 2
|
|
1508
917
|
});
|
|
1509
918
|
}
|
|
1510
|
-
(_body$blockRanges = body.blockRanges) === null || _body$blockRanges === void 0 || _body$blockRanges.forEach((blockRange) => children.push({
|
|
1511
|
-
type: "blockRange",
|
|
1512
|
-
key: blockRange.blockId,
|
|
1513
|
-
position: blockRange.startIndex,
|
|
1514
|
-
priority: 0
|
|
1515
|
-
}));
|
|
1516
|
-
(_body$tables = body.tables) === null || _body$tables === void 0 || _body$tables.forEach((table) => children.push({
|
|
1517
|
-
type: "table",
|
|
1518
|
-
key: table.tableId,
|
|
1519
|
-
position: table.startIndex,
|
|
1520
|
-
priority: 1
|
|
1521
|
-
}));
|
|
1522
|
-
(_body$customBlocks = body.customBlocks) === null || _body$customBlocks === void 0 || _body$customBlocks.forEach((customBlock) => children.push({
|
|
1523
|
-
type: "customBlock",
|
|
1524
|
-
key: customBlock.blockId,
|
|
1525
|
-
position: customBlock.startIndex,
|
|
1526
|
-
priority: 2
|
|
1527
|
-
}));
|
|
1528
919
|
return children.sort((a, b) => a.position - b.position || a.priority - b.priority);
|
|
1529
920
|
}
|
|
1530
|
-
|
|
1531
|
-
return
|
|
921
|
+
_resolveParagraphInfo(paragraph, paragraphIndex, previousParagraphStartIndex) {
|
|
922
|
+
return {
|
|
923
|
+
type: DocumentBlockType.PARAGRAPH,
|
|
924
|
+
key: this._getParagraphId(paragraph, paragraphIndex),
|
|
925
|
+
position: paragraphIndex > 0 ? previousParagraphStartIndex + 1 : 0,
|
|
926
|
+
priority: 3
|
|
927
|
+
};
|
|
1532
928
|
}
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
if (!
|
|
1536
|
-
return
|
|
929
|
+
_getParagraphId(paragraph, paragraphIndex) {
|
|
930
|
+
if (!paragraph) throw new Error(`Paragraph index ${paragraphIndex} is out of range.`);
|
|
931
|
+
if (!paragraph.paragraphId) throw new Error(`Paragraph at index ${paragraphIndex} is missing paragraphId.`);
|
|
932
|
+
return paragraph.paragraphId;
|
|
1537
933
|
}
|
|
1538
934
|
_getParagraphInsertOffset(index) {
|
|
1539
|
-
var _body$paragraphs3;
|
|
1540
|
-
const body = this._getBody();
|
|
1541
935
|
if (index <= 0) return 0;
|
|
1542
|
-
const paragraphs =
|
|
1543
|
-
if (paragraphs.length === 0) return Math.max(0,
|
|
936
|
+
const { dataStream, paragraphs = [] } = this.getBody();
|
|
937
|
+
if (paragraphs.length === 0) return Math.max(0, dataStream.length - 1);
|
|
1544
938
|
if (index >= paragraphs.length) return paragraphs[paragraphs.length - 1].startIndex + 1;
|
|
1545
939
|
return paragraphs[index - 1].startIndex + 1;
|
|
1546
940
|
}
|
|
1547
|
-
_normalizeInsertedParagraphIndex(index) {
|
|
1548
|
-
var _this$_getBody$paragr4;
|
|
1549
|
-
const paragraphs = (_this$_getBody$paragr4 = this._getBody().paragraphs) !== null && _this$_getBody$paragr4 !== void 0 ? _this$_getBody$paragr4 : [];
|
|
1550
|
-
return Math.max(0, Math.min(index, paragraphs.length - 1));
|
|
1551
|
-
}
|
|
1552
|
-
_getParagraphId(paragraph, paragraphIndex) {
|
|
1553
|
-
if (!paragraph) throw new RangeError(`Paragraph index ${paragraphIndex} is out of range.`);
|
|
1554
|
-
if (!paragraph.paragraphId) throw new DocElementStaleError(`Paragraph at index ${paragraphIndex} is missing paragraphId.`);
|
|
1555
|
-
return paragraph.paragraphId;
|
|
1556
|
-
}
|
|
1557
|
-
_preserveExplicitParagraphIds(body) {
|
|
1558
|
-
body[RESTORE_INSERTED_PARAGRAPH_IDS] = true;
|
|
1559
|
-
}
|
|
1560
|
-
_findParagraphByRange(range) {
|
|
1561
|
-
var _this$_getBody$paragr5;
|
|
1562
|
-
const paragraphs = (_this$_getBody$paragr5 = this._getBody().paragraphs) !== null && _this$_getBody$paragr5 !== void 0 ? _this$_getBody$paragr5 : [];
|
|
1563
|
-
const paragraphIndex = paragraphs.findIndex((paragraph, index) => {
|
|
1564
|
-
return (index > 0 ? paragraphs[index - 1].startIndex + 1 : 0) <= range.startOffset && range.endOffset <= paragraph.startIndex;
|
|
1565
|
-
});
|
|
1566
|
-
if (paragraphIndex < 0) throw new RangeError("Range does not resolve to a paragraph.");
|
|
1567
|
-
const paragraph = paragraphs[paragraphIndex];
|
|
1568
|
-
return {
|
|
1569
|
-
paragraph,
|
|
1570
|
-
paragraphIndex,
|
|
1571
|
-
startOffset: paragraphIndex > 0 ? paragraphs[paragraphIndex - 1].startIndex + 1 : 0,
|
|
1572
|
-
endOffset: paragraph.startIndex
|
|
1573
|
-
};
|
|
1574
|
-
}
|
|
1575
941
|
_replaceBodyRange(range, insertBody) {
|
|
1576
|
-
const startOffset = range
|
|
1577
|
-
const endOffset = range.endOffset;
|
|
942
|
+
const { startOffset, endOffset } = range;
|
|
1578
943
|
const textX = new TextX();
|
|
1579
944
|
if (startOffset > 0) textX.push({
|
|
1580
945
|
t: TextXActionType.RETAIN,
|
|
@@ -1593,7 +958,7 @@ var FDocBody = class {
|
|
|
1593
958
|
}
|
|
1594
959
|
_retainBodyRange(range, body, coverType) {
|
|
1595
960
|
var _body$textRuns;
|
|
1596
|
-
if (((_body$textRuns = body.textRuns) === null || _body$textRuns === void 0 ? void 0 : _body$textRuns.length) && this.
|
|
961
|
+
if (((_body$textRuns = body.textRuns) === null || _body$textRuns === void 0 ? void 0 : _body$textRuns.length) && this.getBody().textRuns == null) this._ensureTextRuns();
|
|
1597
962
|
const textX = new TextX();
|
|
1598
963
|
if (range.startOffset > 0) textX.push({
|
|
1599
964
|
t: TextXActionType.RETAIN,
|
|
@@ -1608,73 +973,27 @@ var FDocBody = class {
|
|
|
1608
973
|
return this._executeTextX(textX);
|
|
1609
974
|
}
|
|
1610
975
|
_ensureTextRuns() {
|
|
1611
|
-
if (this._getBody().textRuns != null) return;
|
|
1612
976
|
const actions = JSONX.getInstance().replaceOp([...getRichTextEditPath(this._documentDataModel, this._segmentId), "textRuns"], void 0, []);
|
|
1613
|
-
this.
|
|
977
|
+
this._injector.get(ICommandService).syncExecuteCommand(RichTextEditingMutation.id, {
|
|
1614
978
|
unitId: this._documentDataModel.getUnitId(),
|
|
1615
979
|
segmentId: this._segmentId,
|
|
1616
980
|
actions,
|
|
1617
981
|
textRanges: [],
|
|
1618
|
-
trigger: FACADE_TRIGGER,
|
|
1619
982
|
isEditing: false
|
|
1620
983
|
});
|
|
1621
984
|
}
|
|
1622
985
|
_executeTextX(textX) {
|
|
1623
986
|
const actions = JSONX.getInstance().editOp(textX.serialize(), getRichTextEditPath(this._documentDataModel, this._segmentId));
|
|
1624
|
-
|
|
987
|
+
return this._injector.get(ICommandService).syncExecuteCommand(RichTextEditingMutation.id, {
|
|
1625
988
|
unitId: this._documentDataModel.getUnitId(),
|
|
1626
989
|
segmentId: this._segmentId,
|
|
1627
990
|
actions,
|
|
1628
991
|
textRanges: [],
|
|
1629
|
-
trigger: FACADE_TRIGGER,
|
|
1630
992
|
isEditing: false
|
|
1631
|
-
});
|
|
1632
|
-
return Boolean(result);
|
|
993
|
+
}) !== false;
|
|
1633
994
|
}
|
|
1634
995
|
};
|
|
1635
996
|
|
|
1636
|
-
//#endregion
|
|
1637
|
-
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/typeof.js
|
|
1638
|
-
function _typeof(o) {
|
|
1639
|
-
"@babel/helpers - typeof";
|
|
1640
|
-
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
1641
|
-
return typeof o;
|
|
1642
|
-
} : function(o) {
|
|
1643
|
-
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
1644
|
-
}, _typeof(o);
|
|
1645
|
-
}
|
|
1646
|
-
|
|
1647
|
-
//#endregion
|
|
1648
|
-
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPrimitive.js
|
|
1649
|
-
function toPrimitive(t, r) {
|
|
1650
|
-
if ("object" != _typeof(t) || !t) return t;
|
|
1651
|
-
var e = t[Symbol.toPrimitive];
|
|
1652
|
-
if (void 0 !== e) {
|
|
1653
|
-
var i = e.call(t, r || "default");
|
|
1654
|
-
if ("object" != _typeof(i)) return i;
|
|
1655
|
-
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
1656
|
-
}
|
|
1657
|
-
return ("string" === r ? String : Number)(t);
|
|
1658
|
-
}
|
|
1659
|
-
|
|
1660
|
-
//#endregion
|
|
1661
|
-
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/toPropertyKey.js
|
|
1662
|
-
function toPropertyKey(t) {
|
|
1663
|
-
var i = toPrimitive(t, "string");
|
|
1664
|
-
return "symbol" == _typeof(i) ? i : i + "";
|
|
1665
|
-
}
|
|
1666
|
-
|
|
1667
|
-
//#endregion
|
|
1668
|
-
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/defineProperty.js
|
|
1669
|
-
function _defineProperty(e, r, t) {
|
|
1670
|
-
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
1671
|
-
value: t,
|
|
1672
|
-
enumerable: !0,
|
|
1673
|
-
configurable: !0,
|
|
1674
|
-
writable: !0
|
|
1675
|
-
}) : e[r] = t, e;
|
|
1676
|
-
}
|
|
1677
|
-
|
|
1678
997
|
//#endregion
|
|
1679
998
|
//#region \0@oxc-project+runtime@0.137.0/helpers/esm/decorateParam.js
|
|
1680
999
|
function __decorateParam(paramIndex, decorator) {
|
|
@@ -1703,7 +1022,6 @@ let FDocument = class FDocument extends FBaseInitialable {
|
|
|
1703
1022
|
this._resourceLoaderService = _resourceLoaderService;
|
|
1704
1023
|
this._commandService = _commandService;
|
|
1705
1024
|
_defineProperty(this, "id", void 0);
|
|
1706
|
-
_defineProperty(this, "_docElementRegistry", new DocElementRegistry());
|
|
1707
1025
|
this.id = this._documentDataModel.getUnitId();
|
|
1708
1026
|
}
|
|
1709
1027
|
/**
|
|
@@ -1727,19 +1045,23 @@ let FDocument = class FDocument extends FBaseInitialable {
|
|
|
1727
1045
|
* use their persisted `paragraphId` values. Persisted elements, such as tables
|
|
1728
1046
|
* and custom blocks, use their existing ids.
|
|
1729
1047
|
*
|
|
1730
|
-
* @returns {
|
|
1048
|
+
* @returns {FDocumentBody} The document body API instance.
|
|
1731
1049
|
* @example
|
|
1732
1050
|
* ```typescript
|
|
1733
|
-
* const
|
|
1734
|
-
*
|
|
1735
|
-
*
|
|
1736
|
-
*
|
|
1737
|
-
* const
|
|
1738
|
-
*
|
|
1051
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
1052
|
+
* const fDocumentBody = fDocument.getBody();
|
|
1053
|
+
* console.log(fDocumentBody.getBody());
|
|
1054
|
+
*
|
|
1055
|
+
* const element = fDocumentBody.getElement(0);
|
|
1056
|
+
* if (element.isParagraph()) {
|
|
1057
|
+
* const paragraph = element.asParagraph();
|
|
1058
|
+
* paragraph.appendText(' updated');
|
|
1059
|
+
* console.log(paragraph.getText());
|
|
1060
|
+
* }
|
|
1739
1061
|
* ```
|
|
1740
1062
|
*/
|
|
1741
1063
|
getBody() {
|
|
1742
|
-
return
|
|
1064
|
+
return this._injector.createInstance(FDocumentBody, this._documentDataModel, this._injector);
|
|
1743
1065
|
}
|
|
1744
1066
|
dispose() {
|
|
1745
1067
|
super.dispose();
|
|
@@ -1811,155 +1133,264 @@ let FDocument = class FDocument extends FBaseInitialable {
|
|
|
1811
1133
|
this._univerInstanceService.focusUnit(this.id);
|
|
1812
1134
|
return this._commandService.syncExecuteCommand(RedoCommand.id);
|
|
1813
1135
|
}
|
|
1136
|
+
};
|
|
1137
|
+
FDocument = __decorate([
|
|
1138
|
+
__decorateParam(1, Inject(Injector)),
|
|
1139
|
+
__decorateParam(2, IUniverInstanceService),
|
|
1140
|
+
__decorateParam(3, Inject(IResourceLoaderService)),
|
|
1141
|
+
__decorateParam(4, ICommandService)
|
|
1142
|
+
], FDocument);
|
|
1143
|
+
|
|
1144
|
+
//#endregion
|
|
1145
|
+
//#region src/facade/f-univer.ts
|
|
1146
|
+
var FUniverDocsMixin = class extends FUniver {
|
|
1147
|
+
createDocument(data) {
|
|
1148
|
+
const document = this._injector.get(IUniverInstanceService).createUnit(UniverInstanceType.UNIVER_DOC, data);
|
|
1149
|
+
return this._injector.createInstance(FDocument, document);
|
|
1150
|
+
}
|
|
1151
|
+
getActiveDocument() {
|
|
1152
|
+
const document = this._univerInstanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_DOC);
|
|
1153
|
+
if (!document) return null;
|
|
1154
|
+
return this._injector.createInstance(FDocument, document);
|
|
1155
|
+
}
|
|
1156
|
+
getDocument(id) {
|
|
1157
|
+
const document = this._univerInstanceService.getUnit(id, UniverInstanceType.UNIVER_DOC);
|
|
1158
|
+
if (!document) return null;
|
|
1159
|
+
return this._injector.createInstance(FDocument, document);
|
|
1160
|
+
}
|
|
1161
|
+
};
|
|
1162
|
+
FUniver.extend(FUniverDocsMixin);
|
|
1163
|
+
|
|
1164
|
+
//#endregion
|
|
1165
|
+
//#region src/facade/f-document-block-range.ts
|
|
1166
|
+
/**
|
|
1167
|
+
* A facade wrapper for document block ranges, such as callout, quote, and code blocks.
|
|
1168
|
+
*
|
|
1169
|
+
* Block range identity is backed by the persisted `IDocumentBlockRange.blockId`,
|
|
1170
|
+
* so wrappers can be re-resolved after text is inserted before the block range.
|
|
1171
|
+
*
|
|
1172
|
+
* @hideconstructor
|
|
1173
|
+
*/
|
|
1174
|
+
var FDocumentBlockRange = class extends FDocumentElement {
|
|
1175
|
+
constructor(body, bodyEdit, info, injector) {
|
|
1176
|
+
super(body, bodyEdit, info, injector);
|
|
1177
|
+
this.body = body;
|
|
1178
|
+
this.bodyEdit = bodyEdit;
|
|
1179
|
+
this.info = info;
|
|
1180
|
+
this.injector = injector;
|
|
1181
|
+
if (this.getType() !== DocumentBlockType.BLOCK_RANGE) throw new Error(`Element type is not a block range: ${this.getType()}`);
|
|
1182
|
+
}
|
|
1814
1183
|
/**
|
|
1815
|
-
*
|
|
1816
|
-
* @
|
|
1817
|
-
* @return {boolean} `true` if the text was successfully appended, or `false` if it failed.
|
|
1184
|
+
* Get the top-level block range data model.
|
|
1185
|
+
* @returns {IDocumentBlockRange} The block range data model.
|
|
1818
1186
|
* @example
|
|
1819
|
-
* ```
|
|
1187
|
+
* ```ts
|
|
1820
1188
|
* const fDocument = univerAPI.getActiveDocument();
|
|
1821
|
-
* const
|
|
1822
|
-
*
|
|
1189
|
+
* const fDocumentBody = fDocument.getBody();
|
|
1190
|
+
* const element = fDocumentBody.getElement(0);
|
|
1191
|
+
*
|
|
1192
|
+
* if (element?.isBlockRange()) {
|
|
1193
|
+
* const blockRange = element.asBlockRange();
|
|
1194
|
+
* console.log(blockRange.getBlockRange());
|
|
1195
|
+
* }
|
|
1823
1196
|
* ```
|
|
1824
1197
|
*/
|
|
1825
|
-
|
|
1826
|
-
const {
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
return
|
|
1830
|
-
startOffset: lastPosition,
|
|
1831
|
-
endOffset: lastPosition,
|
|
1832
|
-
segmentId: ""
|
|
1833
|
-
});
|
|
1198
|
+
getBlockRange() {
|
|
1199
|
+
const { blockRanges = [] } = this._body.getBody();
|
|
1200
|
+
const blockRange = blockRanges.find((blockRange) => blockRange.blockId === this.getKey());
|
|
1201
|
+
if (!blockRange) throw new Error(`Block range not found: ${this.getKey()}`);
|
|
1202
|
+
return blockRange;
|
|
1834
1203
|
}
|
|
1835
1204
|
/**
|
|
1836
|
-
*
|
|
1837
|
-
* @
|
|
1838
|
-
* @param {IDocumentInsertTextFacadeOptions} options - Optional target range, segment id, and cursor offset.
|
|
1839
|
-
* @returns {boolean} `true` if the text was successfully inserted, or `false` if it failed.
|
|
1205
|
+
* Get the block range type.
|
|
1206
|
+
* @returns {DocumentBlockRangeType} The block type, such as callout, quote, or code.
|
|
1840
1207
|
* @example
|
|
1841
|
-
*
|
|
1842
|
-
* // Insert text at a specific range in the document body
|
|
1843
|
-
* ```typescript
|
|
1208
|
+
* ```ts
|
|
1844
1209
|
* const fDocument = univerAPI.getActiveDocument();
|
|
1845
|
-
* const
|
|
1846
|
-
*
|
|
1847
|
-
*
|
|
1848
|
-
*
|
|
1849
|
-
*
|
|
1850
|
-
*
|
|
1851
|
-
*
|
|
1210
|
+
* const fDocumentBody = fDocument.getBody();
|
|
1211
|
+
* const element = fDocumentBody.getElement(0);
|
|
1212
|
+
*
|
|
1213
|
+
* if (element?.isBlockRange()) {
|
|
1214
|
+
* const blockRange = element.asBlockRange();
|
|
1215
|
+
* console.log(blockRange.getBlockType());
|
|
1216
|
+
* }
|
|
1852
1217
|
* ```
|
|
1218
|
+
*/
|
|
1219
|
+
getBlockType() {
|
|
1220
|
+
return this.getBlockRange().blockType;
|
|
1221
|
+
}
|
|
1222
|
+
/**
|
|
1223
|
+
* Get the plain text inside this block range.
|
|
1224
|
+
* @returns {string} The block range text.
|
|
1225
|
+
* @example
|
|
1226
|
+
* ```ts
|
|
1227
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
1228
|
+
* const fDocumentBody = fDocument.getBody();
|
|
1229
|
+
* const element = fDocumentBody.getElement(0);
|
|
1853
1230
|
*
|
|
1854
|
-
*
|
|
1855
|
-
*
|
|
1231
|
+
* if (element?.isBlockRange()) {
|
|
1232
|
+
* const blockRange = element.asBlockRange();
|
|
1233
|
+
* console.log(blockRange.getText());
|
|
1234
|
+
* }
|
|
1235
|
+
* ```
|
|
1236
|
+
*/
|
|
1237
|
+
getText() {
|
|
1238
|
+
const { dataStream } = this._body.getBody();
|
|
1239
|
+
const { startIndex, endIndex } = this.getBlockRange();
|
|
1240
|
+
return dataStream.slice(startIndex, endIndex);
|
|
1241
|
+
}
|
|
1242
|
+
/**
|
|
1243
|
+
* Replace the plain text inside this block range.
|
|
1244
|
+
* @param {string} text The replacement text.
|
|
1245
|
+
* @returns {boolean} `true` if the block range text was replaced.
|
|
1246
|
+
* @example
|
|
1247
|
+
* ```ts
|
|
1856
1248
|
* const fDocument = univerAPI.getActiveDocument();
|
|
1857
|
-
* const
|
|
1858
|
-
* const
|
|
1249
|
+
* const fDocumentBody = fDocument.getBody();
|
|
1250
|
+
* const element = fDocumentBody.getElement(0);
|
|
1859
1251
|
*
|
|
1860
|
-
* if (
|
|
1861
|
-
*
|
|
1862
|
-
*
|
|
1863
|
-
*
|
|
1864
|
-
* startOffset: 0,
|
|
1865
|
-
* endOffset: 0,
|
|
1866
|
-
* segmentId: headerId,
|
|
1867
|
-
* });
|
|
1868
|
-
* }
|
|
1869
|
-
* }
|
|
1252
|
+
* if (element?.isBlockRange()) {
|
|
1253
|
+
* const blockRange = element.asBlockRange();
|
|
1254
|
+
* blockRange.setText('Updated block text');
|
|
1255
|
+
* console.log(blockRange.getText());
|
|
1870
1256
|
* }
|
|
1257
|
+
* ```
|
|
1258
|
+
*/
|
|
1259
|
+
setText(text) {
|
|
1260
|
+
const blockRange = this.getBlockRange();
|
|
1261
|
+
const { startIndex, endIndex } = blockRange;
|
|
1262
|
+
const updateBody = buildPlainTextInsertBody(`${text}\r`);
|
|
1263
|
+
updateBody.blockRanges = [{
|
|
1264
|
+
...blockRange,
|
|
1265
|
+
startIndex: 0,
|
|
1266
|
+
endIndex: text.length
|
|
1267
|
+
}];
|
|
1268
|
+
return this._bodyEdit.replaceRange({
|
|
1269
|
+
startOffset: startIndex,
|
|
1270
|
+
endOffset: endIndex + 1
|
|
1271
|
+
}, updateBody);
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* Remove this block range wrapper from the body.
|
|
1871
1275
|
*
|
|
1872
|
-
*
|
|
1873
|
-
*
|
|
1874
|
-
*
|
|
1875
|
-
*
|
|
1876
|
-
*
|
|
1877
|
-
*
|
|
1878
|
-
*
|
|
1879
|
-
*
|
|
1880
|
-
*
|
|
1881
|
-
*
|
|
1276
|
+
* This currently removes the block range and its content, matching
|
|
1277
|
+
* `remove()`.
|
|
1278
|
+
*
|
|
1279
|
+
* @returns {boolean} `true` if the block range content was removed.
|
|
1280
|
+
* @example
|
|
1281
|
+
* ```ts
|
|
1282
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
1283
|
+
* const fDocumentBody = fDocument.getBody();
|
|
1284
|
+
* const element = fDocumentBody.getElement(0);
|
|
1285
|
+
*
|
|
1286
|
+
* if (element?.isBlockRange()) {
|
|
1287
|
+
* const blockRange = element.asBlockRange();
|
|
1288
|
+
* const removed = blockRange.unwrap();
|
|
1289
|
+
* console.log(removed ? 'Block range removed' : 'Failed to remove block range');
|
|
1882
1290
|
* }
|
|
1883
1291
|
* ```
|
|
1884
1292
|
*/
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
});
|
|
1293
|
+
unwrap() {
|
|
1294
|
+
return this.remove();
|
|
1295
|
+
}
|
|
1296
|
+
};
|
|
1297
|
+
var FDocumentBlockRangeMixin = class extends FDocumentElement {
|
|
1298
|
+
asBlockRange() {
|
|
1299
|
+
if (this.getType() !== DocumentBlockType.BLOCK_RANGE) throw new Error(`Element type is not a block range: ${this.getType()}`);
|
|
1300
|
+
return this._injector.createInstance(FDocumentBlockRange, this._body, this._bodyEdit, this.getResolvedInfo(), this._injector);
|
|
1301
|
+
}
|
|
1302
|
+
};
|
|
1303
|
+
FDocumentElement.extend(FDocumentBlockRangeMixin);
|
|
1304
|
+
|
|
1305
|
+
//#endregion
|
|
1306
|
+
//#region src/facade/f-document-custom-block.ts
|
|
1307
|
+
/**
|
|
1308
|
+
* A facade wrapper for document top-level custom blocks.
|
|
1309
|
+
* @hideconstructor
|
|
1310
|
+
*/
|
|
1311
|
+
var FDocumentCustomBlock = class extends FDocumentElement {
|
|
1312
|
+
constructor(body, bodyEdit, info, injector) {
|
|
1313
|
+
super(body, bodyEdit, info, injector);
|
|
1314
|
+
this.body = body;
|
|
1315
|
+
this.bodyEdit = bodyEdit;
|
|
1316
|
+
this.info = info;
|
|
1317
|
+
this.injector = injector;
|
|
1318
|
+
if (this.getType() !== DocumentBlockType.CUSTOM_BLOCK) throw new Error(`Element type is not a custom block: ${this.getType()}`);
|
|
1912
1319
|
}
|
|
1913
1320
|
/**
|
|
1914
|
-
*
|
|
1915
|
-
* @
|
|
1916
|
-
* @param {IDocumentInsertTextFacadeOptions} options - Optional target range, segment id, and cursor offset.
|
|
1917
|
-
* @returns {boolean} `true` if the paragraphs were successfully inserted, or `false` if it failed.
|
|
1321
|
+
* Get the custom block marker.
|
|
1322
|
+
* @returns {ICustomBlock} The custom block marker.
|
|
1918
1323
|
* @example
|
|
1919
|
-
* ```
|
|
1324
|
+
* ```ts
|
|
1920
1325
|
* const fDocument = univerAPI.getActiveDocument();
|
|
1921
|
-
* const
|
|
1922
|
-
*
|
|
1923
|
-
*
|
|
1924
|
-
*
|
|
1925
|
-
*
|
|
1326
|
+
* const fDocumentBody = fDocument.getBody();
|
|
1327
|
+
* const element = fDocumentBody.getElement(0);
|
|
1328
|
+
*
|
|
1329
|
+
* if (element?.isCustomBlock()) {
|
|
1330
|
+
* const customBlock = element.asCustomBlock();
|
|
1331
|
+
* console.log(customBlock.getCustomBlock());
|
|
1332
|
+
* }
|
|
1926
1333
|
* ```
|
|
1927
1334
|
*/
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
const
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
cursorOffset: (_options$cursorOffset = options.cursorOffset) !== null && _options$cursorOffset !== void 0 ? _options$cursorOffset : dataStream.length
|
|
1934
|
-
});
|
|
1335
|
+
getCustomBlock() {
|
|
1336
|
+
const { customBlocks = [] } = this._body.getBody();
|
|
1337
|
+
const block = customBlocks.find((item) => item.blockId === this.getKey());
|
|
1338
|
+
if (!block) throw new Error("Doc custom block is stale");
|
|
1339
|
+
return block;
|
|
1935
1340
|
}
|
|
1936
1341
|
};
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1342
|
+
var FDocumentCustomBlockMixin = class extends FDocumentElement {
|
|
1343
|
+
asCustomBlock() {
|
|
1344
|
+
if (this.getType() !== DocumentBlockType.CUSTOM_BLOCK) throw new Error(`Element type is not a custom block: ${this.getType()}`);
|
|
1345
|
+
return this._injector.createInstance(FDocumentCustomBlock, this._body, this._bodyEdit, this.getResolvedInfo(), this._injector);
|
|
1346
|
+
}
|
|
1347
|
+
};
|
|
1348
|
+
FDocumentElement.extend(FDocumentCustomBlockMixin);
|
|
1943
1349
|
|
|
1944
1350
|
//#endregion
|
|
1945
|
-
//#region src/facade/f-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1351
|
+
//#region src/facade/f-document-table.ts
|
|
1352
|
+
/**
|
|
1353
|
+
* A facade wrapper for document top-level tables.
|
|
1354
|
+
* @hideconstructor
|
|
1355
|
+
*/
|
|
1356
|
+
var FDocumentTable = class extends FDocumentElement {
|
|
1357
|
+
constructor(body, bodyEdit, info, injector) {
|
|
1358
|
+
super(body, bodyEdit, info, injector);
|
|
1359
|
+
this.body = body;
|
|
1360
|
+
this.bodyEdit = bodyEdit;
|
|
1361
|
+
this.info = info;
|
|
1362
|
+
this.injector = injector;
|
|
1363
|
+
if (this.getType() !== DocumentBlockType.TABLE) throw new Error(`Element type is not a table: ${this.getType()}`);
|
|
1950
1364
|
}
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1365
|
+
/**
|
|
1366
|
+
* Get the table marker.
|
|
1367
|
+
* @returns {ICustomTable} The table marker.
|
|
1368
|
+
* @example
|
|
1369
|
+
* ```ts
|
|
1370
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
1371
|
+
* const fDocumentBody = fDocument.getBody();
|
|
1372
|
+
* const element = fDocumentBody.getElement(0);
|
|
1373
|
+
*
|
|
1374
|
+
* if (element?.isTable()) {
|
|
1375
|
+
* const table = element.asTable();
|
|
1376
|
+
* console.log(table.getTable());
|
|
1377
|
+
* }
|
|
1378
|
+
* ```
|
|
1379
|
+
*/
|
|
1380
|
+
getTable() {
|
|
1381
|
+
const { tables = [] } = this._body.getBody();
|
|
1382
|
+
const table = tables.find((item) => item.tableId === this.getKey());
|
|
1383
|
+
if (!table) throw new Error("Doc table is stale");
|
|
1384
|
+
return table;
|
|
1955
1385
|
}
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1386
|
+
};
|
|
1387
|
+
var FDocumentTableMixin = class extends FDocumentElement {
|
|
1388
|
+
asTable() {
|
|
1389
|
+
if (this.getType() !== DocumentBlockType.TABLE) throw new Error(`Element type is not a table: ${this.getType()}`);
|
|
1390
|
+
return this._injector.createInstance(FDocumentTable, this._body, this._bodyEdit, this.getResolvedInfo(), this._injector);
|
|
1960
1391
|
}
|
|
1961
1392
|
};
|
|
1962
|
-
|
|
1393
|
+
FDocumentElement.extend(FDocumentTableMixin);
|
|
1963
1394
|
|
|
1964
1395
|
//#endregion
|
|
1965
|
-
export {
|
|
1396
|
+
export { FDocument, FDocumentBlockRange, FDocumentBody, FDocumentCustomBlock, FDocumentElement, FDocumentParagraph, FDocumentTable };
|