@univerjs/docs 0.24.0 → 0.25.0-insiders.20260608-e4336f7
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/README.md +1 -1
- package/lib/cjs/facade.js +351 -0
- package/lib/cjs/index.js +372 -35
- package/lib/es/facade.js +345 -0
- package/lib/es/index.js +360 -34
- package/lib/facade.js +345 -0
- package/lib/index.js +360 -34
- package/lib/types/commands/commands/core-editing.command.d.ts +57 -0
- package/lib/types/facade/f-document.d.ts +178 -0
- package/lib/types/facade/f-univer.d.ts +64 -0
- package/lib/types/facade/index.d.ts +18 -0
- package/lib/types/facade/utils.d.ts +26 -0
- package/lib/types/index.d.ts +3 -0
- package/lib/types/services/doc-content-insert.service.d.ts +28 -0
- package/lib/types/services/doc-state-change-manager.service.d.ts +53 -0
- package/lib/types/utils/custom-range-factory.d.ts +1 -5
- package/lib/umd/facade.js +5 -0
- package/lib/umd/index.js +1 -1
- package/package.json +15 -5
- package/LICENSE +0 -176
package/lib/es/facade.js
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { ICommandService, IResourceLoaderService, IUniverInstanceService, Inject, Injector, RedoCommand, UndoCommand, UniverInstanceType } from "@univerjs/core";
|
|
2
|
+
import { FBaseInitialable, FUniver } from "@univerjs/core/facade";
|
|
3
|
+
import { InsertTextCommand } from "@univerjs/docs";
|
|
4
|
+
|
|
5
|
+
//#region src/facade/utils.ts
|
|
6
|
+
function cloneParagraphStyle(paragraphStyle) {
|
|
7
|
+
return paragraphStyle == null ? paragraphStyle : JSON.parse(JSON.stringify(paragraphStyle));
|
|
8
|
+
}
|
|
9
|
+
function normalizePlainTextDataStream(dataStream) {
|
|
10
|
+
return dataStream.replace(/\r\n/g, "\r").replace(/\n/g, "\r");
|
|
11
|
+
}
|
|
12
|
+
function getRemovedLeadingParagraphBreakLength(dataStream, removeLeadingParagraphBreak) {
|
|
13
|
+
const normalized = normalizePlainTextDataStream(dataStream);
|
|
14
|
+
if (removeLeadingParagraphBreak && normalized.length > 1 && normalized.startsWith("\r")) return 1;
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
function getNormalizedPlainTextCursorOffset(dataStream, cursorOffset, removeLeadingParagraphBreak) {
|
|
18
|
+
const normalizedPrefixLength = normalizePlainTextDataStream(dataStream.slice(0, cursorOffset)).length;
|
|
19
|
+
return Math.max(0, normalizedPrefixLength - getRemovedLeadingParagraphBreakLength(dataStream, removeLeadingParagraphBreak));
|
|
20
|
+
}
|
|
21
|
+
function getParagraphStyleAtOffset(body, offset) {
|
|
22
|
+
var _body$paragraphs, _paragraphs$find;
|
|
23
|
+
const paragraphs = (_body$paragraphs = body.paragraphs) !== null && _body$paragraphs !== void 0 ? _body$paragraphs : [];
|
|
24
|
+
const paragraph = (_paragraphs$find = paragraphs.find((item) => item.startIndex >= offset)) !== null && _paragraphs$find !== void 0 ? _paragraphs$find : paragraphs[paragraphs.length - 1];
|
|
25
|
+
return paragraph === null || paragraph === void 0 ? void 0 : paragraph.paragraphStyle;
|
|
26
|
+
}
|
|
27
|
+
function buildPlainTextInsertBody(dataStream, options = {}) {
|
|
28
|
+
const normalizedDataStream = normalizePlainTextDataStream(dataStream).slice(getRemovedLeadingParagraphBreakLength(dataStream, options.removeLeadingParagraphBreak));
|
|
29
|
+
const body = {
|
|
30
|
+
dataStream: normalizedDataStream,
|
|
31
|
+
customDecorations: [],
|
|
32
|
+
customRanges: [],
|
|
33
|
+
textRuns: []
|
|
34
|
+
};
|
|
35
|
+
const paragraphs = [];
|
|
36
|
+
for (let index = 0; index < normalizedDataStream.length; index++) if (normalizedDataStream[index] === "\r") paragraphs.push({
|
|
37
|
+
startIndex: index,
|
|
38
|
+
...options.paragraphStyle == null ? {} : { paragraphStyle: cloneParagraphStyle(options.paragraphStyle) }
|
|
39
|
+
});
|
|
40
|
+
if (paragraphs.length > 0) body.paragraphs = paragraphs;
|
|
41
|
+
return body;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/typeof.js
|
|
46
|
+
function _typeof(o) {
|
|
47
|
+
"@babel/helpers - typeof";
|
|
48
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
49
|
+
return typeof o;
|
|
50
|
+
} : function(o) {
|
|
51
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
52
|
+
}, _typeof(o);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/toPrimitive.js
|
|
57
|
+
function toPrimitive(t, r) {
|
|
58
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
59
|
+
var e = t[Symbol.toPrimitive];
|
|
60
|
+
if (void 0 !== e) {
|
|
61
|
+
var i = e.call(t, r || "default");
|
|
62
|
+
if ("object" != _typeof(i)) return i;
|
|
63
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
64
|
+
}
|
|
65
|
+
return ("string" === r ? String : Number)(t);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/toPropertyKey.js
|
|
70
|
+
function toPropertyKey(t) {
|
|
71
|
+
var i = toPrimitive(t, "string");
|
|
72
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/defineProperty.js
|
|
77
|
+
function _defineProperty(e, r, t) {
|
|
78
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
79
|
+
value: t,
|
|
80
|
+
enumerable: !0,
|
|
81
|
+
configurable: !0,
|
|
82
|
+
writable: !0
|
|
83
|
+
}) : e[r] = t, e;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/decorateParam.js
|
|
88
|
+
function __decorateParam(paramIndex, decorator) {
|
|
89
|
+
return function(target, key) {
|
|
90
|
+
decorator(target, key, paramIndex);
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
//#endregion
|
|
95
|
+
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/decorate.js
|
|
96
|
+
function __decorate(decorators, target, key, desc) {
|
|
97
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
98
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
99
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
100
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/facade/f-document.ts
|
|
105
|
+
let FDocument = class FDocument extends FBaseInitialable {
|
|
106
|
+
constructor(_documentDataModel, _injector, _univerInstanceService, _resourceLoaderService, _commandService) {
|
|
107
|
+
super(_injector);
|
|
108
|
+
this._documentDataModel = _documentDataModel;
|
|
109
|
+
this._injector = _injector;
|
|
110
|
+
this._univerInstanceService = _univerInstanceService;
|
|
111
|
+
this._resourceLoaderService = _resourceLoaderService;
|
|
112
|
+
this._commandService = _commandService;
|
|
113
|
+
_defineProperty(this, "id", void 0);
|
|
114
|
+
this.id = this._documentDataModel.getUnitId();
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get the document data model of the document.
|
|
118
|
+
* @returns {DocumentDataModel} The document data model.
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
122
|
+
* const documentDataModel = fDocument.getDocumentDataModel();
|
|
123
|
+
* console.log(documentDataModel);
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
getDocumentDataModel() {
|
|
127
|
+
return this._documentDataModel;
|
|
128
|
+
}
|
|
129
|
+
dispose() {
|
|
130
|
+
super.dispose();
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get the document id.
|
|
134
|
+
* @returns {string} The document id.
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
138
|
+
* const unitId = fDocument.getId();
|
|
139
|
+
* console.log(unitId);
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
getId() {
|
|
143
|
+
return this.id;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get the document name.
|
|
147
|
+
* @returns {string} The document name.
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
151
|
+
* const name = fDocument.getName();
|
|
152
|
+
* console.log(name);
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
getName() {
|
|
156
|
+
return this._documentDataModel.getTitle() || "";
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Save the document snapshot data, including the document content and resource data, etc.
|
|
160
|
+
* @returns {IDocumentData} The document snapshot data.
|
|
161
|
+
* @example
|
|
162
|
+
* ```typescript
|
|
163
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
164
|
+
* const snapshot = fDocument.save();
|
|
165
|
+
* console.log(snapshot);
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
save() {
|
|
169
|
+
return this._resourceLoaderService.saveUnit(this._documentDataModel.getUnitId());
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Undo the last operation in the document.
|
|
173
|
+
* @returns {Promise<boolean>} A promise that resolves to true if the undo operation was successful, or false if it failed.
|
|
174
|
+
* @example
|
|
175
|
+
* ```typescript
|
|
176
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
177
|
+
* await fDocument.undo();
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
undo() {
|
|
181
|
+
this._univerInstanceService.focusUnit(this.id);
|
|
182
|
+
return this._commandService.executeCommand(UndoCommand.id);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Redo the last undone operation in the document.
|
|
186
|
+
* @returns {Promise<boolean>} A promise that resolves to true if the redo operation was successful, or false if it failed.
|
|
187
|
+
* @example
|
|
188
|
+
* ```typescript
|
|
189
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
190
|
+
* await fDocument.redo();
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
redo() {
|
|
194
|
+
this._univerInstanceService.focusUnit(this.id);
|
|
195
|
+
return this._commandService.executeCommand(RedoCommand.id);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Adds the specified text to the end of this text region.
|
|
199
|
+
* @param {string} text - The text to be added to the end of this text region.
|
|
200
|
+
* @return {Promise<boolean>} A promise that resolves to true if the text was successfully appended, or false if it failed.
|
|
201
|
+
* @example
|
|
202
|
+
* ```typescript
|
|
203
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
204
|
+
* await fDocument.appendText('Hello, world!');
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
appendText(text) {
|
|
208
|
+
const { body } = this.save();
|
|
209
|
+
if (!body) throw new Error("The document body is empty");
|
|
210
|
+
const lastPosition = body.dataStream.length - 2;
|
|
211
|
+
return this.insertText(text, {
|
|
212
|
+
startOffset: lastPosition,
|
|
213
|
+
endOffset: lastPosition,
|
|
214
|
+
segmentId: ""
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Inserts text at the provided document range. Defaults to appending before the final section break.
|
|
219
|
+
* @param {string} text - The text to insert.
|
|
220
|
+
* @param {IDocumentInsertTextFacadeOptions} options - Optional target range, segment id, and cursor offset.
|
|
221
|
+
* @returns {Promise<boolean>} A promise that resolves to true if the text was successfully inserted, or false if it failed.
|
|
222
|
+
* @example
|
|
223
|
+
*
|
|
224
|
+
* // Insert text at a specific range in the document body
|
|
225
|
+
* ```typescript
|
|
226
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
227
|
+
* await fDocument.insertText('Hello, world!', {
|
|
228
|
+
* startOffset: 5,
|
|
229
|
+
* endOffset: 5,
|
|
230
|
+
* segmentId: '',
|
|
231
|
+
* cursorOffset: 13,
|
|
232
|
+
* });
|
|
233
|
+
* ```
|
|
234
|
+
*
|
|
235
|
+
* // Insert text at the beginning of a header or footer segment
|
|
236
|
+
* ```typescript
|
|
237
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
238
|
+
* const snapshot = fDocument.save();
|
|
239
|
+
* const { headers, footers } = snapshot;
|
|
240
|
+
*
|
|
241
|
+
* if (headers) {
|
|
242
|
+
* for (const headerId in headers) {
|
|
243
|
+
* if (headerId === 'target-header-id') {
|
|
244
|
+
* await fDocument.insertText('Hello, header!', {
|
|
245
|
+
* startOffset: 0,
|
|
246
|
+
* endOffset: 0,
|
|
247
|
+
* segmentId: headerId,
|
|
248
|
+
* });
|
|
249
|
+
* }
|
|
250
|
+
* }
|
|
251
|
+
* }
|
|
252
|
+
*
|
|
253
|
+
* if (footers) {
|
|
254
|
+
* for (const footerId in footers) {
|
|
255
|
+
* if (footerId === 'target-footer-id') {
|
|
256
|
+
* await fDocument.insertText('Hello, footer!', {
|
|
257
|
+
* startOffset: 0,
|
|
258
|
+
* endOffset: 0,
|
|
259
|
+
* segmentId: footerId,
|
|
260
|
+
* });
|
|
261
|
+
* }
|
|
262
|
+
* }
|
|
263
|
+
* }
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
insertText(text, options = {}) {
|
|
267
|
+
var _options$startOffset, _options$endOffset, _options$segmentId;
|
|
268
|
+
const unitId = this.id;
|
|
269
|
+
const { body } = this.save();
|
|
270
|
+
if (!body) throw new Error("The document body is empty");
|
|
271
|
+
const startOffset = (_options$startOffset = options.startOffset) !== null && _options$startOffset !== void 0 ? _options$startOffset : Math.max(0, body.dataStream.length - 2);
|
|
272
|
+
const endOffset = (_options$endOffset = options.endOffset) !== null && _options$endOffset !== void 0 ? _options$endOffset : startOffset;
|
|
273
|
+
const segmentId = (_options$segmentId = options.segmentId) !== null && _options$segmentId !== void 0 ? _options$segmentId : "";
|
|
274
|
+
const activeRange = {
|
|
275
|
+
startOffset,
|
|
276
|
+
endOffset,
|
|
277
|
+
collapsed: startOffset === endOffset,
|
|
278
|
+
segmentId
|
|
279
|
+
};
|
|
280
|
+
const removeLeadingParagraphBreak = startOffset === 0;
|
|
281
|
+
const insertBody = buildPlainTextInsertBody(text, {
|
|
282
|
+
paragraphStyle: getParagraphStyleAtOffset(body, startOffset),
|
|
283
|
+
removeLeadingParagraphBreak
|
|
284
|
+
});
|
|
285
|
+
const cursorOffset = options.cursorOffset == null ? void 0 : getNormalizedPlainTextCursorOffset(text, options.cursorOffset, removeLeadingParagraphBreak);
|
|
286
|
+
return this._commandService.executeCommand(InsertTextCommand.id, {
|
|
287
|
+
unitId,
|
|
288
|
+
body: insertBody,
|
|
289
|
+
range: activeRange,
|
|
290
|
+
segmentId,
|
|
291
|
+
...cursorOffset == null ? {} : { cursorOffset }
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Inserts one or more plain-text paragraphs at the provided document range.
|
|
296
|
+
* @param {string} text - The paragraph text to insert. Newlines are normalized to document paragraph separators.
|
|
297
|
+
* @param {IDocumentInsertTextFacadeOptions} options - Optional target range, segment id, and cursor offset.
|
|
298
|
+
* @returns {Promise<boolean>} A promise that resolves to true if the paragraphs were successfully inserted, or false if it failed.
|
|
299
|
+
* @example
|
|
300
|
+
* ```typescript
|
|
301
|
+
* const fDocument = univerAPI.getActiveDocument();
|
|
302
|
+
* await fDocument.insertParagraph('Hello, world! This is a new paragraph.', {
|
|
303
|
+
* startOffset: 5,
|
|
304
|
+
* endOffset: 5,
|
|
305
|
+
* });
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
insertParagraph(text = "", options = {}) {
|
|
309
|
+
var _options$cursorOffset;
|
|
310
|
+
const dataStream = `${text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").join("\r\n")}\r\n`;
|
|
311
|
+
return this.insertText(dataStream, {
|
|
312
|
+
...options,
|
|
313
|
+
cursorOffset: (_options$cursorOffset = options.cursorOffset) !== null && _options$cursorOffset !== void 0 ? _options$cursorOffset : dataStream.length
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
FDocument = __decorate([
|
|
318
|
+
__decorateParam(1, Inject(Injector)),
|
|
319
|
+
__decorateParam(2, IUniverInstanceService),
|
|
320
|
+
__decorateParam(3, Inject(IResourceLoaderService)),
|
|
321
|
+
__decorateParam(4, ICommandService)
|
|
322
|
+
], FDocument);
|
|
323
|
+
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/facade/f-univer.ts
|
|
326
|
+
var FUniverDocsMixin = class extends FUniver {
|
|
327
|
+
createDocument(data) {
|
|
328
|
+
const document = this._injector.get(IUniverInstanceService).createUnit(UniverInstanceType.UNIVER_DOC, data);
|
|
329
|
+
return this._injector.createInstance(FDocument, document);
|
|
330
|
+
}
|
|
331
|
+
getActiveDocument() {
|
|
332
|
+
const document = this._univerInstanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_DOC);
|
|
333
|
+
if (!document) return null;
|
|
334
|
+
return this._injector.createInstance(FDocument, document);
|
|
335
|
+
}
|
|
336
|
+
getDocument(id) {
|
|
337
|
+
const document = this._univerInstanceService.getUnit(id, UniverInstanceType.UNIVER_DOC);
|
|
338
|
+
if (!document) return null;
|
|
339
|
+
return this._injector.createInstance(FDocument, document);
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
FUniver.extend(FUniverDocsMixin);
|
|
343
|
+
|
|
344
|
+
//#endregion
|
|
345
|
+
export { FDocument };
|