@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,392 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
extension EditorV2Adapter {
|
|
4
|
+
enum MutationKind {
|
|
5
|
+
case transaction(changed: Bool, revision: UInt64)
|
|
6
|
+
case notApplicable
|
|
7
|
+
case replacement(changed: Bool, revision: UInt64)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
struct MutationOutcome {
|
|
11
|
+
let kind: MutationKind
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
func parseMutationOutcome(_ json: String) -> MutationOutcome? {
|
|
15
|
+
guard let data = json.data(using: .utf8),
|
|
16
|
+
let object = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
17
|
+
let type = object["type"] as? String
|
|
18
|
+
else { return nil }
|
|
19
|
+
switch type {
|
|
20
|
+
case "transaction":
|
|
21
|
+
guard let changed = object["changed"] as? Bool,
|
|
22
|
+
let revision = Self.uint64Field(object, "documentRevision")
|
|
23
|
+
else { return nil }
|
|
24
|
+
return MutationOutcome(kind: .transaction(changed: changed, revision: revision))
|
|
25
|
+
case "notApplicable":
|
|
26
|
+
return MutationOutcome(kind: .notApplicable)
|
|
27
|
+
case "replacement":
|
|
28
|
+
guard let changed = object["changed"] as? Bool,
|
|
29
|
+
let revision = Self.uint64Field(object, "documentRevision")
|
|
30
|
+
else { return nil }
|
|
31
|
+
return MutationOutcome(kind: .replacement(changed: changed, revision: revision))
|
|
32
|
+
default:
|
|
33
|
+
return nil
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private func handleMutationError(_ error: FfiError) -> String? {
|
|
38
|
+
if error.code == "REVISION_MISMATCH" {
|
|
39
|
+
let update = refreshInternal(
|
|
40
|
+
mirrorSelection: nil,
|
|
41
|
+
strippingViewSelection: false
|
|
42
|
+
)?.updateJSON
|
|
43
|
+
debugNotes.append("mismatch-refresh \(update == nil ? "nil" : "ok")")
|
|
44
|
+
return update
|
|
45
|
+
}
|
|
46
|
+
emit(error)
|
|
47
|
+
return nil
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
struct NativeMutationRender {
|
|
51
|
+
let updateJSON: String
|
|
52
|
+
let changed: Bool
|
|
53
|
+
let documentChanged: Bool
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
struct NativeIntentOutcome {
|
|
57
|
+
let changed: Bool
|
|
58
|
+
let documentChanged: Bool
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
func nativeIntent(_ type: String, anchor: UInt32, head: UInt32) -> [String: Any] {
|
|
62
|
+
[
|
|
63
|
+
"type": type,
|
|
64
|
+
"anchor": Int(clampScalar(anchor)),
|
|
65
|
+
"head": Int(clampScalar(head))
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
func submitNativeIntent(
|
|
70
|
+
_ intent: [String: Any],
|
|
71
|
+
reportPositionEpochInvalid: Bool = false,
|
|
72
|
+
refreshPositionEpochInvalid: Bool = true
|
|
73
|
+
) -> NativeIntentOutcome? {
|
|
74
|
+
guard !destroyed else { return nil }
|
|
75
|
+
guard let nativeOwnerId else { return nil }
|
|
76
|
+
if positionEpoch == nil {
|
|
77
|
+
guard refreshInternal(mirrorSelection: nil, strippingViewSelection: false) != nil else {
|
|
78
|
+
return nil
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
guard let positionEpoch else { return nil }
|
|
82
|
+
let result = callWithEnvelope(
|
|
83
|
+
[
|
|
84
|
+
"ownerId": String(nativeOwnerId),
|
|
85
|
+
"positionEpoch": String(positionEpoch),
|
|
86
|
+
"intent": intent
|
|
87
|
+
],
|
|
88
|
+
includeBaseRevision: false
|
|
89
|
+
) { requestJson in
|
|
90
|
+
editorV2ApplyNativeIntent(editorId: self.editorId, requestJson: requestJson)
|
|
91
|
+
}
|
|
92
|
+
switch Self.normalizeJsonResult(result) {
|
|
93
|
+
case .failure(let error):
|
|
94
|
+
if error.code == "POSITION_EPOCH_INVALID" {
|
|
95
|
+
debugNotes.append(
|
|
96
|
+
refreshPositionEpochInvalid
|
|
97
|
+
? "position-epoch-refresh"
|
|
98
|
+
: "position-epoch-invalid"
|
|
99
|
+
)
|
|
100
|
+
if refreshPositionEpochInvalid {
|
|
101
|
+
_ = refreshInternal(mirrorSelection: nil, strippingViewSelection: false)
|
|
102
|
+
}
|
|
103
|
+
if reportPositionEpochInvalid {
|
|
104
|
+
emit(error)
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
emit(error)
|
|
108
|
+
}
|
|
109
|
+
return nil
|
|
110
|
+
case .success(let value):
|
|
111
|
+
guard let outcome = parseMutationOutcome(value) else {
|
|
112
|
+
emit(contractError("v2 native intent outcome violates the frozen shape"))
|
|
113
|
+
return nil
|
|
114
|
+
}
|
|
115
|
+
let changed: Bool
|
|
116
|
+
switch outcome.kind {
|
|
117
|
+
case .transaction(let didChange, let revision):
|
|
118
|
+
changed = didChange
|
|
119
|
+
baseDocumentRevision = revision
|
|
120
|
+
case .notApplicable:
|
|
121
|
+
changed = false
|
|
122
|
+
case .replacement(let didChange, let revision):
|
|
123
|
+
changed = didChange
|
|
124
|
+
baseDocumentRevision = revision
|
|
125
|
+
}
|
|
126
|
+
let documentChanged: Bool
|
|
127
|
+
switch outcome.kind {
|
|
128
|
+
case .notApplicable:
|
|
129
|
+
documentChanged = false
|
|
130
|
+
case .transaction, .replacement:
|
|
131
|
+
guard let data = value.data(using: .utf8),
|
|
132
|
+
let object = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
133
|
+
let didChangeDocument = object["documentChanged"] as? Bool
|
|
134
|
+
else {
|
|
135
|
+
emit(contractError("v2 native intent outcome violates the frozen shape"))
|
|
136
|
+
return nil
|
|
137
|
+
}
|
|
138
|
+
documentChanged = didChangeDocument
|
|
139
|
+
}
|
|
140
|
+
return NativeIntentOutcome(
|
|
141
|
+
changed: changed,
|
|
142
|
+
documentChanged: documentChanged
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
func renderNativeIntentOutcome(
|
|
148
|
+
_ outcome: NativeIntentOutcome,
|
|
149
|
+
publishMutation: Bool = true
|
|
150
|
+
) -> NativeMutationRender? {
|
|
151
|
+
guard let update = refreshInternal(
|
|
152
|
+
mirrorSelection: nil,
|
|
153
|
+
strippingViewSelection: false
|
|
154
|
+
)?.updateJSON else {
|
|
155
|
+
return nil
|
|
156
|
+
}
|
|
157
|
+
lastSyncedScalarSelection = cachedAuthoritativeScalarSelection
|
|
158
|
+
if publishMutation, outcome.changed {
|
|
159
|
+
publishCachedCollaborationSelection()
|
|
160
|
+
notifyCollaborationMutation()
|
|
161
|
+
}
|
|
162
|
+
return NativeMutationRender(
|
|
163
|
+
updateJSON: update,
|
|
164
|
+
changed: outcome.changed,
|
|
165
|
+
documentChanged: outcome.documentChanged
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
static func replacingRender(
|
|
170
|
+
in stateUpdateJSON: String,
|
|
171
|
+
with renderUpdateJSON: String
|
|
172
|
+
) -> String? {
|
|
173
|
+
guard let stateData = stateUpdateJSON.data(using: .utf8),
|
|
174
|
+
var stateUpdate = try? JSONSerialization.jsonObject(with: stateData) as? [String: Any],
|
|
175
|
+
let renderData = renderUpdateJSON.data(using: .utf8),
|
|
176
|
+
let renderUpdate = try? JSONSerialization.jsonObject(with: renderData) as? [String: Any]
|
|
177
|
+
else {
|
|
178
|
+
return nil
|
|
179
|
+
}
|
|
180
|
+
for key in ["renderBlocks", "renderPatch", "renderElements"] {
|
|
181
|
+
if renderUpdate.keys.contains(key) {
|
|
182
|
+
stateUpdate[key] = renderUpdate[key]
|
|
183
|
+
} else {
|
|
184
|
+
stateUpdate.removeValue(forKey: key)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
guard let combinedData = try? JSONSerialization.data(withJSONObject: stateUpdate) else {
|
|
188
|
+
return nil
|
|
189
|
+
}
|
|
190
|
+
return String(data: combinedData, encoding: .utf8)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
func performNativeIntent(
|
|
194
|
+
_ intent: [String: Any],
|
|
195
|
+
reportPositionEpochInvalid: Bool = false
|
|
196
|
+
) -> NativeMutationRender? {
|
|
197
|
+
guard let outcome = submitNativeIntent(
|
|
198
|
+
intent,
|
|
199
|
+
reportPositionEpochInvalid: reportPositionEpochInvalid
|
|
200
|
+
) else {
|
|
201
|
+
return nil
|
|
202
|
+
}
|
|
203
|
+
return renderNativeIntentOutcome(outcome)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/// One typed v2 mutation: optional selection pre-sync, one transaction,
|
|
207
|
+
/// revision tracking, render synthesis, and the collaboration drain ping.
|
|
208
|
+
///
|
|
209
|
+
/// The synthesized update mirrors the post-mutation selection whenever
|
|
210
|
+
/// the caller tracks one (typing/commands) so the view can restore the
|
|
211
|
+
/// caret — the legacy engine's updates always carried the selection.
|
|
212
|
+
/// Callers that must NOT move the view caret (paste paths) pass no
|
|
213
|
+
/// postSelectionMirror and get a selection-less update.
|
|
214
|
+
/// - Parameter adoptEngineSelection: report the engine's own post-command
|
|
215
|
+
/// selection instead of forcing the caret back to caller-supplied
|
|
216
|
+
/// offsets. Required for any command that can restructure the document:
|
|
217
|
+
/// wrapping a line in a list inserts the list, item, and paragraph
|
|
218
|
+
/// openings ahead of the text, so every offset inside it shifts and the
|
|
219
|
+
/// pre-command numbers no longer address the character the caret was on.
|
|
220
|
+
func performMutation(
|
|
221
|
+
preSelection: (UInt32, UInt32)? = nil,
|
|
222
|
+
postSelectionMirror: (UInt32, UInt32)? = nil,
|
|
223
|
+
includeSelectionInUpdate: Bool = false,
|
|
224
|
+
adoptEngineSelection: Bool = false,
|
|
225
|
+
publishMutation: Bool = true,
|
|
226
|
+
_ call: () -> FfiJsonResult
|
|
227
|
+
) -> String? {
|
|
228
|
+
guard !destroyed else {
|
|
229
|
+
emit(
|
|
230
|
+
FfiError(
|
|
231
|
+
domain: "lifecycle",
|
|
232
|
+
code: "ENGINE_DESTROYED",
|
|
233
|
+
message: "editor session is destroyed",
|
|
234
|
+
requestId: nil,
|
|
235
|
+
operationIndex: nil,
|
|
236
|
+
limit: nil,
|
|
237
|
+
actual: nil,
|
|
238
|
+
detailsJson: nil
|
|
239
|
+
)
|
|
240
|
+
)
|
|
241
|
+
return nil
|
|
242
|
+
}
|
|
243
|
+
let mirror = postSelectionMirror
|
|
244
|
+
let pre = preSelection
|
|
245
|
+
if let pre {
|
|
246
|
+
switch ensureSelection(anchor: pre.0, head: pre.1) {
|
|
247
|
+
case .ok:
|
|
248
|
+
break
|
|
249
|
+
case .refreshed(let updateJSON):
|
|
250
|
+
return updateJSON
|
|
251
|
+
case .failed:
|
|
252
|
+
return nil
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
switch Self.normalizeJsonResult(call()) {
|
|
256
|
+
case .failure(let error):
|
|
257
|
+
return handleMutationError(error)
|
|
258
|
+
case .success(let value):
|
|
259
|
+
guard let outcome = parseMutationOutcome(value) else {
|
|
260
|
+
emit(contractError("v2 mutation outcome violates the frozen shape"))
|
|
261
|
+
return nil
|
|
262
|
+
}
|
|
263
|
+
let postSelectionMirror = mirror
|
|
264
|
+
let preSelection = pre
|
|
265
|
+
let changed: Bool
|
|
266
|
+
switch outcome.kind {
|
|
267
|
+
case .transaction(let didChange, let revision):
|
|
268
|
+
changed = didChange
|
|
269
|
+
baseDocumentRevision = revision
|
|
270
|
+
if let postSelectionMirror, !adoptEngineSelection {
|
|
271
|
+
lastSyncedScalarSelection = postSelectionMirror
|
|
272
|
+
}
|
|
273
|
+
case .notApplicable:
|
|
274
|
+
// Nothing applicable: no commit happened; surface the current
|
|
275
|
+
// state (legacy no-op command parity) and skip the drain.
|
|
276
|
+
return refreshInternal(mirrorSelection: postSelectionMirror ?? preSelection)?.updateJSON
|
|
277
|
+
case .replacement(let didChange, let revision):
|
|
278
|
+
changed = didChange
|
|
279
|
+
baseDocumentRevision = revision
|
|
280
|
+
// Whole-root replacement resets the engine-side selection;
|
|
281
|
+
// the cached sync point is no longer valid.
|
|
282
|
+
lastSyncedScalarSelection = nil
|
|
283
|
+
}
|
|
284
|
+
guard let update = refreshInternal(
|
|
285
|
+
mirrorSelection: adoptEngineSelection
|
|
286
|
+
? nil
|
|
287
|
+
: postSelectionMirror ?? (includeSelectionInUpdate ? preSelection : nil),
|
|
288
|
+
// Paste and composition-preserving paths still derive active
|
|
289
|
+
// and history state from the authoritative post-operation
|
|
290
|
+
// selection. Only the view-facing selection is omitted so
|
|
291
|
+
// UIKit retains its IME-owned caret.
|
|
292
|
+
strippingViewSelection: !adoptEngineSelection
|
|
293
|
+
&& postSelectionMirror == nil
|
|
294
|
+
&& !includeSelectionInUpdate
|
|
295
|
+
)?.updateJSON else {
|
|
296
|
+
return nil
|
|
297
|
+
}
|
|
298
|
+
if adoptEngineSelection {
|
|
299
|
+
// The refresh adopted the engine's own post-command selection;
|
|
300
|
+
// that is now the view's caret, so it becomes the sync point.
|
|
301
|
+
// Leaving the pre-command offsets here would make the next
|
|
302
|
+
// ensureSelection push a stale caret back into the engine.
|
|
303
|
+
lastSyncedScalarSelection = cachedAuthoritativeScalarSelection
|
|
304
|
+
}
|
|
305
|
+
if changed && publishMutation {
|
|
306
|
+
publishCachedCollaborationSelection()
|
|
307
|
+
notifyCollaborationMutation()
|
|
308
|
+
}
|
|
309
|
+
return update
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/// Post-mutation caret for block-void insertions: when the document ends
|
|
314
|
+
/// with a void block followed by an empty placeholder paragraph, the
|
|
315
|
+
/// planner moved the caret into that trailing paragraph (scalar extent
|
|
316
|
+
/// - 1, the placeholder position). The update is re-derived with the
|
|
317
|
+
/// mirror so it carries the resolved selection the view applies.
|
|
318
|
+
func remirrorTrailingVoidCaretIfNeeded(_ updateJSON: String) -> String? {
|
|
319
|
+
guard let extent = cachedScalarLength,
|
|
320
|
+
extent > 0,
|
|
321
|
+
let data = updateJSON.data(using: .utf8),
|
|
322
|
+
let update = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
323
|
+
let blocks = update["renderBlocks"] as? [[[String: Any]]],
|
|
324
|
+
blocks.count >= 2,
|
|
325
|
+
Self.isEmptyPlaceholderParagraph(blocks[blocks.count - 1]),
|
|
326
|
+
blocks[blocks.count - 2].contains(where: { ($0["type"] as? String) == "voidBlock" })
|
|
327
|
+
else {
|
|
328
|
+
return updateJSON
|
|
329
|
+
}
|
|
330
|
+
let caret = extent - 1
|
|
331
|
+
lastSyncedScalarSelection = (caret, caret)
|
|
332
|
+
return refreshInternal(mirrorSelection: (caret, caret))?.updateJSON
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/// The trailing caret paragraph after a block-void insert renders as a
|
|
336
|
+
/// single zero-width-space text run (the synthetic empty-paragraph
|
|
337
|
+
/// placeholder).
|
|
338
|
+
private static func isEmptyPlaceholderParagraph(_ block: [[String: Any]]) -> Bool {
|
|
339
|
+
let types = block.compactMap { $0["type"] as? String }
|
|
340
|
+
guard types.contains("blockStart"), types.contains("blockEnd") else { return false }
|
|
341
|
+
let texts = block.filter { ($0["type"] as? String) == "textRun" }
|
|
342
|
+
return texts.count == 1 && (texts[0]["text"] as? String) == "\u{200B}"
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/// One history (undo/redo) mutation: no base-revision envelope, changed
|
|
346
|
+
/// flag drives the synthesize path.
|
|
347
|
+
func performHistoryMutation(_ call: (String) -> FfiJsonResult) -> String? {
|
|
348
|
+
guard !destroyed else {
|
|
349
|
+
emit(
|
|
350
|
+
FfiError(
|
|
351
|
+
domain: "lifecycle",
|
|
352
|
+
code: "ENGINE_DESTROYED",
|
|
353
|
+
message: "editor session is destroyed",
|
|
354
|
+
requestId: nil,
|
|
355
|
+
operationIndex: nil,
|
|
356
|
+
limit: nil,
|
|
357
|
+
actual: nil,
|
|
358
|
+
detailsJson: nil
|
|
359
|
+
)
|
|
360
|
+
)
|
|
361
|
+
return nil
|
|
362
|
+
}
|
|
363
|
+
let result = callWithEnvelope([:], includeBaseRevision: false, call)
|
|
364
|
+
switch Self.normalizeJsonResult(result) {
|
|
365
|
+
case .failure(let error):
|
|
366
|
+
emit(error)
|
|
367
|
+
return nil
|
|
368
|
+
case .success(let value):
|
|
369
|
+
guard let data = value.data(using: .utf8),
|
|
370
|
+
let object = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
371
|
+
let changed = object["changed"] as? Bool
|
|
372
|
+
else {
|
|
373
|
+
emit(contractError("v2 history outcome violates the frozen shape"))
|
|
374
|
+
return nil
|
|
375
|
+
}
|
|
376
|
+
guard let update = refreshInternal(mirrorSelection: nil)?.updateJSON else { return nil }
|
|
377
|
+
if changed {
|
|
378
|
+
publishCachedCollaborationSelection()
|
|
379
|
+
notifyCollaborationMutation()
|
|
380
|
+
}
|
|
381
|
+
return update
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/// A successful room mutation wakes the handle-owned native driver.
|
|
386
|
+
/// The adapter never owns a generation, socket, frame, or retry timer.
|
|
387
|
+
func notifyCollaborationMutation() {
|
|
388
|
+
guard roomBound, let nativeEditorId = UInt64(editorId) else { return }
|
|
389
|
+
collaborationWake(nativeEditorId, .localMutation)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
// MARK: - Session pairing registry
|
|
4
|
+
|
|
5
|
+
func v2DestroyAlreadyInProgressError() -> FfiError {
|
|
6
|
+
FfiError(
|
|
7
|
+
domain: "operation",
|
|
8
|
+
code: "OPERATION_INVALID",
|
|
9
|
+
message: "destroy already in progress",
|
|
10
|
+
requestId: nil,
|
|
11
|
+
operationIndex: nil,
|
|
12
|
+
limit: nil,
|
|
13
|
+
actual: nil,
|
|
14
|
+
detailsJson: nil
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
func invokeDestroyTestingHook(
|
|
19
|
+
_ hook: ((UInt64) throws -> Void)?,
|
|
20
|
+
editorId: UInt64
|
|
21
|
+
) {
|
|
22
|
+
do {
|
|
23
|
+
try hook?(editorId)
|
|
24
|
+
} catch {
|
|
25
|
+
// Destroy test hooks are observational and cannot alter the transaction.
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private func editorV2UnavailableOperationError() -> FfiError {
|
|
30
|
+
FfiError(
|
|
31
|
+
domain: "lifecycle",
|
|
32
|
+
code: "ENGINE_DESTROYED",
|
|
33
|
+
message: "editor session is not active",
|
|
34
|
+
requestId: nil,
|
|
35
|
+
operationIndex: nil,
|
|
36
|
+
limit: nil,
|
|
37
|
+
actual: nil,
|
|
38
|
+
detailsJson: nil
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func performEditorV2JsonOperation(
|
|
43
|
+
editorId: String,
|
|
44
|
+
_ operation: () -> FfiJsonResult
|
|
45
|
+
) -> FfiJsonResult {
|
|
46
|
+
guard let legacyId = UInt64(editorId),
|
|
47
|
+
let adapter = EditorV2Registry.adapter(forLegacyId: legacyId)
|
|
48
|
+
else {
|
|
49
|
+
return operation()
|
|
50
|
+
}
|
|
51
|
+
return adapter.performRuntimeOperation(
|
|
52
|
+
unavailable: FfiJsonResult(value: nil, error: editorV2UnavailableOperationError()),
|
|
53
|
+
operation
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
func performEditorV2UnitOperation(
|
|
58
|
+
editorId: String,
|
|
59
|
+
_ operation: () -> FfiUnitResult
|
|
60
|
+
) -> FfiUnitResult {
|
|
61
|
+
guard let legacyId = UInt64(editorId),
|
|
62
|
+
let adapter = EditorV2Registry.adapter(forLegacyId: legacyId)
|
|
63
|
+
else {
|
|
64
|
+
return operation()
|
|
65
|
+
}
|
|
66
|
+
return adapter.performRuntimeOperation(
|
|
67
|
+
unavailable: FfiUnitResult(value: nil, error: editorV2UnavailableOperationError()),
|
|
68
|
+
operation
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
func performEditorV2LifecycleUnitOperation(
|
|
73
|
+
editorId: String,
|
|
74
|
+
_ operation: () -> FfiUnitResult
|
|
75
|
+
) -> FfiUnitResult {
|
|
76
|
+
guard let legacyId = UInt64(editorId),
|
|
77
|
+
let adapter = EditorV2Registry.adapter(forLegacyId: legacyId)
|
|
78
|
+
else {
|
|
79
|
+
return operation()
|
|
80
|
+
}
|
|
81
|
+
return adapter.performRuntimeLifecycleOperation(
|
|
82
|
+
unavailable: FfiUnitResult(value: nil, error: editorV2UnavailableOperationError()),
|
|
83
|
+
operation
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
func performEditorV2SnapshotExportOperation(
|
|
88
|
+
editorId: String,
|
|
89
|
+
_ operation: () -> FfiSnapshotExportResult
|
|
90
|
+
) -> FfiSnapshotExportResult {
|
|
91
|
+
guard let legacyId = UInt64(editorId),
|
|
92
|
+
let adapter = EditorV2Registry.adapter(forLegacyId: legacyId)
|
|
93
|
+
else {
|
|
94
|
+
return operation()
|
|
95
|
+
}
|
|
96
|
+
return adapter.performRuntimeOperation(
|
|
97
|
+
unavailable: FfiSnapshotExportResult(value: nil, error: editorV2UnavailableOperationError()),
|
|
98
|
+
operation
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
func performEditorV2OutboundLeaseOperation(
|
|
103
|
+
editorId: String,
|
|
104
|
+
_ operation: () -> FfiOutboundLeaseResult
|
|
105
|
+
) -> FfiOutboundLeaseResult {
|
|
106
|
+
guard let legacyId = UInt64(editorId),
|
|
107
|
+
let adapter = EditorV2Registry.adapter(forLegacyId: legacyId)
|
|
108
|
+
else {
|
|
109
|
+
return operation()
|
|
110
|
+
}
|
|
111
|
+
return adapter.performRuntimeOperation(
|
|
112
|
+
unavailable: FfiOutboundLeaseResult(
|
|
113
|
+
value: nil,
|
|
114
|
+
empty: false,
|
|
115
|
+
error: editorV2UnavailableOperationError()
|
|
116
|
+
),
|
|
117
|
+
operation
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/// Maps the public (module-visible) editor id to the v2 adapter backing it.
|
|
122
|
+
/// The module's create path registers one pairing per editor; views bound
|
|
123
|
+
/// to a paired id route every interaction through the adapter.
|
|
124
|
+
enum EditorV2Registry {
|
|
125
|
+
static let lock = NSLock()
|
|
126
|
+
private static var pairings: [UInt64: EditorV2Adapter] = [:]
|
|
127
|
+
private static var destroyingLegacyIds: Set<UInt64> = []
|
|
128
|
+
static var onHandleDestroyReservationAcquiredForTesting: ((UInt64) throws -> Void)?
|
|
129
|
+
static var onDestroyFfiResultReceivedForTesting: ((UInt64) throws -> Void)?
|
|
130
|
+
static var onPairRemovedBeforeDestroyFinalizationForTesting: ((UInt64) throws -> Void)?
|
|
131
|
+
|
|
132
|
+
static func register(_ adapter: EditorV2Adapter, forLegacyId legacyId: UInt64) {
|
|
133
|
+
lock.lock()
|
|
134
|
+
pairings[legacyId] = adapter
|
|
135
|
+
lock.unlock()
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
static func adapter(forLegacyId legacyId: UInt64) -> EditorV2Adapter? {
|
|
139
|
+
lock.lock()
|
|
140
|
+
defer { lock.unlock() }
|
|
141
|
+
return pairings[legacyId]
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/// Acquire canonical public-handle ownership before consulting the
|
|
145
|
+
/// pairing. Pair removal is part of terminal teardown, so the pairing
|
|
146
|
+
/// cannot be the source of truth for transaction contention.
|
|
147
|
+
static func acquireHandleDestroyReservation(forLegacyId legacyId: UInt64) -> Bool {
|
|
148
|
+
lock.lock()
|
|
149
|
+
guard !destroyingLegacyIds.contains(legacyId) else {
|
|
150
|
+
lock.unlock()
|
|
151
|
+
return false
|
|
152
|
+
}
|
|
153
|
+
destroyingLegacyIds.insert(legacyId)
|
|
154
|
+
lock.unlock()
|
|
155
|
+
invokeDestroyTestingHook(onHandleDestroyReservationAcquiredForTesting, editorId: legacyId)
|
|
156
|
+
return true
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static func releaseHandleDestroyReservation(forLegacyId legacyId: UInt64) {
|
|
160
|
+
lock.lock()
|
|
161
|
+
destroyingLegacyIds.remove(legacyId)
|
|
162
|
+
lock.unlock()
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
static func isHandleDestroyReservedForTesting(_ legacyId: UInt64) -> Bool {
|
|
166
|
+
lock.lock()
|
|
167
|
+
defer { lock.unlock() }
|
|
168
|
+
return destroyingLegacyIds.contains(legacyId)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@discardableResult
|
|
172
|
+
static func removePairing(forLegacyId legacyId: UInt64) -> EditorV2Adapter? {
|
|
173
|
+
lock.lock()
|
|
174
|
+
defer { lock.unlock() }
|
|
175
|
+
return pairings.removeValue(forKey: legacyId)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/// Destroy the v2 session backing a pairing and drop the pairing only
|
|
179
|
+
/// once native destruction has succeeded or the session is already gone.
|
|
180
|
+
@discardableResult
|
|
181
|
+
static func destroyPair(forLegacyId legacyId: UInt64) -> FfiError? {
|
|
182
|
+
destroyEditorV2FromModule(editorId: String(legacyId)).error
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
}
|