@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/index.js CHANGED
@@ -532,7 +532,7 @@ const UpdateTextCommand = {
532
532
  //#endregion
533
533
  //#region package.json
534
534
  var name = "@univerjs/docs";
535
- var version = "1.0.0-alpha.0";
535
+ var version = "1.0.0-alpha.1";
536
536
 
537
537
  //#endregion
538
538
  //#region src/commands/mutations/docs-rename.mutation.ts
@@ -621,6 +621,33 @@ DocCustomRangeController = __decorate([
621
621
  __decorateParam(2, IUniverInstanceService)
622
622
  ], DocCustomRangeController);
623
623
 
624
+ //#endregion
625
+ //#region src/services/doc-block-move-validator.service.ts
626
+ var DocBlockMoveValidatorService = class extends Disposable {
627
+ constructor(..._args) {
628
+ super(..._args);
629
+ _defineProperty(this, "_validators", []);
630
+ _defineProperty(this, "_transformers", []);
631
+ }
632
+ registerValidator(validator) {
633
+ this._validators.push(validator);
634
+ return this.disposeWithMe(toDisposable(() => remove(this._validators, validator)));
635
+ }
636
+ registerTransformer(transformer) {
637
+ this._transformers.push(transformer);
638
+ return this.disposeWithMe(toDisposable(() => remove(this._transformers, transformer)));
639
+ }
640
+ canMoveBlock(context) {
641
+ return this._validators.every((validator) => validator(context));
642
+ }
643
+ transformMoveResult(context) {
644
+ return this._transformers.reduce((result, transformer) => transformer({
645
+ ...context,
646
+ result
647
+ }), context.result);
648
+ }
649
+ };
650
+
624
651
  //#endregion
625
652
  //#region src/services/doc-content-insert.service.ts
626
653
  /**
@@ -839,6 +866,7 @@ let UniverDocsPlugin = class UniverDocsPlugin extends Plugin {
839
866
  [DocSelectionManagerService],
840
867
  [DocStateEmitService],
841
868
  [DocStateChangeManagerService],
869
+ [DocBlockMoveValidatorService],
842
870
  [DocContentInsertService],
843
871
  [DocCustomRangeController]
844
872
  ].forEach((d) => this._injector.add(d));
@@ -1064,4 +1092,4 @@ function replaceSelectionFactory(accessor, params) {
1064
1092
  }
1065
1093
 
1066
1094
  //#endregion
1067
- export { DOC_INTERCEPTOR_POINT, DeleteTextCommand, DocContentInsertService, DocInterceptorService, DocSelectionManagerService, DocSkeletonManagerService, DocStateChangeManagerService, DocStateEmitService, IDocStateChangeInterceptorService, InsertTextCommand, RichTextEditingMutation, SetTextSelectionsOperation, UniverDocsPlugin, UpdateTextCommand, addCustomRangeBySelectionFactory, addCustomRangeFactory, deleteCustomRangeFactory, replaceSelectionFactory };
1095
+ export { DOC_INTERCEPTOR_POINT, DeleteTextCommand, DocBlockMoveValidatorService, DocContentInsertService, DocInterceptorService, DocSelectionManagerService, DocSkeletonManagerService, DocStateChangeManagerService, DocStateEmitService, IDocStateChangeInterceptorService, InsertTextCommand, RichTextEditingMutation, SetTextSelectionsOperation, UniverDocsPlugin, UpdateTextCommand, addCustomRangeBySelectionFactory, addCustomRangeFactory, deleteCustomRangeFactory, replaceSelectionFactory };
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Copyright 2023-present DreamNum Co., Ltd.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import type { DocumentBlockRangeType, IDocumentBlockRange, Injector } from '@univerjs/core';
17
+ import type { FDocumentBody, IFDocumentBodyEdit } from './f-document-body';
18
+ import type { IFDocumentElementInfo } from './f-document-element';
19
+ import { FDocumentElement } from './f-document-element';
20
+ interface IFDocumentBlockRangeMixin {
21
+ asBlockRange(): FDocumentBlockRange;
22
+ }
23
+ /**
24
+ * A facade wrapper for document block ranges, such as callout, quote, and code blocks.
25
+ *
26
+ * Block range identity is backed by the persisted `IDocumentBlockRange.blockId`,
27
+ * so wrappers can be re-resolved after text is inserted before the block range.
28
+ *
29
+ * @hideconstructor
30
+ */
31
+ export declare class FDocumentBlockRange extends FDocumentElement {
32
+ protected readonly body: FDocumentBody;
33
+ protected readonly bodyEdit: IFDocumentBodyEdit;
34
+ protected readonly info: IFDocumentElementInfo;
35
+ protected readonly injector: Injector;
36
+ constructor(body: FDocumentBody, bodyEdit: IFDocumentBodyEdit, info: IFDocumentElementInfo, injector: Injector);
37
+ /**
38
+ * Get the top-level block range data model.
39
+ * @returns {IDocumentBlockRange} The block range data model.
40
+ * @example
41
+ * ```ts
42
+ * const fDocument = univerAPI.getActiveDocument();
43
+ * const fDocumentBody = fDocument.getBody();
44
+ * const element = fDocumentBody.getElement(0);
45
+ *
46
+ * if (element?.isBlockRange()) {
47
+ * const blockRange = element.asBlockRange();
48
+ * console.log(blockRange.getBlockRange());
49
+ * }
50
+ * ```
51
+ */
52
+ getBlockRange(): IDocumentBlockRange;
53
+ /**
54
+ * Get the block range type.
55
+ * @returns {DocumentBlockRangeType} The block type, such as callout, quote, or code.
56
+ * @example
57
+ * ```ts
58
+ * const fDocument = univerAPI.getActiveDocument();
59
+ * const fDocumentBody = fDocument.getBody();
60
+ * const element = fDocumentBody.getElement(0);
61
+ *
62
+ * if (element?.isBlockRange()) {
63
+ * const blockRange = element.asBlockRange();
64
+ * console.log(blockRange.getBlockType());
65
+ * }
66
+ * ```
67
+ */
68
+ getBlockType(): DocumentBlockRangeType;
69
+ /**
70
+ * Get the plain text inside this block range.
71
+ * @returns {string} The block range text.
72
+ * @example
73
+ * ```ts
74
+ * const fDocument = univerAPI.getActiveDocument();
75
+ * const fDocumentBody = fDocument.getBody();
76
+ * const element = fDocumentBody.getElement(0);
77
+ *
78
+ * if (element?.isBlockRange()) {
79
+ * const blockRange = element.asBlockRange();
80
+ * console.log(blockRange.getText());
81
+ * }
82
+ * ```
83
+ */
84
+ getText(): string;
85
+ /**
86
+ * Replace the plain text inside this block range.
87
+ * @param {string} text The replacement text.
88
+ * @returns {boolean} `true` if the block range text was replaced.
89
+ * @example
90
+ * ```ts
91
+ * const fDocument = univerAPI.getActiveDocument();
92
+ * const fDocumentBody = fDocument.getBody();
93
+ * const element = fDocumentBody.getElement(0);
94
+ *
95
+ * if (element?.isBlockRange()) {
96
+ * const blockRange = element.asBlockRange();
97
+ * blockRange.setText('Updated block text');
98
+ * console.log(blockRange.getText());
99
+ * }
100
+ * ```
101
+ */
102
+ setText(text: string): boolean;
103
+ /**
104
+ * Remove this block range wrapper from the body.
105
+ *
106
+ * This currently removes the block range and its content, matching
107
+ * `remove()`.
108
+ *
109
+ * @returns {boolean} `true` if the block range content was removed.
110
+ * @example
111
+ * ```ts
112
+ * const fDocument = univerAPI.getActiveDocument();
113
+ * const fDocumentBody = fDocument.getBody();
114
+ * const element = fDocumentBody.getElement(0);
115
+ *
116
+ * if (element?.isBlockRange()) {
117
+ * const blockRange = element.asBlockRange();
118
+ * const removed = blockRange.unwrap();
119
+ * console.log(removed ? 'Block range removed' : 'Failed to remove block range');
120
+ * }
121
+ * ```
122
+ */
123
+ unwrap(): boolean;
124
+ }
125
+ export declare class FDocumentBlockRangeMixin extends FDocumentElement {
126
+ asBlockRange(): FDocumentBlockRange;
127
+ }
128
+ declare module '@univerjs/docs/facade' {
129
+ interface FDocumentElement extends IFDocumentBlockRangeMixin {
130
+ }
131
+ }
132
+ export {};
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Copyright 2023-present DreamNum Co., Ltd.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import type { DocumentDataModel, IDocumentBody, Injector, ITextStyle } from '@univerjs/core';
17
+ import type { FDocumentBlockRange } from './f-document-block-range';
18
+ import type { FDocumentCustomBlock } from './f-document-custom-block';
19
+ import type { IFDocumentElementInfo } from './f-document-element';
20
+ import type { FDocumentTable } from './f-document-table';
21
+ import { UpdateDocsAttributeType } from '@univerjs/core';
22
+ import { FDocumentElement } from './f-document-element';
23
+ import { FDocumentParagraph } from './f-document-paragraph';
24
+ /**
25
+ * A text range in a document segment. Offsets are zero-based positions in the segment data stream.
26
+ */
27
+ export interface IFDocumentTextRange {
28
+ /** The inclusive start offset of the range. */
29
+ startOffset: number;
30
+ /** The exclusive end offset of the range. */
31
+ endOffset: number;
32
+ /** The header/footer segment id. Omit or use an empty string for the main body. */
33
+ segmentId?: string;
34
+ }
35
+ export interface IFDocumentBodyEdit {
36
+ replaceRange: (range: IFDocumentTextRange, body: IDocumentBody) => boolean;
37
+ retainRange: (range: IFDocumentTextRange, body: IDocumentBody, coverType: UpdateDocsAttributeType) => boolean;
38
+ }
39
+ /**
40
+ * A Facade API object bounded to a document body or header/footer segment.
41
+ * It provides Google Docs-like element access and range editing methods.
42
+ *
43
+ * Paragraph elements use their persisted `paragraphId`. Tables, block ranges, and
44
+ * custom blocks use their persisted ids.
45
+ *
46
+ * @hideconstructor
47
+ */
48
+ export declare class FDocumentBody {
49
+ private readonly _documentDataModel;
50
+ private readonly _injector;
51
+ private readonly _segmentId;
52
+ private readonly _bodyEdit;
53
+ constructor(_documentDataModel: DocumentDataModel, _injector: Injector, _segmentId?: string);
54
+ /**
55
+ * Get the segment id of this document body facade.
56
+ * The main body has an empty string segment id.
57
+ * The header and footer FDocumentBody instances have their respective segment ids.
58
+ * @returns {string} The segment id of this document body facade.
59
+ * @example
60
+ * ```ts
61
+ * const fDocument = univerAPI.getActiveDocument();
62
+ * const fDocumentBody = fDocument.getBody();
63
+ * console.log(fDocumentBody.getSegmentId());
64
+ * ```
65
+ */
66
+ getSegmentId(): string;
67
+ /**
68
+ * Get the underlying document body snapshot.
69
+ * @returns {IDocumentBody} The document body snapshot.
70
+ * @example
71
+ * ```ts
72
+ * const fDocument = univerAPI.getActiveDocument();
73
+ * const fDocumentBody = fDocument.getBody();
74
+ * console.log(fDocumentBody.getBody());
75
+ * ```
76
+ */
77
+ getBody(): IDocumentBody;
78
+ /**
79
+ * Get a list of top-level child elements in the body.
80
+ * @returns {FDocumentElement[]} The list of top-level document elements.
81
+ * @example
82
+ * ```ts
83
+ * const fDocument = univerAPI.getActiveDocument();
84
+ * const fDocumentBody = fDocument.getBody();
85
+ * const elements = fDocumentBody.getElements();
86
+ * console.log(elements);
87
+ * ```
88
+ */
89
+ getElements(): FDocumentElement[];
90
+ /**
91
+ * Get a top-level child element by child index.
92
+ * @param {number} index The zero-based child index.
93
+ * @returns {FDocumentElement} The top-level child element wrapper.
94
+ * @example
95
+ * ```ts
96
+ * const fDocument = univerAPI.getActiveDocument();
97
+ * const fDocumentBody = fDocument.getBody();
98
+ * const element = fDocumentBody.getElement(0);
99
+ * console.log(element);
100
+ * ```
101
+ */
102
+ getElement(index: number): FDocumentElement | null;
103
+ /**
104
+ * Get the current child index of an element handle.
105
+ * The index is resolved from the element key, so a paragraph handle keeps pointing
106
+ * to the same paragraph after facade edits insert content before it.
107
+ * @param {FDocumentElement} element The element handle to locate.
108
+ * @returns {number} The current zero-based child index.
109
+ * @example
110
+ * ```ts
111
+ * const fDocument = univerAPI.getActiveDocument();
112
+ * const fDocumentBody = fDocument.getBody();
113
+ * const element = fDocumentBody.getElement(0);
114
+ * console.log(fDocumentBody.getElementIndex(element));
115
+ * ```
116
+ */
117
+ getElementIndex(element: FDocumentElement): number;
118
+ /**
119
+ * Insert plain text at a document body offset.
120
+ * @param {number} index The zero-based insertion offset.
121
+ * @param {string} text The plain text to insert.
122
+ * @returns {boolean} `true` if the edit was applied.
123
+ * @example
124
+ * ```ts
125
+ * const fDocument = univerAPI.getActiveDocument();
126
+ * const fDocumentBody = fDocument.getBody();
127
+ * fDocumentBody.insertText(0, 'Hello ');
128
+ * ```
129
+ */
130
+ insertText(index: number, text: string): boolean;
131
+ /**
132
+ * Apply text style to a body range.
133
+ * @param {IFDocumentTextRange} range The range to style.
134
+ * @param {ITextStyle} style The Univer text style patch.
135
+ * @returns {boolean} `true` if the style was applied.
136
+ * @example
137
+ * ```ts
138
+ * const fDocument = univerAPI.getActiveDocument();
139
+ * const fDocumentBody = fDocument.getBody();
140
+ * fDocumentBody.setTextStyle({ startOffset: 0, endOffset: 5 }, { bl: 1 });
141
+ * ```
142
+ */
143
+ setTextStyle(range: IFDocumentTextRange, style: ITextStyle): boolean;
144
+ /**
145
+ * Insert a plain-text paragraph before the paragraph at the given paragraph index.
146
+ * @param {number} index The zero-based paragraph insertion index.
147
+ * @param {string} text The paragraph text. Defaults to an empty paragraph.
148
+ * @returns {FDocumentParagraph} The inserted paragraph wrapper.
149
+ * @example
150
+ * ```ts
151
+ * const fDocument = univerAPI.getActiveDocument();
152
+ * const fDocumentBody = fDocument.getBody();
153
+ * const paragraph = fDocumentBody.insertParagraph(0, 'Document title');
154
+ * paragraph.appendText(' suffix');
155
+ * ```
156
+ */
157
+ insertParagraph(index: number, text?: string): FDocumentParagraph;
158
+ /**
159
+ * Append a plain-text paragraph at the end of the body.
160
+ * @param {string} text The paragraph text. Defaults to an empty paragraph.
161
+ * @returns {FDocumentParagraph} The appended paragraph wrapper.
162
+ * @example
163
+ * ```ts
164
+ * const fDocument = univerAPI.getActiveDocument();
165
+ * const fDocumentBody = fDocument.getBody();
166
+ * const paragraph = fDocumentBody.appendParagraph('Summary');
167
+ * console.log(paragraph.getText());
168
+ * ```
169
+ */
170
+ appendParagraph(text?: string): FDocumentParagraph;
171
+ /**
172
+ * Delete a range from the body.
173
+ * @param {IFDocumentTextRange} range The text range to delete.
174
+ * @returns {boolean} `true` if the range was deleted.
175
+ * @example
176
+ * ```ts
177
+ * const fDocument = univerAPI.getActiveDocument();
178
+ * const fDocumentBody = fDocument.getBody();
179
+ * fDocumentBody.deleteRange({ startOffset: 0, endOffset: 5 });
180
+ * ```
181
+ */
182
+ deleteRange(range: IFDocumentTextRange): boolean;
183
+ /**
184
+ * Remove a paragraph by paragraph id.
185
+ * @param {FDocumentParagraph} paragraph The paragraph handle to remove.
186
+ * @returns {boolean} `true` if the paragraph was removed.
187
+ * @example
188
+ * ```ts
189
+ * const fDocument = univerAPI.getActiveDocument();
190
+ * const fDocumentBody = fDocument.getBody();
191
+ * const element = fDocumentBody.getElement(0);
192
+ *
193
+ * if (element?.isParagraph()) {
194
+ * const paragraph = element.asParagraph();
195
+ * const removed = fDocumentBody.removeParagraph(paragraph);
196
+ * console.log(removed ? 'Paragraph removed' : 'Failed to remove paragraph');
197
+ * }
198
+ * ```
199
+ */
200
+ removeParagraph(paragraph: FDocumentParagraph): boolean;
201
+ /**
202
+ * Remove a callout, quote, or code block range and its content.
203
+ * @param {FDocumentBlockRange} blockRange The block range handle to remove.
204
+ * @returns {boolean} `true` if the block range content was removed.
205
+ * @example
206
+ * ```ts
207
+ * const fDocument = univerAPI.getActiveDocument();
208
+ * const fDocumentBody = fDocument.getBody();
209
+ * const element = fDocumentBody.getElement(0);
210
+ *
211
+ * if (element?.isBlockRange()) {
212
+ * const blockRange = element.asBlockRange();
213
+ * const removed = fDocumentBody.removeBlockRange(blockRange);
214
+ * console.log(removed ? 'Block range removed' : 'Failed to remove block range');
215
+ * }
216
+ * ```
217
+ */
218
+ removeBlockRange(blockRange: FDocumentBlockRange): boolean;
219
+ /**
220
+ * Remove a table marker and its content range.
221
+ * @returns {boolean} `true` if the table range was removed.
222
+ * @example
223
+ * ```ts
224
+ * const fDocument = univerAPI.getActiveDocument();
225
+ * const fDocumentBody = fDocument.getBody();
226
+ * const element = fDocumentBody.getElement(0);
227
+ *
228
+ * if (element?.isTable()) {
229
+ * const table = element.asTable();
230
+ * const removed = fDocumentBody.removeTable(table);
231
+ * console.log(removed ? 'Table removed' : 'Failed to remove table');
232
+ * }
233
+ * ```
234
+ */
235
+ removeTable(table: FDocumentTable): boolean;
236
+ /**
237
+ * Remove a custom block marker and its placeholder character.
238
+ * @param {FDocumentCustomBlock} customBlock The custom block handle to remove.
239
+ * @returns {boolean} `true` if the custom block placeholder was removed.
240
+ * @example
241
+ * ```ts
242
+ * const fDocument = univerAPI.getActiveDocument();
243
+ * const fDocumentBody = fDocument.getBody();
244
+ * const element = fDocumentBody.getElement(0);
245
+ *
246
+ * if (element?.isCustomBlock()) {
247
+ * const customBlock = element.asCustomBlock();
248
+ * const removed = fDocumentBody.removeCustomBlock(customBlock);
249
+ * console.log(removed ? 'Custom block removed' : 'Failed to remove custom block');
250
+ * }
251
+ * ```
252
+ */
253
+ removeCustomBlock(customBlock: FDocumentCustomBlock): boolean;
254
+ /**
255
+ * Resolve an element key to its current child metadata.
256
+ * @param {FDocumentElement} element The element handle to resolve.
257
+ * @returns {IFDocumentElementInfo} The current child metadata used by the facade.
258
+ * @example
259
+ * ```ts
260
+ * const fDocument = univerAPI.getActiveDocument();
261
+ * const fDocumentBody = fDocument.getBody();
262
+ * const element = fDocumentBody.getElement(0);
263
+ * const resolved = fDocumentBody.resolveElement(element);
264
+ * console.log(resolved);
265
+ * ```
266
+ */
267
+ resolveElement(element: FDocumentElement): IFDocumentElementInfo;
268
+ private _getChildren;
269
+ private _resolveParagraphInfo;
270
+ private _getParagraphId;
271
+ private _getParagraphInsertOffset;
272
+ private _replaceBodyRange;
273
+ private _retainBodyRange;
274
+ private _ensureTextRuns;
275
+ private _executeTextX;
276
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Copyright 2023-present DreamNum Co., Ltd.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import type { ICustomBlock, Injector } from '@univerjs/core';
17
+ import type { FDocumentBody, IFDocumentBodyEdit } from './f-document-body';
18
+ import type { IFDocumentElementInfo } from './f-document-element';
19
+ import { FDocumentElement } from './f-document-element';
20
+ interface IFDocumentCustomBlockMixin {
21
+ asCustomBlock(): FDocumentCustomBlock;
22
+ }
23
+ /**
24
+ * A facade wrapper for document top-level custom blocks.
25
+ * @hideconstructor
26
+ */
27
+ export declare class FDocumentCustomBlock extends FDocumentElement {
28
+ protected readonly body: FDocumentBody;
29
+ protected readonly bodyEdit: IFDocumentBodyEdit;
30
+ protected readonly info: IFDocumentElementInfo;
31
+ protected readonly injector: Injector;
32
+ constructor(body: FDocumentBody, bodyEdit: IFDocumentBodyEdit, info: IFDocumentElementInfo, injector: Injector);
33
+ /**
34
+ * Get the custom block marker.
35
+ * @returns {ICustomBlock} The custom block marker.
36
+ * @example
37
+ * ```ts
38
+ * const fDocument = univerAPI.getActiveDocument();
39
+ * const fDocumentBody = fDocument.getBody();
40
+ * const element = fDocumentBody.getElement(0);
41
+ *
42
+ * if (element?.isCustomBlock()) {
43
+ * const customBlock = element.asCustomBlock();
44
+ * console.log(customBlock.getCustomBlock());
45
+ * }
46
+ * ```
47
+ */
48
+ getCustomBlock(): ICustomBlock;
49
+ }
50
+ export declare class FDocumentCustomBlockMixin extends FDocumentElement {
51
+ asCustomBlock(): FDocumentCustomBlock;
52
+ }
53
+ declare module '@univerjs/docs/facade' {
54
+ interface FDocumentElement extends IFDocumentCustomBlockMixin {
55
+ }
56
+ }
57
+ export {};