@apollohg/react-native-rich-text-editor 2.0.0
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/LICENSE +160 -0
- package/README.md +259 -0
- package/RUST-STANDARD-LIBRARY-NOTICES.html +8266 -0
- package/ReactNativeProseEditor.podspec +59 -0
- package/THIRD_PARTY_NOTICES.md +31155 -0
- package/android/build.gradle +188 -0
- package/android/consumer-rules.pro +18 -0
- package/android/expo/build.gradle +17 -0
- package/android/src/debug/java/com/apollohg/editor/viewer/PreparedProseDrawInstrumentation.kt +7 -0
- package/android/src/main/assets/editor-icons/MaterialIcons.json +2236 -0
- package/android/src/main/assets/editor-icons/MaterialIcons.ttf +0 -0
- package/android/src/main/java/com/apollohg/editor/AndroidApiCompat.kt +19 -0
- package/android/src/main/java/com/apollohg/editor/AndroidCollaborationTransport.kt +860 -0
- package/android/src/main/java/com/apollohg/editor/CaretGeometry.kt +91 -0
- package/android/src/main/java/com/apollohg/editor/CodeHighlighting.kt +141 -0
- package/android/src/main/java/com/apollohg/editor/DecodedBitmapBudget.kt +250 -0
- package/android/src/main/java/com/apollohg/editor/EditorAddons.kt +133 -0
- package/android/src/main/java/com/apollohg/editor/EditorBlockSpacing.kt +51 -0
- package/android/src/main/java/com/apollohg/editor/EditorBoxDrawable.kt +16 -0
- package/android/src/main/java/com/apollohg/editor/EditorBoxDrawing.kt +234 -0
- package/android/src/main/java/com/apollohg/editor/EditorCheckboxSpan.kt +87 -0
- package/android/src/main/java/com/apollohg/editor/EditorCodeHighlighting.kt +120 -0
- package/android/src/main/java/com/apollohg/editor/EditorDecorationLayer.java +18 -0
- package/android/src/main/java/com/apollohg/editor/EditorDocumentLayout.kt +626 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditText.kt +1042 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextAnnotations.kt +191 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextCaret.kt +100 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextClipboard.kt +101 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextComposition.kt +220 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextConfiguration.kt +316 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextCorrection.kt +303 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextDeferredUpdates.kt +327 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextDeletion.kt +258 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextDiagnostics.kt +83 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextDragDrop.kt +67 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextExternalComposition.kt +357 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextHardwareInput.kt +277 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextImages.kt +280 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextInputLifecycle.kt +183 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextInputPreparation.kt +79 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextInputTraits.kt +384 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextLayout.kt +100 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextNativeMutation.kt +243 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextPlaceholder.kt +154 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextRenderPatch.kt +347 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextRendering.kt +313 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextRustCommands.kt +281 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextSelection.kt +352 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextState.kt +113 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextTaskMarkers.kt +92 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextTextCommit.kt +327 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextToolbar.kt +84 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextUpdates.kt +245 -0
- package/android/src/main/java/com/apollohg/editor/EditorGlyphHeightCursorDrawable.kt +42 -0
- package/android/src/main/java/com/apollohg/editor/EditorHeightBehavior.kt +13 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputConnection.kt +923 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputCoordinates.kt +191 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputCorrection.kt +107 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputCursorGeometry.kt +128 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputSnapshots.kt +134 -0
- package/android/src/main/java/com/apollohg/editor/EditorInputSurroundingDeletion.kt +321 -0
- package/android/src/main/java/com/apollohg/editor/EditorKeyboardToolbarView.kt +851 -0
- package/android/src/main/java/com/apollohg/editor/EditorMentionStyle.kt +192 -0
- package/android/src/main/java/com/apollohg/editor/EditorReconciliationWatcher.kt +46 -0
- package/android/src/main/java/com/apollohg/editor/EditorStyleSheet.kt +303 -0
- package/android/src/main/java/com/apollohg/editor/EditorStyleSheetSpans.kt +253 -0
- package/android/src/main/java/com/apollohg/editor/EditorSurfaceInputConnection.kt +67 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextDecorationDrawing.kt +143 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextSurface.kt +712 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceDragDrop.kt +94 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceInteraction.kt +708 -0
- package/android/src/main/java/com/apollohg/editor/EditorTheme.kt +650 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Adapter.kt +912 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2AdapterMutations.kt +402 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2AdapterRendering.kt +123 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2AdapterSelection.kt +203 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Backend.kt +120 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Driver.kt +87 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Registry.kt +97 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2RenderValidation.kt +409 -0
- package/android/src/main/java/com/apollohg/editor/ExpoAutoGrowStyleSizePublisher.kt +34 -0
- package/android/src/main/java/com/apollohg/editor/ImageResizeOverlayView.kt +266 -0
- package/android/src/main/java/com/apollohg/editor/ImeTextCoordinateMapper.kt +102 -0
- package/android/src/main/java/com/apollohg/editor/KeyboardToolbarImeAnimationController.kt +101 -0
- package/android/src/main/java/com/apollohg/editor/MentionSuggestionChipView.kt +234 -0
- package/android/src/main/java/com/apollohg/editor/NativeCollaborationTransportRegistry.kt +493 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoView.kt +813 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewAtoms.kt +68 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewBinding.kt +126 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewDiagnostics.kt +208 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewErrors.kt +146 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewEvents.kt +150 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewExternalComposition.kt +39 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewFocus.kt +176 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewLifecycle.kt +302 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewMentions.kt +259 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewNativeActions.kt +179 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewOutsideTap.kt +214 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewPendingUpdates.kt +376 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewProperties.kt +234 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewPropertyRetries.kt +197 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewToolbar.kt +285 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewTypes.kt +28 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewUpdates.kt +271 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorModule.kt +687 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorOutsideTapDispatcher.kt +380 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorV2Numbers.kt +45 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorViewRegistry.kt +372 -0
- package/android/src/main/java/com/apollohg/editor/NativeImagePipeline.kt +22 -0
- package/android/src/main/java/com/apollohg/editor/NativeToolbar.kt +193 -0
- package/android/src/main/java/com/apollohg/editor/NativeToolbarIcons.kt +177 -0
- package/android/src/main/java/com/apollohg/editor/NativeToolbarItem.kt +274 -0
- package/android/src/main/java/com/apollohg/editor/OkHttpCollaborationSocket.kt +102 -0
- package/android/src/main/java/com/apollohg/editor/OrderedListMarkerFormatter.kt +130 -0
- package/android/src/main/java/com/apollohg/editor/PointerTransparentView.java +18 -0
- package/android/src/main/java/com/apollohg/editor/PositionBridge.kt +128 -0
- package/android/src/main/java/com/apollohg/editor/ProseViewerView.kt +854 -0
- package/android/src/main/java/com/apollohg/editor/RemoteSelectionOverlayView.kt +314 -0
- package/android/src/main/java/com/apollohg/editor/RenderBlockSpans.kt +314 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridge.kt +224 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridgeBlockStyles.kt +407 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridgeElements.kt +544 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridgeInlineAndAtoms.kt +631 -0
- package/android/src/main/java/com/apollohg/editor/RenderBridgeParagraphs.kt +215 -0
- package/android/src/main/java/com/apollohg/editor/RenderImageDecoder.kt +748 -0
- package/android/src/main/java/com/apollohg/editor/RenderImageLoader.kt +900 -0
- package/android/src/main/java/com/apollohg/editor/RenderLayoutConstants.kt +117 -0
- package/android/src/main/java/com/apollohg/editor/RenderMediaSpans.kt +337 -0
- package/android/src/main/java/com/apollohg/editor/RenderParagraphSpans.kt +182 -0
- package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +951 -0
- package/android/src/main/java/com/apollohg/editor/SharedNativeImagePipeline.kt +78 -0
- package/android/src/main/java/com/apollohg/editor/UniffiEditorV2Backend.kt +261 -0
- package/android/src/main/java/com/apollohg/editor/viewer/AndroidProseLayoutEngine.kt +1656 -0
- package/android/src/main/java/com/apollohg/editor/viewer/FabricAttachmentSidecars.kt +80 -0
- package/android/src/main/java/com/apollohg/editor/viewer/FabricLeaseHandleBridge.kt +59 -0
- package/android/src/main/java/com/apollohg/editor/viewer/FallbackSelectionGeometry.kt +450 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseDrawingView.kt +678 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseInstrumentation.kt +608 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayout.kt +186 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayoutCache.kt +393 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayoutRegistry.kt +828 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseTheme.kt +316 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseViewerManager.kt +900 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseViewerPackage.kt +16 -0
- package/android/src/main/java/com/apollohg/editor/viewer/PreparedViewerAtoms.kt +89 -0
- package/android/src/main/java/com/apollohg/editor/viewer/ViewerCodeHighlighting.kt +91 -0
- package/android/src/main/java/com/apollohg/editor/viewer/ViewerDocument.kt +453 -0
- package/android/src/main/java/com/apollohg/editor/viewer/ViewerFontEnvironment.kt +282 -0
- package/android/src/main/java/com/apollohg/editor/viewer/ViewerImagePipeline.kt +460 -0
- package/android/src/main/jni/CMakeLists.txt +85 -0
- package/android/src/main/jni/PreparedProseViewerMeasurementsManager.cpp +334 -0
- package/android/src/main/jni/ReactNativeProseEditorSpec.h +17 -0
- package/android/src/main/jni/reactnativeproseeditor.h +6 -0
- package/android/src/main/res/values/attrs.xml +6 -0
- package/android/src/release/java/com/apollohg/editor/viewer/PreparedProseDrawInstrumentation.kt +9 -0
- package/app.plugin.js +62 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseMeasurementsManager.h +62 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerComponentDescriptor.h +30 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerShadowNode.cpp +192 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerShadowNode.h +46 -0
- package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerState.h +145 -0
- package/dist/AtomHost.d.ts +17 -0
- package/dist/AtomHost.js +135 -0
- package/dist/DefaultAtomChip.d.ts +2 -0
- package/dist/DefaultAtomChip.js +22 -0
- package/dist/EditorAddon.d.ts +32 -0
- package/dist/EditorAddon.js +29 -0
- package/dist/EditorAddonNormalization.d.ts +6 -0
- package/dist/EditorAddonNormalization.js +48 -0
- package/dist/EditorMentionThemeNormalization.d.ts +8 -0
- package/dist/EditorMentionThemeNormalization.js +22 -0
- package/dist/EditorMentionThemeValidation.d.ts +12 -0
- package/dist/EditorMentionThemeValidation.js +95 -0
- package/dist/EditorStyleSheet.d.ts +4 -0
- package/dist/EditorStyleSheet.js +10 -0
- package/dist/EditorStyleSheetNormalization.d.ts +3 -0
- package/dist/EditorStyleSheetNormalization.js +226 -0
- package/dist/EditorStyleSheetTypes.d.ts +151 -0
- package/dist/EditorStyleSheetTypes.js +2 -0
- package/dist/EditorTheme.d.ts +117 -0
- package/dist/EditorTheme.js +41 -0
- package/dist/EditorToolbar.d.ts +4 -0
- package/dist/EditorToolbar.js +17 -0
- package/dist/EditorToolbarComponent.d.ts +13 -0
- package/dist/EditorToolbarComponent.js +24 -0
- package/dist/EditorToolbarItems.d.ts +9 -0
- package/dist/EditorToolbarItems.js +58 -0
- package/dist/EditorToolbarRegistry.d.ts +59 -0
- package/dist/EditorToolbarRegistry.js +175 -0
- package/dist/EditorToolbarTypes.d.ts +273 -0
- package/dist/EditorToolbarTypes.js +2 -0
- package/dist/EditorToolbarVisuals.d.ts +154 -0
- package/dist/EditorToolbarVisuals.js +228 -0
- package/dist/EditorUpdateRevision.d.ts +8 -0
- package/dist/EditorUpdateRevision.js +22 -0
- package/dist/ExternalTextComposition.d.ts +45 -0
- package/dist/ExternalTextComposition.js +537 -0
- package/dist/ImageLoadingPolicy.d.ts +54 -0
- package/dist/ImageLoadingPolicy.js +60 -0
- package/dist/NativeEditorBoundaryError.d.ts +111 -0
- package/dist/NativeEditorBoundaryError.js +268 -0
- package/dist/NativeEditorBridge.d.ts +9 -0
- package/dist/NativeEditorBridge.js +37 -0
- package/dist/NativeEditorCollaborationTransport.d.ts +154 -0
- package/dist/NativeEditorCollaborationTransport.js +275 -0
- package/dist/NativeEditorCreateConfig.d.ts +16 -0
- package/dist/NativeEditorCreateConfig.js +249 -0
- package/dist/NativeEditorCreateJson.d.ts +76 -0
- package/dist/NativeEditorCreateJson.js +474 -0
- package/dist/NativeEditorCreateValidation.d.ts +32 -0
- package/dist/NativeEditorCreateValidation.js +150 -0
- package/dist/NativeEditorDocumentBridge.d.ts +72 -0
- package/dist/NativeEditorDocumentBridge.js +305 -0
- package/dist/NativeEditorDocumentHandle.d.ts +70 -0
- package/dist/NativeEditorDocumentHandle.js +89 -0
- package/dist/NativeEditorLocalAwareness.d.ts +34 -0
- package/dist/NativeEditorLocalAwareness.js +153 -0
- package/dist/NativeEditorNativeModule.d.ts +48 -0
- package/dist/NativeEditorNativeModule.js +34 -0
- package/dist/NativeEditorRenderNormalization.d.ts +22 -0
- package/dist/NativeEditorRenderNormalization.js +274 -0
- package/dist/NativeEditorResultNormalization.d.ts +108 -0
- package/dist/NativeEditorResultNormalization.js +400 -0
- package/dist/NativeEditorTypes.d.ts +318 -0
- package/dist/NativeEditorTypes.js +15 -0
- package/dist/NativeEditorV2Decimal.d.ts +5 -0
- package/dist/NativeEditorV2Decimal.js +18 -0
- package/dist/NativeProseViewer.d.ts +122 -0
- package/dist/NativeProseViewer.js +130 -0
- package/dist/NativeRichTextEditor.d.ts +3 -0
- package/dist/NativeRichTextEditor.js +6 -0
- package/dist/ResourceLimits.d.ts +100 -0
- package/dist/ResourceLimits.js +80 -0
- package/dist/RichTextEditor.d.ts +4 -0
- package/dist/RichTextEditor.js +25 -0
- package/dist/RichTextEditorNativeTypes.d.ts +122 -0
- package/dist/RichTextEditorNativeTypes.js +2 -0
- package/dist/RichTextEditorNativeView.d.ts +12 -0
- package/dist/RichTextEditorNativeView.js +15 -0
- package/dist/RichTextEditorSerialization.d.ts +53 -0
- package/dist/RichTextEditorSerialization.js +283 -0
- package/dist/RichTextEditorTypes.d.ts +281 -0
- package/dist/RichTextEditorTypes.js +2 -0
- package/dist/ViewerConfiguration.d.ts +22 -0
- package/dist/ViewerConfiguration.js +6 -0
- package/dist/YjsCollaboration.d.ts +146 -0
- package/dist/YjsCollaboration.js +496 -0
- package/dist/addons.d.ts +193 -0
- package/dist/addons.js +122 -0
- package/dist/atomConstants.d.ts +3 -0
- package/dist/atomConstants.js +6 -0
- package/dist/atomInstances.d.ts +35 -0
- package/dist/atomInstances.js +79 -0
- package/dist/atomPolicy.d.ts +4 -0
- package/dist/atomPolicy.js +47 -0
- package/dist/atomUpdates.d.ts +2 -0
- package/dist/atomUpdates.js +38 -0
- package/dist/atoms.d.ts +92 -0
- package/dist/atoms.js +222 -0
- package/dist/attributeValidation.d.ts +4 -0
- package/dist/attributeValidation.js +97 -0
- package/dist/contentExpression.d.ts +6 -0
- package/dist/contentExpression.js +335 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +78 -0
- package/dist/listMarkers.d.ts +15 -0
- package/dist/listMarkers.js +21 -0
- package/dist/schemaDefinition.d.ts +143 -0
- package/dist/schemaDefinition.js +206 -0
- package/dist/schemaDocument.d.ts +17 -0
- package/dist/schemaDocument.js +69 -0
- package/dist/schemaDocumentConstruction.d.ts +5 -0
- package/dist/schemaDocumentConstruction.js +125 -0
- package/dist/schemaNormalization.d.ts +29 -0
- package/dist/schemaNormalization.js +313 -0
- package/dist/schemaPresets.d.ts +68 -0
- package/dist/schemaPresets.js +198 -0
- package/dist/schemaResolution.d.ts +9 -0
- package/dist/schemaResolution.js +211 -0
- package/dist/schemas.d.ts +5 -0
- package/dist/schemas.js +28 -0
- package/dist/specs/PreparedProseViewerNativeComponent.d.ts +37 -0
- package/dist/specs/PreparedProseViewerNativeComponent.js +6 -0
- package/dist/useEditorToolbarInteractions.d.ts +12 -0
- package/dist/useEditorToolbarInteractions.js +218 -0
- package/dist/useEditorToolbarItems.d.ts +8 -0
- package/dist/useEditorToolbarItems.js +280 -0
- package/dist/useEditorToolbarPresentation.d.ts +4 -0
- package/dist/useEditorToolbarPresentation.js +203 -0
- package/dist/useEditorToolbarState.d.ts +63 -0
- package/dist/useEditorToolbarState.js +108 -0
- package/dist/useFocusPreservingFrames.d.ts +17 -0
- package/dist/useFocusPreservingFrames.js +108 -0
- package/dist/useNativeEditor.d.ts +66 -0
- package/dist/useNativeEditor.js +370 -0
- package/dist/useRichTextEditorCommands.d.ts +21 -0
- package/dist/useRichTextEditorCommands.js +299 -0
- package/dist/useRichTextEditorEvents.d.ts +18 -0
- package/dist/useRichTextEditorEvents.js +216 -0
- package/dist/useRichTextEditorMentions.d.ts +11 -0
- package/dist/useRichTextEditorMentions.js +316 -0
- package/dist/useRichTextEditorPresentation.d.ts +5 -0
- package/dist/useRichTextEditorPresentation.js +178 -0
- package/dist/useRichTextEditorState.d.ts +180 -0
- package/dist/useRichTextEditorState.js +405 -0
- package/dist/useRichTextEditorUpdates.d.ts +10 -0
- package/dist/useRichTextEditorUpdates.js +308 -0
- package/dist/useViewerAtoms.d.ts +38 -0
- package/dist/useViewerAtoms.js +288 -0
- package/expo-module.config.json +13 -0
- package/ios/EditorAddons.swift +354 -0
- package/ios/EditorCodeHighlighting.swift +184 -0
- package/ios/EditorCore.xcframework/Info.plist +44 -0
- 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 +697 -0
- package/ios/EditorLayoutManager.swift +971 -0
- package/ios/EditorNodeTypes.swift +37 -0
- package/ios/EditorStyleSheet.swift +461 -0
- package/ios/EditorTextView+AttributedPatch.swift +305 -0
- package/ios/EditorTextView+Binding.swift +61 -0
- package/ios/EditorTextView+Caret.swift +333 -0
- package/ios/EditorTextView+Commands.swift +203 -0
- package/ios/EditorTextView+Delegate.swift +65 -0
- package/ios/EditorTextView+Diagnostics.swift +225 -0
- package/ios/EditorTextView+DragDrop.swift +290 -0
- package/ios/EditorTextView+ExternalComposition.swift +364 -0
- package/ios/EditorTextView+Images.swift +354 -0
- package/ios/EditorTextView+InputTraits.swift +200 -0
- package/ios/EditorTextView+KeyboardInput.swift +318 -0
- package/ios/EditorTextView+Layout.swift +245 -0
- package/ios/EditorTextView+MarkedText.swift +267 -0
- package/ios/EditorTextView+NativeInputLifecycle.swift +372 -0
- package/ios/EditorTextView+NativeMutation.swift +471 -0
- package/ios/EditorTextView+Reconciliation.swift +97 -0
- package/ios/EditorTextView+RenderPatch.swift +573 -0
- package/ios/EditorTextView+Rendering.swift +539 -0
- package/ios/EditorTextView+Selection.swift +542 -0
- package/ios/EditorTextView.swift +953 -0
- package/ios/EditorTheme.swift +626 -0
- package/ios/EditorV2Adapter+Commands.swift +204 -0
- package/ios/EditorV2Adapter+Envelope.swift +238 -0
- package/ios/EditorV2Adapter+Mutation.swift +392 -0
- package/ios/EditorV2Adapter+Registry.swift +185 -0
- package/ios/EditorV2Adapter+RenderState.swift +360 -0
- package/ios/EditorV2Adapter+RenderValidation.swift +420 -0
- package/ios/EditorV2Adapter+Selection.swift +329 -0
- package/ios/EditorV2Adapter+TextCommands.swift +430 -0
- package/ios/EditorV2Adapter.swift +376 -0
- package/ios/EditorV2Shadow.swift +353 -0
- package/ios/Generated_editor_core.swift +2378 -0
- package/ios/NativeCodeHighlighting.swift +159 -0
- package/ios/NativeCollaborationSocket.swift +144 -0
- package/ios/NativeCollaborationTransport+Protocol.swift +258 -0
- package/ios/NativeCollaborationTransport+Socket.swift +379 -0
- package/ios/NativeCollaborationTransport+Validation.swift +103 -0
- package/ios/NativeCollaborationTransport.swift +322 -0
- package/ios/NativeCollaborationTransportRegistry.swift +521 -0
- package/ios/NativeEditorExpoView+AccessoryRetry.swift +219 -0
- package/ios/NativeEditorExpoView+Binding.swift +268 -0
- package/ios/NativeEditorExpoView+Diagnostics.swift +66 -0
- package/ios/NativeEditorExpoView+Events.swift +131 -0
- package/ios/NativeEditorExpoView+Focus.swift +169 -0
- package/ios/NativeEditorExpoView+MentionRetry.swift +288 -0
- package/ios/NativeEditorExpoView+Mentions.swift +288 -0
- package/ios/NativeEditorExpoView+Properties.swift +300 -0
- package/ios/NativeEditorExpoView+Toolbar.swift +86 -0
- package/ios/NativeEditorExpoView+Updates.swift +312 -0
- package/ios/NativeEditorExpoView.swift +349 -0
- package/ios/NativeEditorModule.swift +856 -0
- package/ios/NativeEditorViewRegistry.swift +226 -0
- package/ios/NativeToolbar+ButtonStyle.swift +214 -0
- package/ios/NativeToolbar+Buttons.swift +228 -0
- package/ios/NativeToolbar+Diagnostics.swift +114 -0
- package/ios/NativeToolbar+Menu.swift +101 -0
- package/ios/NativeToolbar+Models.swift +519 -0
- package/ios/NativeToolbar+Placeholder.swift +39 -0
- package/ios/NativeToolbar.swift +612 -0
- package/ios/OrderedListMarkerFormatter.swift +103 -0
- package/ios/PositionBridge.swift +596 -0
- package/ios/ProseViewerView.swift +462 -0
- package/ios/RenderBridge+Atoms.swift +288 -0
- package/ios/RenderBridge+Attachments.swift +246 -0
- package/ios/RenderBridge+BlockBoundaries.swift +313 -0
- package/ios/RenderBridge+Style.swift +343 -0
- package/ios/RenderBridge.swift +704 -0
- package/ios/RichTextEditorView.swift +930 -0
- package/ios/SharedNativeImagePipeline+Cache.swift +189 -0
- package/ios/SharedNativeImagePipeline+Transport.swift +328 -0
- package/ios/SharedNativeImagePipeline.swift +533 -0
- package/ios/Viewer/CoreTextProseLayoutEngine+AttributedText.swift +436 -0
- package/ios/Viewer/CoreTextProseLayoutEngine+Models.swift +322 -0
- package/ios/Viewer/CoreTextProseLayoutEngine.swift +635 -0
- package/ios/Viewer/Fabric/PREPPreparedProseViewerComponentView.h +4 -0
- package/ios/Viewer/Fabric/PREPPreparedProseViewerComponentView.mm +767 -0
- package/ios/Viewer/Fabric/PreparedProseMeasurementsManager.mm +118 -0
- package/ios/Viewer/NativeSVGImageDecoder.h +9 -0
- package/ios/Viewer/NativeSVGImageDecoder.mm +106 -0
- package/ios/Viewer/NativeSVGPreflight.h +11 -0
- package/ios/Viewer/NativeSVGPreflight.mm +219 -0
- package/ios/Viewer/PreparedProseDrawingView.swift +639 -0
- package/ios/Viewer/PreparedProseInstrumentation.swift +387 -0
- package/ios/Viewer/PreparedProseLayout.swift +326 -0
- package/ios/Viewer/PreparedProseLayoutCache.swift +766 -0
- package/ios/Viewer/PreparedProseLayoutRegistry+Artifacts.swift +377 -0
- package/ios/Viewer/PreparedProseLayoutRegistry+Fabric.swift +582 -0
- package/ios/Viewer/PreparedProseLayoutRegistry+FabricOwnership.swift +128 -0
- package/ios/Viewer/PreparedProseLayoutRegistry.swift +381 -0
- package/ios/Viewer/ViewerDocument.swift +575 -0
- package/ios/Viewer/ViewerFontEnvironment.swift +283 -0
- package/ios/Viewer/ViewerImagePipeline.swift +478 -0
- package/ios/editor_coreFFI/editor_coreFFI.h +1023 -0
- package/ios/editor_coreFFI/module.modulemap +7 -0
- package/package.json +151 -0
- package/react-native.config.js +17 -0
- 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/rust/bindings/kotlin/uniffi/editor_core/editor_core.kt +3146 -0
- package/src/AtomHost.tsx +180 -0
- package/src/DefaultAtomChip.tsx +27 -0
- package/src/EditorAddon.ts +65 -0
- package/src/EditorAddonNormalization.ts +49 -0
- package/src/EditorMentionThemeNormalization.ts +25 -0
- package/src/EditorMentionThemeValidation.ts +133 -0
- package/src/EditorStyleSheet.ts +9 -0
- package/src/EditorStyleSheetNormalization.ts +219 -0
- package/src/EditorStyleSheetTypes.ts +189 -0
- package/src/EditorTheme.ts +196 -0
- package/src/EditorToolbar.tsx +31 -0
- package/src/EditorToolbarComponent.tsx +23 -0
- package/src/EditorToolbarItems.tsx +64 -0
- package/src/EditorToolbarRegistry.tsx +254 -0
- package/src/EditorToolbarTypes.tsx +322 -0
- package/src/EditorToolbarVisuals.tsx +270 -0
- package/src/EditorUpdateRevision.ts +26 -0
- package/src/ExternalTextComposition.ts +658 -0
- package/src/ImageLoadingPolicy.ts +125 -0
- package/src/NativeEditorBoundaryError.ts +345 -0
- package/src/NativeEditorBridge.ts +93 -0
- package/src/NativeEditorCollaborationTransport.ts +493 -0
- package/src/NativeEditorCreateConfig.ts +326 -0
- package/src/NativeEditorCreateJson.ts +579 -0
- package/src/NativeEditorCreateValidation.ts +178 -0
- package/src/NativeEditorDocumentBridge.ts +485 -0
- package/src/NativeEditorDocumentHandle.ts +168 -0
- package/src/NativeEditorLocalAwareness.ts +168 -0
- package/src/NativeEditorNativeModule.ts +97 -0
- package/src/NativeEditorRenderNormalization.ts +320 -0
- package/src/NativeEditorResultNormalization.ts +469 -0
- package/src/NativeEditorTypes.ts +366 -0
- package/src/NativeEditorV2Decimal.ts +13 -0
- package/src/NativeProseViewer.tsx +356 -0
- package/src/NativeRichTextEditor.tsx +33 -0
- package/src/ResourceLimits.ts +187 -0
- package/src/RichTextEditor.tsx +27 -0
- package/src/RichTextEditorNativeTypes.tsx +144 -0
- package/src/RichTextEditorNativeView.tsx +21 -0
- package/src/RichTextEditorSerialization.tsx +381 -0
- package/src/RichTextEditorTypes.tsx +327 -0
- package/src/ViewerConfiguration.ts +23 -0
- package/src/YjsCollaboration.ts +692 -0
- package/src/addons.ts +311 -0
- package/src/atomConstants.ts +3 -0
- package/src/atomInstances.ts +123 -0
- package/src/atomPolicy.ts +47 -0
- package/src/atomUpdates.ts +52 -0
- package/src/atoms.ts +379 -0
- package/src/attributeValidation.ts +116 -0
- package/src/contentExpression.ts +338 -0
- package/src/index.ts +295 -0
- package/src/listMarkers.ts +18 -0
- package/src/schemaDefinition.ts +395 -0
- package/src/schemaDocument.ts +92 -0
- package/src/schemaDocumentConstruction.ts +148 -0
- package/src/schemaNormalization.ts +367 -0
- package/src/schemaPresets.ts +250 -0
- package/src/schemaResolution.ts +242 -0
- package/src/schemas.ts +43 -0
- package/src/specs/PreparedProseViewerNativeComponent.ts +40 -0
- package/src/useEditorToolbarInteractions.tsx +329 -0
- package/src/useEditorToolbarItems.tsx +390 -0
- package/src/useEditorToolbarPresentation.tsx +483 -0
- package/src/useEditorToolbarState.tsx +172 -0
- package/src/useFocusPreservingFrames.ts +171 -0
- package/src/useNativeEditor.ts +534 -0
- package/src/useRichTextEditorCommands.tsx +478 -0
- package/src/useRichTextEditorEvents.tsx +342 -0
- package/src/useRichTextEditorMentions.tsx +441 -0
- package/src/useRichTextEditorPresentation.tsx +563 -0
- package/src/useRichTextEditorState.tsx +620 -0
- package/src/useRichTextEditorUpdates.tsx +403 -0
- package/src/useViewerAtoms.tsx +427 -0
|
@@ -0,0 +1,856 @@
|
|
|
1
|
+
@preconcurrency public import ExpoModulesCore
|
|
2
|
+
import UIKit
|
|
3
|
+
|
|
4
|
+
/// Test-facing parser for the v2 create value. Handles are never bridged
|
|
5
|
+
/// through signed native numbers: the frozen wire shape is a canonical
|
|
6
|
+
/// decimal string.
|
|
7
|
+
func createdEditorId(_ resultJson: String) -> String? {
|
|
8
|
+
guard let data = resultJson.data(using: .utf8),
|
|
9
|
+
let result = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
10
|
+
result["error"] == nil,
|
|
11
|
+
let editorId = result["editorId"] as? String,
|
|
12
|
+
let value = v2UInt64Argument(editorId),
|
|
13
|
+
value > 0,
|
|
14
|
+
editorId == String(value)
|
|
15
|
+
else {
|
|
16
|
+
return nil
|
|
17
|
+
}
|
|
18
|
+
return editorId
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// MARK: - v2 result-record bridging (frozen {value, error} contract)
|
|
22
|
+
|
|
23
|
+
/// One FfiError as the plain dictionary the TS boundary normalizes
|
|
24
|
+
/// (`normalizeNativeEditorV2Error`): required domain/code/message plus the
|
|
25
|
+
/// optional fields only when present.
|
|
26
|
+
private func v2FfiErrorDictionary(_ error: FfiError) -> [String: Any] {
|
|
27
|
+
var dictionary: [String: Any] = [
|
|
28
|
+
"domain": error.domain,
|
|
29
|
+
"code": error.code,
|
|
30
|
+
"message": error.message
|
|
31
|
+
]
|
|
32
|
+
if let requestId = error.requestId { dictionary["requestId"] = requestId }
|
|
33
|
+
if let operationIndex = error.operationIndex { dictionary["operationIndex"] = operationIndex }
|
|
34
|
+
if let limit = error.limit { dictionary["limit"] = limit }
|
|
35
|
+
if let actual = error.actual { dictionary["actual"] = actual }
|
|
36
|
+
if let detailsJson = error.detailsJson { dictionary["detailsJson"] = detailsJson }
|
|
37
|
+
return dictionary
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/// A boundary-fabricated error record for arguments that cannot reach Rust
|
|
41
|
+
/// (non-canonical generation strings and the like).
|
|
42
|
+
private func v2ContractErrorDictionary(_ message: String) -> [String: Any] {
|
|
43
|
+
[
|
|
44
|
+
"domain": "boundary",
|
|
45
|
+
"code": "FFI_RESULT_INVALID",
|
|
46
|
+
"message": message
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private func v2InvalidResultDictionary(_ message: String) -> [String: Any] {
|
|
51
|
+
["error": v2ContractErrorDictionary(message)]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private func v2ResultDictionary<Value>(
|
|
55
|
+
value: Value?,
|
|
56
|
+
error: FfiError?,
|
|
57
|
+
mapValue: (Value) -> Any
|
|
58
|
+
) -> [String: Any] {
|
|
59
|
+
switch (value, error) {
|
|
60
|
+
case let (value?, nil):
|
|
61
|
+
return ["value": mapValue(value)]
|
|
62
|
+
case let (nil, error?):
|
|
63
|
+
return ["error": v2FfiErrorDictionary(error)]
|
|
64
|
+
default:
|
|
65
|
+
return v2InvalidResultDictionary("v2 result must carry exactly one of value/error")
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private func v2JsonResultDictionary(_ result: FfiJsonResult) -> [String: Any] {
|
|
70
|
+
v2ResultDictionary(value: result.value, error: result.error, mapValue: { $0 })
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private func v2UnitResultDictionary(_ result: FfiUnitResult) -> [String: Any] {
|
|
74
|
+
v2ResultDictionary(value: result.value, error: result.error, mapValue: { $0 })
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
func v2CollaborationUnitResultDictionary(
|
|
78
|
+
editorId: String,
|
|
79
|
+
operation: (String) -> FfiUnitResult
|
|
80
|
+
) -> [String: Any] {
|
|
81
|
+
v2UnitResultDictionary(operation(editorId))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/// Boundary helper retained for canonical monotonic-u64 coverage. Production
|
|
85
|
+
/// transport timing is native-owned and calls the generated drive function
|
|
86
|
+
/// directly rather than exporting a JavaScript tick.
|
|
87
|
+
func v2CollaborationTickResultDictionary(
|
|
88
|
+
editorId: String,
|
|
89
|
+
nowMillis: String,
|
|
90
|
+
tick: (String, String) -> FfiJsonResult
|
|
91
|
+
) -> [String: Any] {
|
|
92
|
+
guard let canonicalNowMillis = v2CanonicalUInt64String(nowMillis) else {
|
|
93
|
+
return v2InvalidResultDictionary("invalid nowMillis")
|
|
94
|
+
}
|
|
95
|
+
return v2JsonResultDictionary(tick(editorId, canonicalNowMillis))
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private func v2MutationResultDictionary(
|
|
99
|
+
editorId: String,
|
|
100
|
+
result operation: @autoclosure () -> FfiJsonResult
|
|
101
|
+
) -> [String: Any] {
|
|
102
|
+
let result = performEditorV2JsonOperation(editorId: editorId) {
|
|
103
|
+
let result = operation()
|
|
104
|
+
if result.error == nil,
|
|
105
|
+
let value = result.value,
|
|
106
|
+
let data = value.data(using: .utf8),
|
|
107
|
+
let outcome = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
108
|
+
let nativeEditorId = v2UInt64Argument(editorId),
|
|
109
|
+
let adapter = EditorV2Registry.adapter(forLegacyId: nativeEditorId) {
|
|
110
|
+
var revision = EditorV2Adapter.uint64Field(outcome, "documentRevision")
|
|
111
|
+
if revision == nil, outcome["changed"] as? Bool == true,
|
|
112
|
+
let stateJSON = editorV2GetState(editorId: editorId).value,
|
|
113
|
+
let stateData = stateJSON.data(using: .utf8),
|
|
114
|
+
let state = try? JSONSerialization.jsonObject(with: stateData) as? [String: Any] {
|
|
115
|
+
revision = EditorV2Adapter.uint64Field(state, "documentRevision")
|
|
116
|
+
}
|
|
117
|
+
if let revision {
|
|
118
|
+
adapter.latestJSDrivenDocumentRevision = max(adapter.latestJSDrivenDocumentRevision, revision)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return result
|
|
122
|
+
}
|
|
123
|
+
if result.error == nil,
|
|
124
|
+
let value = result.value,
|
|
125
|
+
let data = value.data(using: .utf8),
|
|
126
|
+
let outcome = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
127
|
+
outcome["changed"] as? Bool == true,
|
|
128
|
+
let nativeEditorId = v2UInt64Argument(editorId) {
|
|
129
|
+
NativeCollaborationTransportRegistry.notifyOutboundAvailable(
|
|
130
|
+
editorId: nativeEditorId,
|
|
131
|
+
reason: .moduleMutation
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
return v2JsonResultDictionary(result)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private func v2SnapshotExportResultDictionary(_ result: FfiSnapshotExportResult) -> [String: Any] {
|
|
138
|
+
v2ResultDictionary(value: result.value, error: result.error) { value in
|
|
139
|
+
[
|
|
140
|
+
"metadataJson": value.metadataJson,
|
|
141
|
+
"encodedState": value.encodedState
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/// Canonical decimal u64 values are the only v2 wire representation.
|
|
147
|
+
func v2CanonicalUInt64String(_ raw: String) -> String? {
|
|
148
|
+
guard !raw.isEmpty,
|
|
149
|
+
raw.allSatisfy({ $0 >= "0" && $0 <= "9" }),
|
|
150
|
+
raw == "0" || raw.first != "0",
|
|
151
|
+
UInt64(raw) != nil
|
|
152
|
+
else {
|
|
153
|
+
return nil
|
|
154
|
+
}
|
|
155
|
+
return raw
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/// Native-only conversion after canonical syntax and range verification.
|
|
159
|
+
private func v2UInt64Argument(_ raw: String) -> UInt64? {
|
|
160
|
+
guard let canonical = v2CanonicalUInt64String(raw) else { return nil }
|
|
161
|
+
return UInt64(canonical)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
func applyNativeEditorIdProp(_ raw: String, to view: NativeEditorExpoView) {
|
|
165
|
+
guard let editorId = v2UInt64Argument(raw) else { return }
|
|
166
|
+
view.setEditorId(editorId)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/// NSNumber is the Expo/Foundation numeric boundary. Do not use `uint32Value`:
|
|
170
|
+
/// it truncates fractions and wraps values outside the u32 domain.
|
|
171
|
+
func v2ExactUInt32(_ raw: NSNumber?) -> UInt32? {
|
|
172
|
+
guard let raw,
|
|
173
|
+
CFGetTypeID(raw) != CFBooleanGetTypeID()
|
|
174
|
+
else {
|
|
175
|
+
return nil
|
|
176
|
+
}
|
|
177
|
+
if let decimal = raw as? NSDecimalNumber {
|
|
178
|
+
let maximum = NSDecimalNumber(value: UInt32.max)
|
|
179
|
+
guard decimal != NSDecimalNumber.notANumber,
|
|
180
|
+
decimal.compare(NSDecimalNumber.zero) != .orderedAscending,
|
|
181
|
+
decimal.compare(maximum) != .orderedDescending
|
|
182
|
+
else {
|
|
183
|
+
return nil
|
|
184
|
+
}
|
|
185
|
+
let rounded = decimal.rounding(
|
|
186
|
+
accordingToBehavior: NSDecimalNumberHandler(
|
|
187
|
+
roundingMode: .down,
|
|
188
|
+
scale: 0,
|
|
189
|
+
raiseOnExactness: false,
|
|
190
|
+
raiseOnOverflow: false,
|
|
191
|
+
raiseOnUnderflow: false,
|
|
192
|
+
raiseOnDivideByZero: false
|
|
193
|
+
)
|
|
194
|
+
)
|
|
195
|
+
guard decimal.compare(rounded) == .orderedSame,
|
|
196
|
+
let exact = UInt32(decimal.stringValue)
|
|
197
|
+
else {
|
|
198
|
+
return nil
|
|
199
|
+
}
|
|
200
|
+
return exact
|
|
201
|
+
}
|
|
202
|
+
let value = raw.doubleValue
|
|
203
|
+
guard value.isFinite,
|
|
204
|
+
value >= 0,
|
|
205
|
+
value.rounded(.towardZero) == value,
|
|
206
|
+
value <= Double(UInt32.max)
|
|
207
|
+
else {
|
|
208
|
+
return nil
|
|
209
|
+
}
|
|
210
|
+
return UInt32(exactly: value)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/// A created v2 handle preserves its exact engine-issued string for adapter
|
|
214
|
+
/// binding while retaining the current numeric native-view registry id.
|
|
215
|
+
private struct CreatedV2SessionHandle {
|
|
216
|
+
let handle: String
|
|
217
|
+
let nativeViewId: UInt64
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/// Parse the created v2 session's canonical decimal handle from the frozen
|
|
221
|
+
/// create value (`{"editorId":"<decimal>"}`). The adapter must receive the
|
|
222
|
+
/// exact engine-issued string rather than a numeric reconstruction.
|
|
223
|
+
private func createdV2SessionHandle(_ resultJson: String) -> CreatedV2SessionHandle? {
|
|
224
|
+
guard let data = resultJson.data(using: .utf8),
|
|
225
|
+
let result = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
226
|
+
result.count == 1,
|
|
227
|
+
let editorIdString = result["editorId"] as? String,
|
|
228
|
+
let editorId = v2UInt64Argument(editorIdString),
|
|
229
|
+
editorId > 0,
|
|
230
|
+
editorIdString == String(editorId)
|
|
231
|
+
else {
|
|
232
|
+
return nil
|
|
233
|
+
}
|
|
234
|
+
return CreatedV2SessionHandle(handle: editorIdString, nativeViewId: editorId)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/// A malformed create record may still expose a safely canonical handle. It
|
|
238
|
+
/// is not acceptable for pairing, but it is safe to destroy so Rust does not
|
|
239
|
+
/// retain an otherwise unreachable session.
|
|
240
|
+
private func cleanupCreatedV2SessionHandle(_ resultJson: String) -> CreatedV2SessionHandle? {
|
|
241
|
+
guard let data = resultJson.data(using: .utf8),
|
|
242
|
+
let result = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
243
|
+
let editorIdString = result["editorId"] as? String,
|
|
244
|
+
let editorId = v2UInt64Argument(editorIdString),
|
|
245
|
+
editorId > 0,
|
|
246
|
+
editorIdString == String(editorId)
|
|
247
|
+
else {
|
|
248
|
+
return nil
|
|
249
|
+
}
|
|
250
|
+
return CreatedV2SessionHandle(handle: editorIdString, nativeViewId: editorId)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
private func cleanupCreatedV2Session(
|
|
254
|
+
value: String?,
|
|
255
|
+
destroy: (String) -> FfiUnitResult
|
|
256
|
+
) {
|
|
257
|
+
guard let value,
|
|
258
|
+
let handle = cleanupCreatedV2SessionHandle(value)
|
|
259
|
+
else {
|
|
260
|
+
return
|
|
261
|
+
}
|
|
262
|
+
_ = destroy(handle.handle)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/// Create a public v2 session and register its paired native view adapter
|
|
266
|
+
/// only after the FFI record is exact and the create value parses strictly.
|
|
267
|
+
/// The injected functions keep the exact-result boundary independently testable.
|
|
268
|
+
func createEditorV2SessionFromModule(
|
|
269
|
+
configJson: String,
|
|
270
|
+
snapshotState: Data?,
|
|
271
|
+
create: (String, Data?) -> FfiJsonResult = { configJson, snapshotState in
|
|
272
|
+
editorV2Create(configJson: configJson, snapshotState: snapshotState)
|
|
273
|
+
},
|
|
274
|
+
destroy: (String) -> FfiUnitResult = { editorId in
|
|
275
|
+
editorV2Destroy(editorId: editorId)
|
|
276
|
+
}
|
|
277
|
+
) -> [String: Any] {
|
|
278
|
+
let result = create(configJson, snapshotState)
|
|
279
|
+
switch (result.value, result.error) {
|
|
280
|
+
case let (value?, nil):
|
|
281
|
+
guard let createdHandle = createdV2SessionHandle(value) else {
|
|
282
|
+
cleanupCreatedV2Session(value: value, destroy: destroy)
|
|
283
|
+
return v2InvalidResultDictionary("v2 create value carries no canonical editor id")
|
|
284
|
+
}
|
|
285
|
+
guard let adapter = EditorV2Adapter.attach(
|
|
286
|
+
editorId: createdHandle.handle,
|
|
287
|
+
roomBound: v2ConfigIndicatesRoomBinding(configJson)
|
|
288
|
+
) else {
|
|
289
|
+
_ = destroy(createdHandle.handle)
|
|
290
|
+
return v2InvalidResultDictionary("v2 create could not bind its editor handle")
|
|
291
|
+
}
|
|
292
|
+
EditorV2Registry.register(adapter, forLegacyId: createdHandle.nativeViewId)
|
|
293
|
+
NativeEditorViewRegistry.shared.markEditorCreated(editorId: createdHandle.nativeViewId)
|
|
294
|
+
return v2JsonResultDictionary(result)
|
|
295
|
+
case (nil, _?):
|
|
296
|
+
return v2JsonResultDictionary(result)
|
|
297
|
+
default:
|
|
298
|
+
cleanupCreatedV2Session(value: result.value, destroy: destroy)
|
|
299
|
+
return v2JsonResultDictionary(result)
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/// One canonical-handle destroy transaction. The handle reservation is the
|
|
304
|
+
/// contention authority because pairings are removed before native view
|
|
305
|
+
/// finalization. A paired adapter supplies its own FFI so its error owner is
|
|
306
|
+
/// committed only for exact terminal records; an unpaired session calls the
|
|
307
|
+
/// supplied public FFI directly.
|
|
308
|
+
func destroyEditorV2FromModule(
|
|
309
|
+
editorId: String,
|
|
310
|
+
destroy: (String) -> FfiUnitResult = { editorId in
|
|
311
|
+
editorV2Destroy(editorId: editorId)
|
|
312
|
+
}
|
|
313
|
+
) -> FfiUnitResult {
|
|
314
|
+
guard let nativeViewId = v2UInt64Argument(editorId), nativeViewId > 0 else {
|
|
315
|
+
return destroy(editorId)
|
|
316
|
+
}
|
|
317
|
+
guard EditorV2Registry.acquireHandleDestroyReservation(forLegacyId: nativeViewId) else {
|
|
318
|
+
return FfiUnitResult(value: nil, error: v2DestroyAlreadyInProgressError())
|
|
319
|
+
}
|
|
320
|
+
defer {
|
|
321
|
+
// The canonical-handle reservation remains visible until all paired
|
|
322
|
+
// cleanup has completed, including after the pairing disappears.
|
|
323
|
+
EditorV2Registry.releaseHandleDestroyReservation(forLegacyId: nativeViewId)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Pair lookup follows reservation acquisition. Do not make routing or
|
|
327
|
+
// contention decisions from a pairing that terminal teardown removes.
|
|
328
|
+
let adapter = EditorV2Registry.adapter(forLegacyId: nativeViewId)
|
|
329
|
+
let viewRegistry = NativeEditorViewRegistry.shared
|
|
330
|
+
let reservation = viewRegistry.acquireDestroyReservation(editorId: nativeViewId)
|
|
331
|
+
if reservation == .alreadyInProgress {
|
|
332
|
+
return FfiUnitResult(value: nil, error: v2DestroyAlreadyInProgressError())
|
|
333
|
+
}
|
|
334
|
+
let reserved = reservation == .reserved
|
|
335
|
+
if adapter != nil && !reserved {
|
|
336
|
+
return FfiUnitResult(
|
|
337
|
+
value: nil,
|
|
338
|
+
error: FfiError(
|
|
339
|
+
domain: "boundary",
|
|
340
|
+
code: "FFI_RESULT_INVALID",
|
|
341
|
+
message: "v2 destroy could not reserve its native view",
|
|
342
|
+
requestId: nil,
|
|
343
|
+
operationIndex: nil,
|
|
344
|
+
limit: nil,
|
|
345
|
+
actual: nil,
|
|
346
|
+
detailsJson: nil
|
|
347
|
+
)
|
|
348
|
+
)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Transport callbacks and retained sockets must lose ownership before
|
|
352
|
+
// the Rust session can be destroyed or its numeric handle reused.
|
|
353
|
+
let result: FfiUnitResult
|
|
354
|
+
if let adapter {
|
|
355
|
+
result = adapter.destroyForModuleTransaction {
|
|
356
|
+
NativeCollaborationTransportRegistry.destroy(editorId: nativeViewId)
|
|
357
|
+
}
|
|
358
|
+
} else {
|
|
359
|
+
NativeCollaborationTransportRegistry.destroy(editorId: nativeViewId)
|
|
360
|
+
result = destroy(editorId)
|
|
361
|
+
}
|
|
362
|
+
invokeDestroyTestingHook(
|
|
363
|
+
EditorV2Registry.onDestroyFfiResultReceivedForTesting,
|
|
364
|
+
editorId: nativeViewId
|
|
365
|
+
)
|
|
366
|
+
switch (result.value, result.error) {
|
|
367
|
+
case let (value?, nil) where value:
|
|
368
|
+
break
|
|
369
|
+
case let (nil, error?) where error.domain == "lifecycle"
|
|
370
|
+
&& (error.code == "ENGINE_DESTROYED" || error.code == "ENGINE_DESTROYING"):
|
|
371
|
+
break
|
|
372
|
+
case (nil, .some(_)):
|
|
373
|
+
if reserved { viewRegistry.rollbackDestroy(editorId: nativeViewId) }
|
|
374
|
+
return result
|
|
375
|
+
default:
|
|
376
|
+
if reserved { viewRegistry.rollbackDestroy(editorId: nativeViewId) }
|
|
377
|
+
return FfiUnitResult(
|
|
378
|
+
value: nil,
|
|
379
|
+
error: FfiError(
|
|
380
|
+
domain: "boundary",
|
|
381
|
+
code: "FFI_RESULT_INVALID",
|
|
382
|
+
message: "v2 destroy result violates the frozen unit-result shape",
|
|
383
|
+
requestId: nil,
|
|
384
|
+
operationIndex: nil,
|
|
385
|
+
limit: nil,
|
|
386
|
+
actual: nil,
|
|
387
|
+
detailsJson: nil
|
|
388
|
+
)
|
|
389
|
+
)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Terminal result only: the adapter clears its error owner before this
|
|
393
|
+
// point, then its pairing is removed while the command/callback gate is
|
|
394
|
+
// still held. The handle transaction remains held through finalization.
|
|
395
|
+
if adapter != nil {
|
|
396
|
+
_ = EditorV2Registry.removePairing(forLegacyId: nativeViewId)
|
|
397
|
+
invokeDestroyTestingHook(
|
|
398
|
+
EditorV2Registry.onPairRemovedBeforeDestroyFinalizationForTesting,
|
|
399
|
+
editorId: nativeViewId
|
|
400
|
+
)
|
|
401
|
+
}
|
|
402
|
+
if reserved { viewRegistry.finalizeDestroy(editorId: nativeViewId) }
|
|
403
|
+
return result
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/// Test-facing wrapper retained only to inject the raw FFI result for an
|
|
407
|
+
/// unpaired handle. Production routing uses `destroyEditorV2FromModule`.
|
|
408
|
+
func destroyUnpairedEditorV2FromModule(
|
|
409
|
+
editorId: String,
|
|
410
|
+
nativeViewId _: UInt64,
|
|
411
|
+
destroy: (String) -> FfiUnitResult = { editorId in
|
|
412
|
+
editorV2Destroy(editorId: editorId)
|
|
413
|
+
}
|
|
414
|
+
) -> FfiUnitResult {
|
|
415
|
+
destroyEditorV2FromModule(editorId: editorId, destroy: destroy)
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/// Whether the JS-facing create config initializes a room-bound session
|
|
419
|
+
/// (the paired adapter mirrors the binding for its collaboration gating).
|
|
420
|
+
private func v2ConfigIndicatesRoomBinding(_ configJson: String) -> Bool {
|
|
421
|
+
guard let data = configJson.data(using: .utf8),
|
|
422
|
+
let config = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
423
|
+
let initialization = config["initialization"] as? [String: Any]
|
|
424
|
+
else {
|
|
425
|
+
return false
|
|
426
|
+
}
|
|
427
|
+
return initialization["type"] as? String == "room"
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
final class NativeEditorModuleSessionOwner {
|
|
431
|
+
private let lock = NSLock()
|
|
432
|
+
private var editorIds: Set<String> = []
|
|
433
|
+
|
|
434
|
+
var countForTesting: Int {
|
|
435
|
+
lock.lock()
|
|
436
|
+
defer { lock.unlock() }
|
|
437
|
+
return editorIds.count
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
func insert(_ editorId: String) {
|
|
441
|
+
guard let value = v2CanonicalUInt64String(editorId), value != "0" else { return }
|
|
442
|
+
lock.lock()
|
|
443
|
+
editorIds.insert(value)
|
|
444
|
+
lock.unlock()
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
func remove(_ editorId: String) {
|
|
448
|
+
lock.lock()
|
|
449
|
+
editorIds.remove(editorId)
|
|
450
|
+
lock.unlock()
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
func destroyAll(
|
|
454
|
+
_ destroy: (String) -> FfiUnitResult = {
|
|
455
|
+
destroyEditorV2FromModule(editorId: $0)
|
|
456
|
+
}
|
|
457
|
+
) {
|
|
458
|
+
lock.lock()
|
|
459
|
+
let ownedEditorIds = editorIds.sorted()
|
|
460
|
+
editorIds.removeAll()
|
|
461
|
+
lock.unlock()
|
|
462
|
+
for editorId in ownedEditorIds {
|
|
463
|
+
_ = destroy(editorId)
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
private func isTerminalEditorV2DestroyResult(_ result: FfiUnitResult) -> Bool {
|
|
469
|
+
if result.value == true, result.error == nil { return true }
|
|
470
|
+
guard result.value == nil, let error = result.error else { return false }
|
|
471
|
+
return error.domain == "lifecycle"
|
|
472
|
+
&& (error.code == "ENGINE_DESTROYED" || error.code == "ENGINE_DESTROYING")
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// `Module` is `BaseModule & AnyModule`; the conformance is spelled out so
|
|
476
|
+
// `AnyModule` can carry `@preconcurrency`. That is what lets `definition()`
|
|
477
|
+
// below be `@MainActor` even though the protocol requirement is nonisolated.
|
|
478
|
+
//
|
|
479
|
+
// Why `definition()` has to be main-actor isolated: expo-modules-core declares
|
|
480
|
+
// `extension UIView: @MainActor AnyArgument`, so every `UIView` subclass gets a
|
|
481
|
+
// main-actor-isolated `AnyArgument` conformance. The `AsyncFunction` factories
|
|
482
|
+
// used for view functions require `A0: AnyArgument`, and an isolated conformance
|
|
483
|
+
// may only be used from a context isolated to the same actor — otherwise the
|
|
484
|
+
// compiler reports `#IsolatedConformances` (a warning in Swift 5 mode, an error
|
|
485
|
+
// in Swift 6).
|
|
486
|
+
//
|
|
487
|
+
// Caveat: `definition()` is actually invoked on the JS thread
|
|
488
|
+
// (`EXReactNativeFactory host:didInitializeRuntime:` → `registerNativeModules`),
|
|
489
|
+
// so the isolation claimed here is a compile-time device only. Under Swift 5
|
|
490
|
+
// mode the witness thunk is a plain passthrough — no executor check is emitted —
|
|
491
|
+
// but that also means nothing in this method body may touch main-actor state.
|
|
492
|
+
// Keep it pure definition building.
|
|
493
|
+
public class NativeEditorModule: BaseModule, @preconcurrency AnyModule {
|
|
494
|
+
private var collaborationLifecycleObservers: [NSObjectProtocol] = []
|
|
495
|
+
private let collaborationOwner = UUID()
|
|
496
|
+
private let sessionOwner = NativeEditorModuleSessionOwner()
|
|
497
|
+
|
|
498
|
+
@MainActor
|
|
499
|
+
public func definition() -> ModuleDefinition {
|
|
500
|
+
Name("NativeEditor")
|
|
501
|
+
// Benchmark-only controls are deterministic and surface-independent;
|
|
502
|
+
// they never participate in a viewer draw or measurement path.
|
|
503
|
+
Function("preparedProseBenchmarkBegin") {
|
|
504
|
+
PreparedProseInstrumentation.beginBenchmark()
|
|
505
|
+
}
|
|
506
|
+
Function("preparedProseBenchmarkBeginPhase") { (phase: String) in
|
|
507
|
+
guard let traversal = PreparedProseInstrumentation.TraversalPhase(rawValue: phase) else { return }
|
|
508
|
+
PreparedProseInstrumentation.beginPhase(traversal)
|
|
509
|
+
}
|
|
510
|
+
Function("preparedProseBenchmarkEndPhase") {
|
|
511
|
+
PreparedProseInstrumentation.endPhase()
|
|
512
|
+
}
|
|
513
|
+
Function("preparedProseBenchmarkReset") {
|
|
514
|
+
PreparedProseLayoutRegistry.shared.didReceiveMemoryWarning()
|
|
515
|
+
PreparedProseInstrumentation.invalidated(.cacheReset)
|
|
516
|
+
}
|
|
517
|
+
Function("preparedProseBenchmarkExport") { () -> String in
|
|
518
|
+
PreparedProseInstrumentation.exportJSON()
|
|
519
|
+
}
|
|
520
|
+
Events("onCollaborationTransportEvent")
|
|
521
|
+
|
|
522
|
+
OnCreate {
|
|
523
|
+
NativeCollaborationTransportRegistry.setEventEmitter(owner: self.collaborationOwner) { [weak self] payload in
|
|
524
|
+
DispatchQueue.main.async {
|
|
525
|
+
self?.sendEvent("onCollaborationTransportEvent", payload)
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
let center = NotificationCenter.default
|
|
529
|
+
self.collaborationLifecycleObservers = [
|
|
530
|
+
center.addObserver(
|
|
531
|
+
forName: UIApplication.didEnterBackgroundNotification,
|
|
532
|
+
object: nil,
|
|
533
|
+
queue: nil
|
|
534
|
+
) { _ in
|
|
535
|
+
NativeCollaborationTransportRegistry.enterBackground()
|
|
536
|
+
},
|
|
537
|
+
center.addObserver(
|
|
538
|
+
forName: UIApplication.willEnterForegroundNotification,
|
|
539
|
+
object: nil,
|
|
540
|
+
queue: nil
|
|
541
|
+
) { _ in
|
|
542
|
+
NativeCollaborationTransportRegistry.enterForeground()
|
|
543
|
+
}
|
|
544
|
+
]
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
OnDestroy {
|
|
548
|
+
let center = NotificationCenter.default
|
|
549
|
+
self.collaborationLifecycleObservers.forEach(center.removeObserver)
|
|
550
|
+
self.collaborationLifecycleObservers.removeAll()
|
|
551
|
+
self.sessionOwner.destroyAll()
|
|
552
|
+
NativeCollaborationTransportRegistry.destroyAll(owner: self.collaborationOwner)
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// MARK: v2 UniFFI surface (production ABI)
|
|
556
|
+
//
|
|
557
|
+
// The JS document handle drives the engine directly through these
|
|
558
|
+
// passthroughs; every call returns the frozen {value, error} result
|
|
559
|
+
// record. Decimal-string handles/generations keep full u64 fidelity
|
|
560
|
+
// across the JS boundary; binaries travel as Data.
|
|
561
|
+
|
|
562
|
+
Function("editorV2Create") { (configJson: String, snapshotState: Data?) -> [String: Any] in
|
|
563
|
+
let result = createEditorV2SessionFromModule(configJson: configJson, snapshotState: snapshotState)
|
|
564
|
+
if let value = result["value"] as? String,
|
|
565
|
+
let handle = createdV2SessionHandle(value) {
|
|
566
|
+
self.sessionOwner.insert(handle.handle)
|
|
567
|
+
}
|
|
568
|
+
return result
|
|
569
|
+
}
|
|
570
|
+
Function("editorV2Destroy") { (editorId: String) -> [String: Any] in
|
|
571
|
+
let result = destroyEditorV2FromModule(editorId: editorId)
|
|
572
|
+
if isTerminalEditorV2DestroyResult(result) {
|
|
573
|
+
self.sessionOwner.remove(editorId)
|
|
574
|
+
}
|
|
575
|
+
return v2UnitResultDictionary(result)
|
|
576
|
+
}
|
|
577
|
+
Function("editorV2GetState") { (editorId: String) -> [String: Any] in
|
|
578
|
+
v2JsonResultDictionary(performEditorV2JsonOperation(editorId: editorId) {
|
|
579
|
+
editorV2GetState(editorId: editorId)
|
|
580
|
+
})
|
|
581
|
+
}
|
|
582
|
+
Function("editorV2GetDocumentJson") { (editorId: String) -> [String: Any] in
|
|
583
|
+
v2JsonResultDictionary(performEditorV2JsonOperation(editorId: editorId) {
|
|
584
|
+
editorV2GetDocumentJson(editorId: editorId)
|
|
585
|
+
})
|
|
586
|
+
}
|
|
587
|
+
Function("editorV2GetDocumentHtml") { (editorId: String) -> [String: Any] in
|
|
588
|
+
v2JsonResultDictionary(performEditorV2JsonOperation(editorId: editorId) {
|
|
589
|
+
editorV2GetDocumentHtml(editorId: editorId)
|
|
590
|
+
})
|
|
591
|
+
}
|
|
592
|
+
Function("editorV2GetContentSnapshot") { (editorId: String) -> [String: Any] in
|
|
593
|
+
v2JsonResultDictionary(performEditorV2JsonOperation(editorId: editorId) {
|
|
594
|
+
editorV2GetContentSnapshot(editorId: editorId)
|
|
595
|
+
})
|
|
596
|
+
}
|
|
597
|
+
Function("editorV2ReplaceDocument") { (editorId: String, requestJson: String) -> [String: Any] in
|
|
598
|
+
v2MutationResultDictionary(
|
|
599
|
+
editorId: editorId,
|
|
600
|
+
result: performEditorV2JsonOperation(editorId: editorId) {
|
|
601
|
+
editorV2ReplaceDocument(editorId: editorId, requestJson: requestJson)
|
|
602
|
+
}
|
|
603
|
+
)
|
|
604
|
+
}
|
|
605
|
+
Function("editorV2ApplyInput") { (editorId: String, requestJson: String) -> [String: Any] in
|
|
606
|
+
v2MutationResultDictionary(
|
|
607
|
+
editorId: editorId,
|
|
608
|
+
result: performEditorV2JsonOperation(editorId: editorId) {
|
|
609
|
+
editorV2ApplyInput(editorId: editorId, requestJson: requestJson)
|
|
610
|
+
}
|
|
611
|
+
)
|
|
612
|
+
}
|
|
613
|
+
Function("editorV2ApplyCommand") { (editorId: String, requestJson: String) -> [String: Any] in
|
|
614
|
+
v2MutationResultDictionary(
|
|
615
|
+
editorId: editorId,
|
|
616
|
+
result: performEditorV2JsonOperation(editorId: editorId) {
|
|
617
|
+
editorV2ApplyCommand(editorId: editorId, requestJson: requestJson)
|
|
618
|
+
}
|
|
619
|
+
)
|
|
620
|
+
}
|
|
621
|
+
Function("editorV2ApplyLocalApi") { (editorId: String, requestJson: String) -> [String: Any] in
|
|
622
|
+
v2MutationResultDictionary(
|
|
623
|
+
editorId: editorId,
|
|
624
|
+
result: performEditorV2JsonOperation(editorId: editorId) {
|
|
625
|
+
editorV2ApplyLocalApi(editorId: editorId, requestJson: requestJson)
|
|
626
|
+
}
|
|
627
|
+
)
|
|
628
|
+
}
|
|
629
|
+
Function("editorV2SetSelection") { (editorId: String, requestJson: String) -> [String: Any] in
|
|
630
|
+
v2JsonResultDictionary(performEditorV2JsonOperation(editorId: editorId) {
|
|
631
|
+
editorV2SetSelection(editorId: editorId, requestJson: requestJson)
|
|
632
|
+
})
|
|
633
|
+
}
|
|
634
|
+
Function("editorV2Undo") { (editorId: String, requestJson: String) -> [String: Any] in
|
|
635
|
+
v2MutationResultDictionary(
|
|
636
|
+
editorId: editorId,
|
|
637
|
+
result: performEditorV2JsonOperation(editorId: editorId) {
|
|
638
|
+
editorV2Undo(editorId: editorId, requestJson: requestJson)
|
|
639
|
+
}
|
|
640
|
+
)
|
|
641
|
+
}
|
|
642
|
+
Function("editorV2Redo") { (editorId: String, requestJson: String) -> [String: Any] in
|
|
643
|
+
v2MutationResultDictionary(
|
|
644
|
+
editorId: editorId,
|
|
645
|
+
result: performEditorV2JsonOperation(editorId: editorId) {
|
|
646
|
+
editorV2Redo(editorId: editorId, requestJson: requestJson)
|
|
647
|
+
}
|
|
648
|
+
)
|
|
649
|
+
}
|
|
650
|
+
Function("editorV2RenderUpdate") { (editorId: String, mirrorScalarAnchor: Double?, mirrorScalarHead: Double?) -> [String: Any] in
|
|
651
|
+
// The render accessor for the interactive component: after a
|
|
652
|
+
// JS-driven engine change the component fetches the current
|
|
653
|
+
// render update here and pushes it to the bound view.
|
|
654
|
+
let anchor = mirrorScalarAnchor.flatMap { v2ExactUInt32(NSNumber(value: $0)) }
|
|
655
|
+
let head = mirrorScalarHead.flatMap { v2ExactUInt32(NSNumber(value: $0)) }
|
|
656
|
+
if (mirrorScalarAnchor != nil && anchor == nil) || (mirrorScalarHead != nil && head == nil) {
|
|
657
|
+
return v2InvalidResultDictionary("invalid render scalar position")
|
|
658
|
+
}
|
|
659
|
+
return v2JsonResultDictionary(
|
|
660
|
+
performEditorV2JsonOperation(editorId: editorId) {
|
|
661
|
+
editorV2RenderUpdate(
|
|
662
|
+
editorId: editorId,
|
|
663
|
+
mirrorScalarAnchor: anchor,
|
|
664
|
+
mirrorScalarHead: head
|
|
665
|
+
)
|
|
666
|
+
}
|
|
667
|
+
)
|
|
668
|
+
}
|
|
669
|
+
Function("editorV2CollaborationConfigureTransport") { (editorId: String, configJsonOrNull: String?) -> [String: Any] in
|
|
670
|
+
guard let nativeEditorId = v2UInt64Argument(editorId), nativeEditorId > 0 else {
|
|
671
|
+
return v2InvalidResultDictionary("invalid editorId")
|
|
672
|
+
}
|
|
673
|
+
let error = NativeCollaborationTransportRegistry.configure(
|
|
674
|
+
owner: self.collaborationOwner,
|
|
675
|
+
editorId: nativeEditorId,
|
|
676
|
+
configJSON: configJsonOrNull
|
|
677
|
+
)
|
|
678
|
+
return v2UnitResultDictionary(FfiUnitResult(
|
|
679
|
+
value: error == nil ? true : nil,
|
|
680
|
+
error: error
|
|
681
|
+
))
|
|
682
|
+
}
|
|
683
|
+
Function("editorV2CollaborationResolveProtocolAdapter") { (editorId: String, attemptId: String, eventId: String, responseJson: String) -> [String: Any] in
|
|
684
|
+
guard let nativeEditorId = v2UInt64Argument(editorId), nativeEditorId > 0 else {
|
|
685
|
+
return v2InvalidResultDictionary("invalid editorId")
|
|
686
|
+
}
|
|
687
|
+
let error = NativeCollaborationTransportRegistry.resolveProtocolAdapter(
|
|
688
|
+
editorId: nativeEditorId,
|
|
689
|
+
attemptId: attemptId,
|
|
690
|
+
eventId: eventId,
|
|
691
|
+
responseJSON: responseJson
|
|
692
|
+
)
|
|
693
|
+
return v2UnitResultDictionary(FfiUnitResult(
|
|
694
|
+
value: error == nil ? true : nil,
|
|
695
|
+
error: error
|
|
696
|
+
))
|
|
697
|
+
}
|
|
698
|
+
Function("editorV2CollaborationSetAwareness") { (editorId: String, awarenessJson: String) -> [String: Any] in
|
|
699
|
+
let result = performEditorV2UnitOperation(editorId: editorId) {
|
|
700
|
+
editorV2CollaborationSetAwareness(
|
|
701
|
+
editorId: editorId,
|
|
702
|
+
awarenessJson: awarenessJson
|
|
703
|
+
)
|
|
704
|
+
}
|
|
705
|
+
if result.value == true, result.error == nil,
|
|
706
|
+
let nativeEditorId = v2UInt64Argument(editorId) {
|
|
707
|
+
NativeCollaborationTransportRegistry.notifyOutboundAvailable(
|
|
708
|
+
editorId: nativeEditorId,
|
|
709
|
+
reason: .awareness
|
|
710
|
+
)
|
|
711
|
+
}
|
|
712
|
+
return v2UnitResultDictionary(result)
|
|
713
|
+
}
|
|
714
|
+
Function("editorV2CollaborationPeers") { (editorId: String) -> [String: Any] in
|
|
715
|
+
v2JsonResultDictionary(performEditorV2JsonOperation(editorId: editorId) {
|
|
716
|
+
editorV2CollaborationPeers(editorId: editorId)
|
|
717
|
+
})
|
|
718
|
+
}
|
|
719
|
+
Function("editorV2SnapshotExport") { (editorId: String) -> [String: Any] in
|
|
720
|
+
v2SnapshotExportResultDictionary(performEditorV2SnapshotExportOperation(editorId: editorId) {
|
|
721
|
+
editorV2SnapshotExport(editorId: editorId)
|
|
722
|
+
})
|
|
723
|
+
}
|
|
724
|
+
Function("editorV2SnapshotRestore") { (editorId: String, metadataJson: String, encodedState: Data) -> [String: Any] in
|
|
725
|
+
v2MutationResultDictionary(
|
|
726
|
+
editorId: editorId,
|
|
727
|
+
result: performEditorV2JsonOperation(editorId: editorId) {
|
|
728
|
+
editorV2SnapshotRestore(
|
|
729
|
+
editorId: editorId,
|
|
730
|
+
metadataJson: metadataJson,
|
|
731
|
+
encodedState: encodedState
|
|
732
|
+
)
|
|
733
|
+
}
|
|
734
|
+
)
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
View(NativeEditorExpoView.self) {
|
|
738
|
+
Events(
|
|
739
|
+
"onEditorUpdate",
|
|
740
|
+
"onSelectionChange",
|
|
741
|
+
"onFocusChange",
|
|
742
|
+
"onContentHeightChange",
|
|
743
|
+
"onAtomLayout",
|
|
744
|
+
"onToolbarAction",
|
|
745
|
+
"onAddonEvent",
|
|
746
|
+
"onEditorError",
|
|
747
|
+
"onExternalTextCompositionEnd"
|
|
748
|
+
)
|
|
749
|
+
|
|
750
|
+
Prop("editorId") { (view: NativeEditorExpoView, id: String) in
|
|
751
|
+
applyNativeEditorIdProp(id, to: view)
|
|
752
|
+
}
|
|
753
|
+
Prop("editable") { (view: NativeEditorExpoView, editable: Bool) in
|
|
754
|
+
view.setEditable(editable)
|
|
755
|
+
}
|
|
756
|
+
Prop("accessibilityLabel") { (view: NativeEditorExpoView, label: String?) in
|
|
757
|
+
view.setAccessibilityLabel(label)
|
|
758
|
+
}
|
|
759
|
+
Prop("accessibilityHint") { (view: NativeEditorExpoView, hint: String?) in
|
|
760
|
+
view.setAccessibilityHint(hint)
|
|
761
|
+
}
|
|
762
|
+
Prop("placeholder") { (view: NativeEditorExpoView, placeholder: String) in
|
|
763
|
+
view.richTextView.textView.placeholder = placeholder
|
|
764
|
+
}
|
|
765
|
+
Prop("autoFocus") { (view: NativeEditorExpoView, autoFocus: Bool) in
|
|
766
|
+
view.setAutoFocus(autoFocus)
|
|
767
|
+
}
|
|
768
|
+
Prop("autoCapitalize") { (view: NativeEditorExpoView, autoCapitalize: String?) in
|
|
769
|
+
view.setAutoCapitalize(autoCapitalize)
|
|
770
|
+
}
|
|
771
|
+
Prop("autoCorrect") { (view: NativeEditorExpoView, autoCorrect: Bool?) in
|
|
772
|
+
view.setAutoCorrect(autoCorrect)
|
|
773
|
+
}
|
|
774
|
+
Prop("keyboardType") { (view: NativeEditorExpoView, keyboardType: String?) in
|
|
775
|
+
view.setKeyboardType(keyboardType)
|
|
776
|
+
}
|
|
777
|
+
Prop("showToolbar") { (view: NativeEditorExpoView, showToolbar: Bool) in
|
|
778
|
+
view.setShowToolbar(showToolbar)
|
|
779
|
+
}
|
|
780
|
+
Prop("toolbarPlacement") { (view: NativeEditorExpoView, toolbarPlacement: String?) in
|
|
781
|
+
view.setToolbarPlacement(toolbarPlacement)
|
|
782
|
+
}
|
|
783
|
+
Prop("heightBehavior") { (view: NativeEditorExpoView, heightBehavior: String) in
|
|
784
|
+
view.setHeightBehavior(heightBehavior)
|
|
785
|
+
}
|
|
786
|
+
Prop("allowImageResizing") { (view: NativeEditorExpoView, allowImageResizing: Bool) in
|
|
787
|
+
view.setAllowImageResizing(allowImageResizing)
|
|
788
|
+
}
|
|
789
|
+
Prop("imageLoadingPolicyJson") { (view: NativeEditorExpoView, json: String?) in
|
|
790
|
+
view.setImageLoadingPolicyJson(json)
|
|
791
|
+
}
|
|
792
|
+
Prop("themeJson") { (view: NativeEditorExpoView, themeJson: String?) in
|
|
793
|
+
view.setThemeJson(themeJson)
|
|
794
|
+
}
|
|
795
|
+
Prop("addonsJson") { (view: NativeEditorExpoView, addonsJson: String?) in
|
|
796
|
+
view.setAddonsJson(addonsJson)
|
|
797
|
+
}
|
|
798
|
+
Prop("atomsJson") { (view: NativeEditorExpoView, atomsJson: String?) in
|
|
799
|
+
view.setAtomsJson(atomsJson)
|
|
800
|
+
}
|
|
801
|
+
Prop("remoteSelectionsJson") { (view: NativeEditorExpoView, remoteSelectionsJson: String?) in
|
|
802
|
+
view.setRemoteSelectionsJson(remoteSelectionsJson)
|
|
803
|
+
}
|
|
804
|
+
Prop("toolbarItemsJson") { (view: NativeEditorExpoView, toolbarItemsJson: String?) in
|
|
805
|
+
view.setToolbarButtonsJson(toolbarItemsJson)
|
|
806
|
+
}
|
|
807
|
+
Prop("toolbarFrameJson") { (view: NativeEditorExpoView, toolbarFrameJson: String?) in
|
|
808
|
+
view.setToolbarFrameJson(toolbarFrameJson)
|
|
809
|
+
}
|
|
810
|
+
Prop("editorUpdateResetJson") { (view: NativeEditorExpoView, resetJson: String?) in
|
|
811
|
+
view.pendingEditorUpdateResetJSON = resetJson
|
|
812
|
+
}
|
|
813
|
+
Prop("editorUpdateJson") { (view: NativeEditorExpoView, editorUpdateJson: String?) in
|
|
814
|
+
view.setPendingEditorUpdateJson(editorUpdateJson)
|
|
815
|
+
}
|
|
816
|
+
Prop("editorUpdateEditorId") { (view: NativeEditorExpoView, editorUpdateEditorId: String?) in
|
|
817
|
+
view.setPendingEditorUpdateEditorId(editorUpdateEditorId)
|
|
818
|
+
}
|
|
819
|
+
Prop("editorUpdateRevision") { (view: NativeEditorExpoView, editorUpdateRevision: Double) in
|
|
820
|
+
guard let exactRevision = v2ExactUInt32(NSNumber(value: editorUpdateRevision)) else {
|
|
821
|
+
return
|
|
822
|
+
}
|
|
823
|
+
view.setPendingEditorUpdateRevision(Int(exactRevision))
|
|
824
|
+
}
|
|
825
|
+
OnViewDidUpdateProps { (view: NativeEditorExpoView) in
|
|
826
|
+
view.applyPendingEditorUpdateIfNeeded()
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
AsyncFunction("applyEditorUpdate") { (view: NativeEditorExpoView, updateJson: String) -> Bool in
|
|
830
|
+
view.applyEditorUpdate(updateJson)
|
|
831
|
+
}
|
|
832
|
+
AsyncFunction("beginExternalTextComposition") { (view: NativeEditorExpoView, sessionId: String) -> String in
|
|
833
|
+
view.beginExternalTextComposition(sessionId: sessionId)
|
|
834
|
+
}
|
|
835
|
+
AsyncFunction("updateExternalTextComposition") { (view: NativeEditorExpoView, sessionId: String, text: String) -> String in
|
|
836
|
+
view.updateExternalTextComposition(sessionId: sessionId, text: text)
|
|
837
|
+
}
|
|
838
|
+
AsyncFunction("commitExternalTextComposition") { (view: NativeEditorExpoView, sessionId: String, text: String) -> String in
|
|
839
|
+
view.commitExternalTextComposition(sessionId: sessionId, finalText: text)
|
|
840
|
+
}
|
|
841
|
+
AsyncFunction("cancelExternalTextComposition") { (view: NativeEditorExpoView, sessionId: String, cause: String) -> String in
|
|
842
|
+
view.cancelExternalTextComposition(sessionId: sessionId, cause: cause)
|
|
843
|
+
}
|
|
844
|
+
AsyncFunction("focus") { (view: NativeEditorExpoView) in
|
|
845
|
+
view.focus()
|
|
846
|
+
}
|
|
847
|
+
AsyncFunction("blur") { (view: NativeEditorExpoView) in
|
|
848
|
+
view.blur()
|
|
849
|
+
}
|
|
850
|
+
AsyncFunction("getCaretRect") { (view: NativeEditorExpoView) -> String? in
|
|
851
|
+
view.getCaretRectJson()
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
}
|
|
856
|
+
}
|