@apollohg/react-native-rich-text-editor 2.0.0 → 2.0.2
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 +8 -116
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/android/build.gradle +3 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextImages.kt +25 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2RenderValidation.kt +1 -0
- package/android/src/main/java/com/apollohg/editor/ImageResizeOverlayView.kt +101 -33
- package/android/src/main/java/com/apollohg/editor/RenderMediaSpans.kt +15 -3
- package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +14 -0
- package/android/src/main/java/com/apollohg/editor/viewer/AndroidProseLayoutEngine.kt +1 -1
- package/app.plugin.js +42 -39
- package/dist/AtomHost.js +18 -11
- package/dist/EditorAddon.js +4 -2
- package/dist/EditorAddonNormalization.js +17 -9
- package/dist/EditorMentionThemeNormalization.js +6 -3
- package/dist/EditorMentionThemeValidation.js +28 -11
- package/dist/EditorStyleSheetNormalization.js +85 -38
- package/dist/EditorStyleSheetTypes.d.ts +1 -1
- package/dist/EditorTheme.d.ts +4 -0
- package/dist/EditorTheme.js +5 -3
- package/dist/EditorToolbarComponent.d.ts +1 -1
- package/dist/EditorToolbarComponent.js +1 -1
- package/dist/EditorToolbarRegistry.js +5 -5
- package/dist/EditorToolbarTypes.d.ts +12 -12
- package/dist/EditorToolbarVisuals.js +1 -1
- package/dist/ExternalTextComposition.js +89 -43
- package/dist/ImageLoadingPolicy.d.ts +1 -1
- package/dist/NativeEditorBoundaryError.d.ts +7 -7
- package/dist/NativeEditorBoundaryError.js +9 -5
- package/dist/NativeEditorCollaborationTransport.d.ts +7 -7
- package/dist/NativeEditorCollaborationTransport.js +28 -15
- package/dist/NativeEditorCreateConfig.js +11 -6
- package/dist/NativeEditorCreateJson.js +51 -25
- package/dist/NativeEditorCreateValidation.js +11 -6
- package/dist/NativeEditorDocumentBridge.d.ts +1 -1
- package/dist/NativeEditorDocumentBridge.js +32 -18
- package/dist/NativeEditorDocumentHandle.d.ts +4 -4
- package/dist/NativeEditorDocumentHandle.js +1 -1
- package/dist/NativeEditorLocalAwareness.js +25 -13
- package/dist/NativeEditorNativeModule.d.ts +8 -1
- package/dist/NativeEditorNativeModule.js +7 -5
- package/dist/NativeEditorRenderNormalization.js +66 -25
- package/dist/NativeEditorResultNormalization.js +53 -29
- package/dist/NativeEditorTypes.d.ts +10 -10
- package/dist/NativeEditorV2Decimal.js +6 -3
- package/dist/NativeProseViewer.js +11 -3
- package/dist/ResourceLimits.d.ts +2 -2
- package/dist/ResourceLimits.js +7 -2
- package/dist/RichTextEditor.js +1 -1
- package/dist/RichTextEditorNativeTypes.d.ts +1 -1
- package/dist/RichTextEditorNativeView.d.ts +1 -3
- package/dist/RichTextEditorSerialization.js +24 -14
- package/dist/RichTextEditorTypes.d.ts +1 -1
- package/dist/YjsCollaboration.d.ts +7 -7
- package/dist/YjsCollaboration.js +42 -26
- package/dist/addons.d.ts +4 -4
- package/dist/addons.js +3 -3
- package/dist/atomInstances.js +6 -3
- package/dist/atomUpdates.js +7 -4
- package/dist/atoms.js +20 -12
- package/dist/attributeValidation.js +55 -24
- package/dist/contentExpression.js +80 -42
- package/dist/listMarkers.d.ts +1 -1
- package/dist/listMarkers.js +1 -1
- package/dist/schemaDefinition.d.ts +1 -1
- package/dist/schemaDefinition.js +23 -14
- package/dist/schemaDocument.js +1 -1
- package/dist/schemaDocumentConstruction.js +25 -14
- package/dist/schemaNormalization.js +51 -29
- package/dist/schemaPresets.d.ts +1 -1
- package/dist/schemaPresets.js +9 -4
- package/dist/schemaResolution.js +46 -25
- package/dist/specs/PreparedProseViewerNativeComponent.d.ts +4 -0
- package/dist/useEditorToolbarInteractions.d.ts +2 -2
- package/dist/useEditorToolbarInteractions.js +45 -23
- package/dist/useEditorToolbarItems.d.ts +1 -1
- package/dist/useEditorToolbarItems.js +4 -3
- package/dist/useEditorToolbarPresentation.d.ts +3 -3
- package/dist/useEditorToolbarPresentation.js +4 -4
- package/dist/useEditorToolbarState.d.ts +1 -1
- package/dist/useEditorToolbarState.js +1 -1
- package/dist/useFocusPreservingFrames.js +11 -8
- package/dist/useNativeEditor.d.ts +1 -1
- package/dist/useNativeEditor.js +21 -11
- package/dist/useRichTextEditorCommands.d.ts +2 -2
- package/dist/useRichTextEditorCommands.js +59 -29
- package/dist/useRichTextEditorEvents.d.ts +3 -3
- package/dist/useRichTextEditorEvents.js +75 -32
- package/dist/useRichTextEditorMentions.d.ts +4 -4
- package/dist/useRichTextEditorMentions.js +48 -29
- package/dist/useRichTextEditorPresentation.d.ts +4 -4
- package/dist/useRichTextEditorPresentation.js +25 -23
- package/dist/useRichTextEditorState.d.ts +3 -3
- package/dist/useRichTextEditorState.js +20 -15
- package/dist/useRichTextEditorUpdates.d.ts +1 -1
- package/dist/useRichTextEditorUpdates.js +99 -41
- package/dist/useViewerAtoms.js +63 -36
- package/ios/EditorCore.xcframework/ios-arm64/libeditor_core.a +0 -0
- package/ios/EditorCore.xcframework/ios-arm64_x86_64-simulator/libeditor_core.a +0 -0
- package/ios/EditorInteractionOverlays.swift +114 -122
- package/ios/EditorLayoutManager.swift +13 -3
- package/ios/EditorStyleSheet.swift +12 -1
- package/ios/EditorTextView+Images.swift +32 -10
- package/ios/EditorTextView.swift +1 -1
- package/ios/EditorV2Adapter+RenderValidation.swift +2 -2
- package/ios/NativeToolbar+ButtonStyle.swift +17 -5
- package/ios/NativeToolbar+Diagnostics.swift +15 -0
- package/ios/RenderBridge+Atoms.swift +0 -1
- package/ios/RenderBridge+Attachments.swift +0 -29
- package/ios/RichTextEditorView.swift +4 -12
- package/ios/Viewer/CoreTextProseLayoutEngine+AttributedText.swift +3 -2
- package/package.json +11 -3
- package/react-native.config.js +1 -1
- package/rust/android/arm64-v8a/libeditor_core.so +0 -0
- package/rust/android/armeabi-v7a/libeditor_core.so +0 -0
- package/rust/android/x86/libeditor_core.so +0 -0
- package/rust/android/x86_64/libeditor_core.so +0 -0
- package/src/AtomHost.tsx +58 -28
- package/src/EditorAddon.ts +18 -8
- package/src/EditorAddonNormalization.ts +40 -11
- package/src/EditorMentionThemeNormalization.ts +15 -4
- package/src/EditorMentionThemeValidation.ts +51 -14
- package/src/EditorStyleSheet.ts +1 -0
- package/src/EditorStyleSheetNormalization.ts +195 -64
- package/src/EditorStyleSheetTypes.ts +1 -1
- package/src/EditorTheme.ts +13 -5
- package/src/EditorToolbarComponent.tsx +2 -1
- package/src/EditorToolbarRegistry.tsx +23 -13
- package/src/EditorToolbarTypes.tsx +12 -12
- package/src/EditorToolbarVisuals.tsx +6 -3
- package/src/EditorUpdateRevision.ts +1 -0
- package/src/ExternalTextComposition.ts +259 -49
- package/src/ImageLoadingPolicy.ts +3 -1
- package/src/NativeEditorBoundaryError.ts +38 -11
- package/src/NativeEditorCollaborationTransport.ts +108 -27
- package/src/NativeEditorCreateConfig.ts +92 -19
- package/src/NativeEditorCreateJson.ts +163 -26
- package/src/NativeEditorCreateValidation.ts +33 -12
- package/src/NativeEditorDocumentBridge.ts +111 -19
- package/src/NativeEditorDocumentHandle.ts +9 -4
- package/src/NativeEditorLocalAwareness.ts +70 -15
- package/src/NativeEditorNativeModule.ts +13 -9
- package/src/NativeEditorRenderNormalization.ts +128 -29
- package/src/NativeEditorResultNormalization.ts +143 -32
- package/src/NativeEditorTypes.ts +12 -11
- package/src/NativeEditorV2Decimal.ts +12 -3
- package/src/NativeProseViewer.tsx +46 -16
- package/src/ResourceLimits.ts +15 -8
- package/src/RichTextEditor.tsx +3 -1
- package/src/RichTextEditorNativeTypes.tsx +1 -1
- package/src/RichTextEditorNativeView.tsx +2 -8
- package/src/RichTextEditorSerialization.tsx +70 -24
- package/src/RichTextEditorTypes.tsx +1 -1
- package/src/YjsCollaboration.ts +143 -47
- package/src/addons.ts +12 -8
- package/src/atomInstances.ts +25 -5
- package/src/atomUpdates.ts +23 -6
- package/src/atoms.ts +85 -18
- package/src/attributeValidation.ts +97 -33
- package/src/contentExpression.ts +218 -63
- package/src/listMarkers.ts +1 -1
- package/src/schemaDefinition.ts +82 -20
- package/src/schemaDocument.ts +15 -1
- package/src/schemaDocumentConstruction.ts +80 -16
- package/src/schemaNormalization.ts +155 -41
- package/src/schemaPresets.ts +37 -31
- package/src/schemaResolution.ts +126 -27
- package/src/specs/PreparedProseViewerNativeComponent.ts +4 -2
- package/src/useEditorToolbarInteractions.tsx +85 -36
- package/src/useEditorToolbarItems.tsx +50 -22
- package/src/useEditorToolbarPresentation.tsx +81 -58
- package/src/useEditorToolbarState.tsx +8 -6
- package/src/useFocusPreservingFrames.ts +43 -15
- package/src/useNativeEditor.ts +111 -51
- package/src/useRichTextEditorCommands.tsx +127 -54
- package/src/useRichTextEditorEvents.tsx +144 -42
- package/src/useRichTextEditorMentions.tsx +118 -37
- package/src/useRichTextEditorPresentation.tsx +128 -114
- package/src/useRichTextEditorState.tsx +76 -40
- package/src/useRichTextEditorUpdates.tsx +207 -56
- package/src/useViewerAtoms.tsx +162 -66
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
type ExternalTextCompositionOptions,
|
|
12
12
|
type ExternalTextCompositionSession,
|
|
13
13
|
} from './ExternalTextComposition';
|
|
14
|
-
import { useRichTextEditorState } from './useRichTextEditorState';
|
|
15
|
-
import { useRichTextEditorUpdates } from './useRichTextEditorUpdates';
|
|
14
|
+
import { type useRichTextEditorState } from './useRichTextEditorState';
|
|
15
|
+
import { type useRichTextEditorUpdates } from './useRichTextEditorUpdates';
|
|
16
16
|
import { isRevisionMismatchError, parseCaretRectJson } from './RichTextEditorSerialization';
|
|
17
17
|
import { type RichTextEditorRef, type RichTextEditorCaretRect } from './RichTextEditorTypes';
|
|
18
18
|
|
|
@@ -68,24 +68,28 @@ export function useRichTextEditorCommands(
|
|
|
68
68
|
atomOwnerRef.current = documentHandle;
|
|
69
69
|
|
|
70
70
|
const updateAtomAttrs = useCallback(
|
|
71
|
-
async
|
|
71
|
+
async(
|
|
72
72
|
atomKey: string,
|
|
73
73
|
nodeType: string,
|
|
74
74
|
expectedDocPos: number,
|
|
75
75
|
expectedDocumentVersion: string | null,
|
|
76
76
|
hasStableKey: boolean,
|
|
77
77
|
update: AtomAttrsUpdate
|
|
78
|
-
): Promise<void> => {
|
|
78
|
+
): Promise<void> => { // eslint-disable-line @typescript-eslint/require-await -- Preserve promise rejection for validation errors.
|
|
79
79
|
const baseDocumentRevision = latestRevisionRef.current;
|
|
80
|
+
|
|
80
81
|
if (documentHandle.isDestroyed || baseDocumentRevision == null) {
|
|
81
82
|
throw new AtomUpdateAttrsError('not-ready', 'The editor is not ready');
|
|
82
83
|
}
|
|
84
|
+
|
|
83
85
|
if (!editableRef.current) {
|
|
84
86
|
throw new AtomUpdateAttrsError('not-applicable', 'The editor is not editable');
|
|
85
87
|
}
|
|
88
|
+
|
|
86
89
|
const instance = atomStateRef.current.instances.find(
|
|
87
|
-
|
|
90
|
+
candidate => candidate.key === atomKey && candidate.nodeType === nodeType
|
|
88
91
|
);
|
|
92
|
+
|
|
89
93
|
if (
|
|
90
94
|
instance == null ||
|
|
91
95
|
(!hasStableKey &&
|
|
@@ -97,8 +101,10 @@ export function useRichTextEditorCommands(
|
|
|
97
101
|
'The atom no longer exists in the document'
|
|
98
102
|
);
|
|
99
103
|
}
|
|
104
|
+
|
|
100
105
|
const attrs = resolveAtomAttrsUpdate(instance.attrs, update);
|
|
101
106
|
let outcome;
|
|
107
|
+
|
|
102
108
|
try {
|
|
103
109
|
outcome = bridge.applyCommand({
|
|
104
110
|
baseDocumentRevision,
|
|
@@ -113,6 +119,7 @@ export function useRichTextEditorCommands(
|
|
|
113
119
|
'The atom changed before its attributes were updated'
|
|
114
120
|
);
|
|
115
121
|
}
|
|
122
|
+
|
|
116
123
|
if (
|
|
117
124
|
error instanceof NativeEditorErrorBase &&
|
|
118
125
|
(error.code === 'ENGINE_NOT_READY' ||
|
|
@@ -121,11 +128,13 @@ export function useRichTextEditorCommands(
|
|
|
121
128
|
) {
|
|
122
129
|
throw new AtomUpdateAttrsError('not-ready', 'The editor is not ready');
|
|
123
130
|
}
|
|
131
|
+
|
|
124
132
|
throw new AtomUpdateAttrsError(
|
|
125
133
|
'engine-error',
|
|
126
134
|
error instanceof Error ? error.message : 'The atom update failed'
|
|
127
135
|
);
|
|
128
136
|
}
|
|
137
|
+
|
|
129
138
|
if (outcome.type === 'notApplicable') {
|
|
130
139
|
refreshAtomsFromUpdate(bridge.renderUpdate());
|
|
131
140
|
document.refresh();
|
|
@@ -134,42 +143,58 @@ export function useRichTextEditorCommands(
|
|
|
134
143
|
'The atom no longer exists at this document position'
|
|
135
144
|
);
|
|
136
145
|
}
|
|
146
|
+
|
|
137
147
|
if (outcome.type !== 'transaction') {
|
|
138
148
|
throw new AtomUpdateAttrsError('engine-error', 'Unexpected atom update outcome');
|
|
139
149
|
}
|
|
150
|
+
|
|
140
151
|
afterLocalEngineMutation();
|
|
141
152
|
},
|
|
142
|
-
[afterLocalEngineMutation,
|
|
153
|
+
[ afterLocalEngineMutation,
|
|
154
|
+
atomStateRef,
|
|
155
|
+
bridge,
|
|
156
|
+
document,
|
|
157
|
+
documentHandle.isDestroyed,
|
|
158
|
+
latestRevisionRef,
|
|
159
|
+
refreshAtomsFromUpdate ]
|
|
143
160
|
);
|
|
144
161
|
|
|
145
162
|
const runAtomAction = useCallback(
|
|
146
|
-
async
|
|
163
|
+
async(
|
|
147
164
|
owner: NativeEditorDocumentHandle,
|
|
148
165
|
instance: AtomInstance,
|
|
149
166
|
documentVersion: string | null,
|
|
150
167
|
action: 'select' | 'delete' | 'before' | 'after'
|
|
151
|
-
) => {
|
|
168
|
+
) => { // eslint-disable-line @typescript-eslint/require-await -- Preserve promise rejection for validation errors.
|
|
152
169
|
if (
|
|
153
170
|
owner !== atomOwnerRef.current ||
|
|
154
171
|
documentHandle.isDestroyed ||
|
|
155
172
|
latestRevisionRef.current == null
|
|
156
|
-
)
|
|
173
|
+
) {
|
|
157
174
|
throw new AtomUpdateAttrsError('not-ready', 'The editor is not ready.');
|
|
158
|
-
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (action === 'delete' && !editableRef.current) {
|
|
159
178
|
throw new AtomUpdateAttrsError('not-applicable', 'The editor is not editable.');
|
|
179
|
+
}
|
|
180
|
+
|
|
160
181
|
const current = atomStateRef.current.instances.find(
|
|
161
|
-
|
|
182
|
+
candidate =>
|
|
162
183
|
candidate.key === instance.key && candidate.nodeType === instance.nodeType
|
|
163
184
|
);
|
|
185
|
+
|
|
164
186
|
if (
|
|
165
187
|
!current ||
|
|
166
188
|
(!instance.hasStableKey &&
|
|
167
189
|
(documentVersion !== atomStateRef.current.documentVersion ||
|
|
168
190
|
current.docPos !== instance.docPos))
|
|
169
|
-
)
|
|
191
|
+
) {
|
|
170
192
|
throw new AtomUpdateAttrsError('not-applicable', 'The atom no longer exists.');
|
|
193
|
+
}
|
|
194
|
+
|
|
171
195
|
try {
|
|
172
196
|
const baseDocumentRevision = latestRevisionRef.current;
|
|
197
|
+
|
|
173
198
|
const selection = bridge.setSelection({
|
|
174
199
|
baseDocumentRevision,
|
|
175
200
|
selection: {
|
|
@@ -178,29 +203,41 @@ export function useRichTextEditorCommands(
|
|
|
178
203
|
edge: action === 'select' || action === 'delete' ? 'node' : action,
|
|
179
204
|
},
|
|
180
205
|
});
|
|
181
|
-
|
|
206
|
+
|
|
207
|
+
if (selection.type !== 'transaction') {
|
|
182
208
|
throw new AtomUpdateAttrsError(
|
|
183
209
|
'not-applicable',
|
|
184
210
|
'The atom could not be selected.'
|
|
185
211
|
);
|
|
212
|
+
}
|
|
213
|
+
|
|
186
214
|
if (action === 'delete') {
|
|
187
215
|
const outcome = bridge.applyCommand({
|
|
188
216
|
baseDocumentRevision,
|
|
189
217
|
command: { type: 'deleteBackward' },
|
|
190
218
|
});
|
|
191
|
-
|
|
219
|
+
|
|
220
|
+
if (outcome.type !== 'transaction') {
|
|
192
221
|
throw new AtomUpdateAttrsError(
|
|
193
222
|
'not-applicable',
|
|
194
223
|
'The atom could not be deleted.'
|
|
195
224
|
);
|
|
225
|
+
}
|
|
226
|
+
|
|
196
227
|
afterLocalEngineMutation();
|
|
197
228
|
} else {
|
|
198
229
|
pushEngineUpdateToView();
|
|
199
230
|
document.refresh();
|
|
200
|
-
|
|
231
|
+
|
|
232
|
+
if (action !== 'select') {
|
|
233
|
+
nativeViewRef.current?.focus?.();
|
|
234
|
+
}
|
|
201
235
|
}
|
|
202
236
|
} catch (error) {
|
|
203
|
-
if (error instanceof AtomUpdateAttrsError)
|
|
237
|
+
if (error instanceof AtomUpdateAttrsError) {
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
|
|
204
241
|
if (isRevisionMismatchError(error)) {
|
|
205
242
|
refreshAtomsFromUpdate(bridge.renderUpdate());
|
|
206
243
|
document.refresh();
|
|
@@ -209,20 +246,22 @@ export function useRichTextEditorCommands(
|
|
|
209
246
|
'The document changed before the atom action.'
|
|
210
247
|
);
|
|
211
248
|
}
|
|
249
|
+
|
|
212
250
|
throw new AtomUpdateAttrsError(
|
|
213
251
|
'engine-error',
|
|
214
252
|
error instanceof Error ? error.message : String(error)
|
|
215
253
|
);
|
|
216
254
|
}
|
|
217
255
|
},
|
|
218
|
-
[
|
|
219
|
-
|
|
256
|
+
[ afterLocalEngineMutation,
|
|
257
|
+
atomStateRef,
|
|
220
258
|
bridge,
|
|
221
259
|
document,
|
|
222
|
-
documentHandle,
|
|
260
|
+
documentHandle.isDestroyed,
|
|
261
|
+
latestRevisionRef,
|
|
262
|
+
nativeViewRef,
|
|
223
263
|
pushEngineUpdateToView,
|
|
224
|
-
refreshAtomsFromUpdate
|
|
225
|
-
]
|
|
264
|
+
refreshAtomsFromUpdate ]
|
|
226
265
|
);
|
|
227
266
|
|
|
228
267
|
const runEngineMutation = useCallback(
|
|
@@ -239,11 +278,14 @@ export function useRichTextEditorCommands(
|
|
|
239
278
|
details: null,
|
|
240
279
|
});
|
|
241
280
|
}
|
|
281
|
+
|
|
242
282
|
const baseRevision = latestRevisionRef.current;
|
|
283
|
+
|
|
243
284
|
if (baseRevision == null) {
|
|
244
285
|
// Engine not ready (room awaiting the server document).
|
|
245
286
|
return;
|
|
246
287
|
}
|
|
288
|
+
|
|
247
289
|
try {
|
|
248
290
|
invoke(baseRevision);
|
|
249
291
|
} catch (error) {
|
|
@@ -251,63 +293,71 @@ export function useRichTextEditorCommands(
|
|
|
251
293
|
// Refresh from the engine; NEVER retry against guessed
|
|
252
294
|
// positions (native adapter parity).
|
|
253
295
|
document.refresh();
|
|
296
|
+
|
|
254
297
|
return;
|
|
255
298
|
}
|
|
299
|
+
|
|
256
300
|
throw error;
|
|
257
301
|
}
|
|
302
|
+
|
|
258
303
|
afterLocalEngineMutation();
|
|
259
304
|
},
|
|
260
|
-
[afterLocalEngineMutation, document]
|
|
305
|
+
[ afterLocalEngineMutation, document, latestRevisionRef ]
|
|
261
306
|
);
|
|
262
307
|
|
|
263
308
|
const applyEngineCommand = useCallback(
|
|
264
309
|
(command: Record<string, unknown>) => {
|
|
265
|
-
runEngineMutation(
|
|
266
|
-
bridge.applyCommand({ command, baseDocumentRevision })
|
|
267
|
-
);
|
|
310
|
+
runEngineMutation(baseDocumentRevision =>
|
|
311
|
+
bridge.applyCommand({ command, baseDocumentRevision }));
|
|
268
312
|
},
|
|
269
|
-
[bridge, runEngineMutation]
|
|
313
|
+
[ bridge, runEngineMutation ]
|
|
270
314
|
);
|
|
271
315
|
|
|
272
316
|
const commandToggleMark = useCallback(
|
|
273
317
|
(markType: string) => applyEngineCommand({ type: 'toggleMark', markType }),
|
|
274
|
-
[applyEngineCommand]
|
|
318
|
+
[ applyEngineCommand ]
|
|
275
319
|
);
|
|
276
320
|
|
|
277
321
|
const commandSetLink = useCallback(
|
|
278
322
|
(href: string) => {
|
|
279
323
|
const trimmedHref = href.trim();
|
|
280
|
-
|
|
324
|
+
|
|
325
|
+
if (!trimmedHref) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
|
|
281
329
|
applyEngineCommand({
|
|
282
330
|
type: 'setMark',
|
|
283
331
|
markType: 'link',
|
|
284
332
|
attrs: { href: trimmedHref },
|
|
285
333
|
});
|
|
286
334
|
},
|
|
287
|
-
[applyEngineCommand]
|
|
335
|
+
[ applyEngineCommand ]
|
|
288
336
|
);
|
|
289
337
|
|
|
290
338
|
const commandUnsetLink = useCallback(
|
|
291
339
|
() => applyEngineCommand({ type: 'unsetMark', markType: 'link' }),
|
|
292
|
-
[applyEngineCommand]
|
|
340
|
+
[ applyEngineCommand ]
|
|
293
341
|
);
|
|
294
342
|
|
|
295
343
|
const commandToggleBlockquote = useCallback(
|
|
296
344
|
() => applyEngineCommand({ type: 'toggleBlockquote' }),
|
|
297
|
-
[applyEngineCommand]
|
|
345
|
+
[ applyEngineCommand ]
|
|
298
346
|
);
|
|
299
347
|
|
|
300
348
|
const commandToggleHeading = useCallback(
|
|
301
349
|
(level: EditorToolbarHeadingLevel) => applyEngineCommand({ type: 'toggleHeading', level }),
|
|
302
|
-
[applyEngineCommand]
|
|
350
|
+
[ applyEngineCommand ]
|
|
303
351
|
);
|
|
304
352
|
|
|
305
353
|
const commandToggleList = useCallback(
|
|
306
354
|
(listType: string) => {
|
|
307
355
|
if (activeStateRef.current.nodes[listType] === true) {
|
|
308
356
|
applyEngineCommand({ type: 'unwrapFromList' });
|
|
357
|
+
|
|
309
358
|
return;
|
|
310
359
|
}
|
|
360
|
+
|
|
311
361
|
applyEngineCommand({
|
|
312
362
|
type: 'wrapInList',
|
|
313
363
|
listType,
|
|
@@ -315,26 +365,26 @@ export function useRichTextEditorCommands(
|
|
|
315
365
|
listType === 'taskList'
|
|
316
366
|
? 'taskItem'
|
|
317
367
|
: listType === 'bullet_list' || listType === 'ordered_list'
|
|
318
|
-
|
|
319
|
-
|
|
368
|
+
? 'list_item'
|
|
369
|
+
: 'listItem',
|
|
320
370
|
});
|
|
321
371
|
},
|
|
322
|
-
[applyEngineCommand]
|
|
372
|
+
[ activeStateRef, applyEngineCommand ]
|
|
323
373
|
);
|
|
324
374
|
|
|
325
375
|
const commandIndentListItem = useCallback(
|
|
326
376
|
() => applyEngineCommand({ type: 'indentListItem' }),
|
|
327
|
-
[applyEngineCommand]
|
|
377
|
+
[ applyEngineCommand ]
|
|
328
378
|
);
|
|
329
379
|
|
|
330
380
|
const commandOutdentListItem = useCallback(
|
|
331
381
|
() => applyEngineCommand({ type: 'outdentListItem' }),
|
|
332
|
-
[applyEngineCommand]
|
|
382
|
+
[ applyEngineCommand ]
|
|
333
383
|
);
|
|
334
384
|
|
|
335
385
|
const commandInsertNode = useCallback(
|
|
336
386
|
(nodeType: string) => applyEngineCommand({ type: 'insertNode', nodeType }),
|
|
337
|
-
[applyEngineCommand]
|
|
387
|
+
[ applyEngineCommand ]
|
|
338
388
|
);
|
|
339
389
|
|
|
340
390
|
const commandInsertImage = useCallback(
|
|
@@ -344,31 +394,34 @@ export function useRichTextEditorCommands(
|
|
|
344
394
|
json: buildImageFragmentJson({ src, ...attrs }, documentDescriptor),
|
|
345
395
|
});
|
|
346
396
|
},
|
|
347
|
-
[applyEngineCommand, documentDescriptor]
|
|
397
|
+
[ applyEngineCommand, documentDescriptor ]
|
|
348
398
|
);
|
|
349
399
|
|
|
350
400
|
const commandInsertText = useCallback(
|
|
351
401
|
(text: string) => {
|
|
352
|
-
if (!text)
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
402
|
+
if (!text) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
runEngineMutation(baseDocumentRevision =>
|
|
407
|
+
bridge.applyInput({ text, baseDocumentRevision }));
|
|
356
408
|
},
|
|
357
|
-
[bridge, runEngineMutation]
|
|
409
|
+
[ bridge, runEngineMutation ]
|
|
358
410
|
);
|
|
359
411
|
|
|
360
412
|
const commandInsertContentHtml = useCallback(
|
|
361
413
|
(html: string) => applyEngineCommand({ type: 'insertContentHtml', html }),
|
|
362
|
-
[applyEngineCommand]
|
|
414
|
+
[ applyEngineCommand ]
|
|
363
415
|
);
|
|
364
416
|
|
|
365
417
|
const commandInsertContentJson = useCallback(
|
|
366
418
|
(doc: DocumentJSON) => applyEngineCommand({ type: 'insertContentJson', json: doc }),
|
|
367
|
-
[applyEngineCommand]
|
|
419
|
+
[ applyEngineCommand ]
|
|
368
420
|
);
|
|
369
421
|
|
|
370
422
|
const openLinkRequest = useCallback(() => {
|
|
371
423
|
const linkAttrs = activeStateRef.current.markAttrs?.link;
|
|
424
|
+
|
|
372
425
|
onRequestLinkRef.current?.({
|
|
373
426
|
href: typeof linkAttrs?.href === 'string' ? linkAttrs.href : undefined,
|
|
374
427
|
isActive: activeStateRef.current.marks.link === true,
|
|
@@ -376,14 +429,18 @@ export function useRichTextEditorCommands(
|
|
|
376
429
|
setLink: commandSetLink,
|
|
377
430
|
unsetLink: commandUnsetLink,
|
|
378
431
|
});
|
|
379
|
-
}, [
|
|
432
|
+
}, [ activeStateRef,
|
|
433
|
+
commandSetLink,
|
|
434
|
+
commandUnsetLink,
|
|
435
|
+
onRequestLinkRef,
|
|
436
|
+
selectionRef ]);
|
|
380
437
|
|
|
381
438
|
const openImageRequest = useCallback(() => {
|
|
382
439
|
onRequestImageRef.current?.({
|
|
383
440
|
selection: selectionRef.current,
|
|
384
441
|
insertImage: commandInsertImage,
|
|
385
442
|
});
|
|
386
|
-
}, [commandInsertImage]);
|
|
443
|
+
}, [ commandInsertImage, onRequestImageRef, selectionRef ]);
|
|
387
444
|
|
|
388
445
|
useImperativeHandle(
|
|
389
446
|
ref,
|
|
@@ -408,6 +465,7 @@ export function useRichTextEditorCommands(
|
|
|
408
465
|
)
|
|
409
466
|
);
|
|
410
467
|
}
|
|
468
|
+
|
|
411
469
|
return externalCompositionManager.begin(options);
|
|
412
470
|
},
|
|
413
471
|
toggleMark: commandToggleMark,
|
|
@@ -432,8 +490,13 @@ export function useRichTextEditorCommands(
|
|
|
432
490
|
getTextContent: document.getTextContent,
|
|
433
491
|
async getCaretRect(): Promise<RichTextEditorCaretRect | null> {
|
|
434
492
|
const nativeView = nativeViewRef.current;
|
|
435
|
-
|
|
493
|
+
|
|
494
|
+
if (!nativeView?.getCaretRect) {
|
|
495
|
+
return null;
|
|
496
|
+
}
|
|
497
|
+
|
|
436
498
|
const raw = await Promise.resolve(nativeView.getCaretRect());
|
|
499
|
+
|
|
437
500
|
return parseCaretRectJson(raw);
|
|
438
501
|
},
|
|
439
502
|
undo: document.undo,
|
|
@@ -441,9 +504,7 @@ export function useRichTextEditorCommands(
|
|
|
441
504
|
canUndo: document.canUndo,
|
|
442
505
|
canRedo: document.canRedo,
|
|
443
506
|
}),
|
|
444
|
-
[
|
|
445
|
-
document,
|
|
446
|
-
commandToggleMark,
|
|
507
|
+
[ commandToggleMark,
|
|
447
508
|
commandSetLink,
|
|
448
509
|
commandUnsetLink,
|
|
449
510
|
commandToggleBlockquote,
|
|
@@ -456,10 +517,22 @@ export function useRichTextEditorCommands(
|
|
|
456
517
|
commandInsertText,
|
|
457
518
|
commandInsertContentHtml,
|
|
458
519
|
commandInsertContentJson,
|
|
459
|
-
|
|
520
|
+
document.setContent,
|
|
521
|
+
document.setContentJson,
|
|
522
|
+
document.clearContent,
|
|
523
|
+
document.getContent,
|
|
524
|
+
document.getContentJson,
|
|
525
|
+
document.getIsEmpty,
|
|
526
|
+
document.getTextContent,
|
|
527
|
+
document.undo,
|
|
528
|
+
document.redo,
|
|
529
|
+
document.canUndo,
|
|
530
|
+
document.canRedo,
|
|
531
|
+
nativeViewRef,
|
|
460
532
|
externalCompositionManager,
|
|
461
|
-
|
|
533
|
+
editable ]
|
|
462
534
|
);
|
|
535
|
+
|
|
463
536
|
return {
|
|
464
537
|
openLinkRequest,
|
|
465
538
|
openImageRequest,
|