@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,318 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import UIKit
|
|
3
|
+
|
|
4
|
+
extension EditorTextView {
|
|
5
|
+
@objc func handleIndentKeyCommand() {
|
|
6
|
+
handleListDepthKeyCommand(outdent: false)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@objc func handleHardBreakKeyCommand() {
|
|
10
|
+
guard !isApplyingRustState, editorId != 0, isEditable else { return }
|
|
11
|
+
guard finishExternalTextCompositionBeforeInteractionIfNeeded() else { return }
|
|
12
|
+
guard flushPendingNativeTextMutationCommitIfNeeded() else { return }
|
|
13
|
+
guard !isCollapsedAtomBoundary(selectedUtf16Range()) else { return }
|
|
14
|
+
performInterceptedInput {
|
|
15
|
+
insertNodeInRust(preferredHardBreakNodeType())
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@objc func handleOutdentKeyCommand() {
|
|
20
|
+
handleListDepthKeyCommand(outdent: true)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
func adjacentVoidBlockDeleteRangeForBackwardDelete(
|
|
24
|
+
cursorUtf16Offset: Int,
|
|
25
|
+
cursorScalar: UInt32
|
|
26
|
+
) -> (from: UInt32, to: UInt32)? {
|
|
27
|
+
guard cursorUtf16Offset >= 0, cursorUtf16Offset < textStorage.length else {
|
|
28
|
+
return nil
|
|
29
|
+
}
|
|
30
|
+
let attrs = textStorage.attributes(at: cursorUtf16Offset, effectiveRange: nil)
|
|
31
|
+
guard attrs[.attachment] is NSTextAttachment,
|
|
32
|
+
attrs[RenderBridgeAttributes.voidNodeType] is String,
|
|
33
|
+
cursorScalar < UInt32.max
|
|
34
|
+
else {
|
|
35
|
+
return nil
|
|
36
|
+
}
|
|
37
|
+
return (from: cursorScalar, to: cursorScalar + 1)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func trailingVoidBlockDeleteRangeForBackwardDelete(
|
|
41
|
+
cursorUtf16Offset: Int
|
|
42
|
+
) -> (from: UInt32, to: UInt32)? {
|
|
43
|
+
let text = textStorage.string as NSString
|
|
44
|
+
guard text.length > 0 else { return nil }
|
|
45
|
+
|
|
46
|
+
let clampedCursor = min(max(cursorUtf16Offset, 0), text.length)
|
|
47
|
+
let paragraphProbe = min(max(clampedCursor - 1, 0), text.length - 1)
|
|
48
|
+
let paragraphRange = text.paragraphRange(for: NSRange(location: paragraphProbe, length: 0))
|
|
49
|
+
|
|
50
|
+
let placeholderRange = NSRange(location: paragraphRange.location, length: 1)
|
|
51
|
+
guard placeholderRange.location + placeholderRange.length <= text.length else {
|
|
52
|
+
return nil
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let paragraphText = text.substring(with: placeholderRange)
|
|
56
|
+
guard paragraphText == "\u{200B}" else { return nil }
|
|
57
|
+
guard paragraphRange.location >= 2 else { return nil }
|
|
58
|
+
guard text.character(at: paragraphRange.location - 1) == 0x000A else { return nil }
|
|
59
|
+
|
|
60
|
+
let attachmentIndex = paragraphRange.location - 2
|
|
61
|
+
guard
|
|
62
|
+
let deleteRange = scalarDeleteRangeForVoidAttachment(at: attachmentIndex)
|
|
63
|
+
else {
|
|
64
|
+
return nil
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return deleteRange
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private func scalarDeleteRangeForVoidAttachment(
|
|
71
|
+
at utf16Offset: Int
|
|
72
|
+
) -> (from: UInt32, to: UInt32)? {
|
|
73
|
+
guard utf16Offset >= 0, utf16Offset < textStorage.length else {
|
|
74
|
+
return nil
|
|
75
|
+
}
|
|
76
|
+
let attrs = textStorage.attributes(at: utf16Offset, effectiveRange: nil)
|
|
77
|
+
guard let attachment = attrs[.attachment] as? NSTextAttachment,
|
|
78
|
+
!(attachment is AtomBlockAttachment),
|
|
79
|
+
attrs[RenderBridgeAttributes.voidNodeType] is String
|
|
80
|
+
else {
|
|
81
|
+
return nil
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let attachmentEndScalar = PositionBridge.utf16OffsetToScalar(
|
|
85
|
+
utf16Offset + 1,
|
|
86
|
+
in: self
|
|
87
|
+
)
|
|
88
|
+
guard attachmentEndScalar > 0 else { return nil }
|
|
89
|
+
return (from: attachmentEndScalar - 1, to: attachmentEndScalar)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private func handleListDepthKeyCommand(outdent: Bool) {
|
|
93
|
+
guard !isApplyingRustState else { return }
|
|
94
|
+
guard editorId != 0 else { return }
|
|
95
|
+
guard isEditable else { return }
|
|
96
|
+
guard finishExternalTextCompositionBeforeInteractionIfNeeded() else { return }
|
|
97
|
+
guard flushPendingNativeTextMutationCommitIfNeeded() else { return }
|
|
98
|
+
guard isCaretInsideList() else { return }
|
|
99
|
+
guard let selection = currentScalarSelection() else { return }
|
|
100
|
+
|
|
101
|
+
performInterceptedInput {
|
|
102
|
+
let updateJSON = outdent
|
|
103
|
+
? EditorV2Shadow.outdentListItemAtSelectionScalar(
|
|
104
|
+
id: editorId,
|
|
105
|
+
scalarAnchor: selection.anchor,
|
|
106
|
+
scalarHead: selection.head
|
|
107
|
+
)
|
|
108
|
+
: EditorV2Shadow.indentListItemAtSelectionScalar(
|
|
109
|
+
id: editorId,
|
|
110
|
+
scalarAnchor: selection.anchor,
|
|
111
|
+
scalarHead: selection.head
|
|
112
|
+
)
|
|
113
|
+
applyUpdateJSON(updateJSON)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private func isCaretInsideList() -> Bool {
|
|
118
|
+
guard editorId != 0 else { return false }
|
|
119
|
+
guard
|
|
120
|
+
let data = EditorV2Shadow.getCurrentState(id: editorId).data(using: .utf8),
|
|
121
|
+
let object = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
122
|
+
let activeState = object["activeState"] as? [String: Any],
|
|
123
|
+
let nodes = activeState["nodes"] as? [String: Any]
|
|
124
|
+
else {
|
|
125
|
+
return false
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return nodes.contains { nodeType, value in
|
|
129
|
+
EditorNodeTypes.isListContainer(nodeType) && value as? Bool == true
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private func preferredHardBreakNodeType() -> String {
|
|
134
|
+
guard
|
|
135
|
+
let data = EditorV2Shadow.getCurrentState(id: editorId).data(using: .utf8),
|
|
136
|
+
let object = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
137
|
+
let activeState = object["activeState"] as? [String: Any],
|
|
138
|
+
let insertableNodes = activeState["insertableNodes"] as? [String]
|
|
139
|
+
else {
|
|
140
|
+
return "hardBreak"
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return EditorNodeTypes.preferredHardBreak(in: Set(insertableNodes))
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
func ensureInternalTextViewDelegate() {
|
|
147
|
+
// Some keyboard integrations replace UITextView's private delegate ivar
|
|
148
|
+
// directly. The editor must own delegate callbacks so external observers
|
|
149
|
+
// cannot inspect transient TextKit state during Rust-driven edits.
|
|
150
|
+
// The delegate is a dedicated object rather than the text view itself;
|
|
151
|
+
// see EditorTextViewInternalDelegate for why (APOLLO-REACT-56).
|
|
152
|
+
guard (delegate as AnyObject?) !== internalTextViewDelegate else { return }
|
|
153
|
+
delegate = internalTextViewDelegate
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
func performInterceptedInput(
|
|
157
|
+
flushPendingNativeTextMutation: Bool = true,
|
|
158
|
+
_ action: () -> Void
|
|
159
|
+
) {
|
|
160
|
+
if flushPendingNativeTextMutation, interceptedInputDepth == 0 {
|
|
161
|
+
guard flushPendingNativeTextMutationCommitIfNeeded() else { return }
|
|
162
|
+
}
|
|
163
|
+
interceptedInputDepth += 1
|
|
164
|
+
Self.inputLog.debug(
|
|
165
|
+
"[intercept.begin] depth=\(self.interceptedInputDepth) selection=\(self.selectionSummary(), privacy: .public) textState=\(self.textSnapshotSummary(), privacy: .public)"
|
|
166
|
+
)
|
|
167
|
+
action()
|
|
168
|
+
DispatchQueue.main.async { [weak self] in
|
|
169
|
+
guard let self else { return }
|
|
170
|
+
self.interceptedInputDepth = max(0, self.interceptedInputDepth - 1)
|
|
171
|
+
Self.inputLog.debug(
|
|
172
|
+
"[intercept.end] depth=\(self.interceptedInputDepth) selection=\(self.selectionSummary(), privacy: .public) textState=\(self.textSnapshotSummary(), privacy: .public)"
|
|
173
|
+
)
|
|
174
|
+
if self.interceptedInputDepth == 0 {
|
|
175
|
+
_ = self.drainPendingNativeTextMutation(
|
|
176
|
+
allowAfterBlur: false,
|
|
177
|
+
allowWhileIntercepting: false
|
|
178
|
+
)
|
|
179
|
+
self.drainDeferredInsertTextIfReady()
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
func enqueueDeferredInsertText(_ text: String) {
|
|
185
|
+
deferredInsertTexts.append(text)
|
|
186
|
+
scheduleDeferredInsertDrain()
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private func scheduleDeferredInsertDrain() {
|
|
190
|
+
guard !deferredInsertDrainScheduled else { return }
|
|
191
|
+
deferredInsertDrainScheduled = true
|
|
192
|
+
DispatchQueue.main.async { [weak self] in
|
|
193
|
+
self?.drainDeferredInsertTextIfReady()
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private func drainDeferredInsertTextIfReady() {
|
|
198
|
+
deferredInsertDrainScheduled = false
|
|
199
|
+
guard !deferredInsertTexts.isEmpty else { return }
|
|
200
|
+
guard editorId != 0 else {
|
|
201
|
+
deferredInsertTexts.removeAll()
|
|
202
|
+
return
|
|
203
|
+
}
|
|
204
|
+
guard !isApplyingRustState,
|
|
205
|
+
interceptedInputDepth == 0,
|
|
206
|
+
pendingNativeTextMutation == nil,
|
|
207
|
+
!nativeTextMutationCommitScheduled
|
|
208
|
+
else {
|
|
209
|
+
scheduleDeferredInsertDrain()
|
|
210
|
+
return
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
let text = deferredInsertTexts.removeFirst()
|
|
214
|
+
isReplayingDeferredInsertText = true
|
|
215
|
+
defer { isReplayingDeferredInsertText = false }
|
|
216
|
+
insertText(text)
|
|
217
|
+
if !deferredInsertTexts.isEmpty {
|
|
218
|
+
scheduleDeferredInsertDrain()
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/// Handle return key press as a block split operation.
|
|
223
|
+
private func handleReturnKey() {
|
|
224
|
+
if let selectedRange = selectedTextRange, !selectedRange.isEmpty {
|
|
225
|
+
let range = PositionBridge.textRangeToScalarRange(selectedRange, in: self)
|
|
226
|
+
let updateJSON = EditorV2Shadow.deleteAndSplitScalar(
|
|
227
|
+
id: editorId,
|
|
228
|
+
scalarFrom: range.from,
|
|
229
|
+
scalarTo: range.to
|
|
230
|
+
)
|
|
231
|
+
applyUpdateJSON(updateJSON)
|
|
232
|
+
} else {
|
|
233
|
+
let scalarPos = PositionBridge.cursorScalarOffset(in: self)
|
|
234
|
+
splitBlockInRust(at: scalarPos)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
func interceptReturnInput(
|
|
239
|
+
_ text: String,
|
|
240
|
+
replacing replacementRange: UITextRange? = nil
|
|
241
|
+
) -> Bool {
|
|
242
|
+
guard text == "\n" || text == "\r" else { return false }
|
|
243
|
+
let scalarRange = replacementRange.map {
|
|
244
|
+
PositionBridge.textRangeToScalarRange($0, in: self)
|
|
245
|
+
}
|
|
246
|
+
guard commitActiveMarkedTextBeforeReturn() else { return true }
|
|
247
|
+
performInterceptedInput {
|
|
248
|
+
if let scalarRange {
|
|
249
|
+
if scalarRange.from == scalarRange.to {
|
|
250
|
+
splitBlockInRust(at: scalarRange.from)
|
|
251
|
+
} else {
|
|
252
|
+
let updateJSON = EditorV2Shadow.deleteAndSplitScalar(
|
|
253
|
+
id: editorId,
|
|
254
|
+
scalarFrom: scalarRange.from,
|
|
255
|
+
scalarTo: scalarRange.to
|
|
256
|
+
)
|
|
257
|
+
applyUpdateJSON(updateJSON)
|
|
258
|
+
}
|
|
259
|
+
} else {
|
|
260
|
+
handleReturnKey()
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return true
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/// Split a block at a scalar position via the Rust editor.
|
|
267
|
+
private func splitBlockInRust(at scalarPos: UInt32) {
|
|
268
|
+
Self.inputLog.debug(
|
|
269
|
+
"[rust.splitBlockScalar] scalarPos=\(scalarPos) selection=\(self.selectionSummary(), privacy: .public)"
|
|
270
|
+
)
|
|
271
|
+
let updateJSON = EditorV2Shadow.splitBlockScalar(id: editorId, scalarPos: scalarPos)
|
|
272
|
+
applyUpdateJSON(updateJSON)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/// Paste HTML content through Rust.
|
|
276
|
+
@discardableResult
|
|
277
|
+
func pasteHTML(_ html: String, detectContentChange: Bool = false) -> Bool {
|
|
278
|
+
let previousHTML = detectContentChange ? EditorV2Shadow.getHtml(id: editorId) : nil
|
|
279
|
+
syncCurrentUIKitSelectionToRust()
|
|
280
|
+
Self.inputLog.debug(
|
|
281
|
+
"[rust.pasteHTML] html=\(self.preview(html), privacy: .public) selection=\(self.selectionSummary(), privacy: .public)"
|
|
282
|
+
)
|
|
283
|
+
let updateJSON = EditorV2Shadow.insertContentHtml(id: editorId, html: html)
|
|
284
|
+
applyUpdateJSON(updateJSON)
|
|
285
|
+
guard let previousHTML else { return true }
|
|
286
|
+
return EditorV2Shadow.getHtml(id: editorId) != previousHTML
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
private func syncCurrentUIKitSelectionToRust() {
|
|
290
|
+
guard editorId != 0, let range = selectedTextRange else { return }
|
|
291
|
+
let anchor = PositionBridge.textViewToScalar(range.start, in: self)
|
|
292
|
+
let head = PositionBridge.textViewToScalar(range.end, in: self)
|
|
293
|
+
EditorV2Shadow.setSelectionScalar(id: editorId, scalarAnchor: anchor, scalarHead: head)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/// Paste plain text through Rust.
|
|
297
|
+
func pastePlainText(_ text: String) {
|
|
298
|
+
if let selectedRange = selectedTextRange, !selectedRange.isEmpty {
|
|
299
|
+
let range = PositionBridge.textRangeToScalarRange(selectedRange, in: self)
|
|
300
|
+
Self.inputLog.debug(
|
|
301
|
+
"[rust.pastePlainText.replace] text=\(self.preview(text), privacy: .public) scalar=\(range.from)-\(range.to) selection=\(self.selectionSummary(), privacy: .public)"
|
|
302
|
+
)
|
|
303
|
+
let updateJSON = EditorV2Shadow.replaceTextScalar(
|
|
304
|
+
id: editorId,
|
|
305
|
+
scalarFrom: range.from,
|
|
306
|
+
scalarTo: range.to,
|
|
307
|
+
text: text
|
|
308
|
+
)
|
|
309
|
+
applyUpdateJSON(updateJSON)
|
|
310
|
+
} else {
|
|
311
|
+
Self.inputLog.debug(
|
|
312
|
+
"[rust.pastePlainText.insert] text=\(self.preview(text), privacy: .public) selection=\(self.selectionSummary(), privacy: .public)"
|
|
313
|
+
)
|
|
314
|
+
insertTextInRust(text, at: PositionBridge.cursorScalarOffset(in: self))
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import UIKit
|
|
3
|
+
|
|
4
|
+
extension EditorTextView {
|
|
5
|
+
@objc func handleKeyboardFrameChange(_ notification: Notification) {
|
|
6
|
+
guard isFirstResponder || keyboardFrameInScreen != nil else { return }
|
|
7
|
+
if notification.name == UIResponder.keyboardWillHideNotification {
|
|
8
|
+
keyboardFrameInScreen = nil
|
|
9
|
+
} else {
|
|
10
|
+
keyboardFrameInScreen = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
|
|
11
|
+
}
|
|
12
|
+
let duration = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
|
|
13
|
+
let curve = (notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.uintValue ?? 0
|
|
14
|
+
UIView.animate(
|
|
15
|
+
withDuration: duration,
|
|
16
|
+
delay: 0,
|
|
17
|
+
options: [UIView.AnimationOptions(rawValue: curve << 16), .beginFromCurrentState]
|
|
18
|
+
) {
|
|
19
|
+
self.updateKeyboardInset()
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
func updateKeyboardInset() {
|
|
24
|
+
var overlap: CGFloat = 0
|
|
25
|
+
if isScrollEnabled, let window, let keyboardFrameInScreen {
|
|
26
|
+
let frameInWindow = window.convert(keyboardFrameInScreen, from: window.screen.coordinateSpace)
|
|
27
|
+
let keyboardFrame = convert(frameInWindow, from: window)
|
|
28
|
+
let intersection = bounds.intersection(keyboardFrame)
|
|
29
|
+
if !intersection.isNull, intersection.maxY >= bounds.maxY - 1 {
|
|
30
|
+
overlap = intersection.height
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
let baseBottomInset = contentInset.bottom - keyboardBottomInset
|
|
34
|
+
let automaticBottomInset = adjustedContentInset.bottom - contentInset.bottom
|
|
35
|
+
let nextInset = max(0, overlap - automaticBottomInset - baseBottomInset)
|
|
36
|
+
guard abs(nextInset - keyboardBottomInset) > 0.5 else { return }
|
|
37
|
+
let delta = nextInset - keyboardBottomInset
|
|
38
|
+
keyboardBottomInset = nextInset
|
|
39
|
+
contentInset.bottom += delta
|
|
40
|
+
verticalScrollIndicatorInsets.bottom += delta
|
|
41
|
+
if overlap > 0, isFirstResponder, let selection = selectedTextRange {
|
|
42
|
+
let caret = caretRect(for: selection.end)
|
|
43
|
+
if !caret.isEmpty {
|
|
44
|
+
scrollRectToVisible(caret.insetBy(dx: 0, dy: -8), animated: false)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// Whether the document holds nothing the user authored.
|
|
50
|
+
///
|
|
51
|
+
/// Taken verbatim from the core. Deriving it cannot work: an empty list
|
|
52
|
+
/// item contributes no characters, so scanning the storage reports empty
|
|
53
|
+
/// and leaves the placeholder over a visible bullet. The scan below is
|
|
54
|
+
/// only the fallback for renders with no editor update (the viewer).
|
|
55
|
+
private func isRenderedContentEmpty() -> Bool {
|
|
56
|
+
if let coreReportedDocumentIsEmpty {
|
|
57
|
+
return coreReportedDocumentIsEmpty
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let renderedText = textStorage.string
|
|
61
|
+
guard !renderedText.isEmpty else { return true }
|
|
62
|
+
|
|
63
|
+
for scalar in renderedText.unicodeScalars {
|
|
64
|
+
switch scalar {
|
|
65
|
+
case Self.emptyBlockPlaceholderScalar, "\n", "\r":
|
|
66
|
+
continue
|
|
67
|
+
default:
|
|
68
|
+
return false
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return true
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@discardableResult
|
|
76
|
+
func normalizeSelectionForEmptyBlockAutocapitalizationIfNeeded() -> Bool {
|
|
77
|
+
guard textStorage.length == 1 else { return false }
|
|
78
|
+
guard textStorage.string.unicodeScalars.elementsEqual([Self.emptyBlockPlaceholderScalar]) else {
|
|
79
|
+
return false
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let currentRange = selectedRange
|
|
83
|
+
guard currentRange.location != NSNotFound, currentRange.length == 0 else { return false }
|
|
84
|
+
guard currentRange.location == textStorage.length else { return false }
|
|
85
|
+
|
|
86
|
+
let adjustedRange = NSRange(location: 0, length: 0)
|
|
87
|
+
guard currentRange != adjustedRange else { return false }
|
|
88
|
+
selectedRange = adjustedRange
|
|
89
|
+
noteSelectionDidChange()
|
|
90
|
+
return true
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
func refreshPlaceholderVisibility() {
|
|
94
|
+
let hasProvisionalText = externalTextComposition?.latestText.isEmpty == false
|
|
95
|
+
placeholderLabel.isHidden = placeholder.isEmpty
|
|
96
|
+
|| hasProvisionalText
|
|
97
|
+
|| !isRenderedContentEmpty()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
func preserveScrollOffset(_ previousOffset: CGPoint) {
|
|
101
|
+
let restore = { [weak self] in
|
|
102
|
+
guard let self else { return }
|
|
103
|
+
self.layoutIfNeeded()
|
|
104
|
+
|
|
105
|
+
let maxOffsetX = max(
|
|
106
|
+
-self.adjustedContentInset.left,
|
|
107
|
+
self.contentSize.width - self.bounds.width + self.adjustedContentInset.right
|
|
108
|
+
)
|
|
109
|
+
let maxOffsetY = max(
|
|
110
|
+
-self.adjustedContentInset.top,
|
|
111
|
+
self.contentSize.height - self.bounds.height + self.adjustedContentInset.bottom
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
let clampedOffset = CGPoint(
|
|
115
|
+
x: min(max(previousOffset.x, -self.adjustedContentInset.left), maxOffsetX),
|
|
116
|
+
y: min(max(previousOffset.y, -self.adjustedContentInset.top), maxOffsetY)
|
|
117
|
+
)
|
|
118
|
+
self.setContentOffset(clampedOffset, animated: false)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
restore()
|
|
122
|
+
DispatchQueue.main.async(execute: restore)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
func defaultTypingAttributes() -> [NSAttributedString.Key: Any] {
|
|
126
|
+
[
|
|
127
|
+
.font: resolvedDefaultFont(),
|
|
128
|
+
.foregroundColor: resolvedDefaultTextColor()
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
func resolvedDefaultFont() -> UIFont {
|
|
133
|
+
theme?.effectiveTextStyle(for: "paragraph").resolvedFont(fallback: baseFont)
|
|
134
|
+
?? baseFont
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
func resolvedDefaultTextColor() -> UIColor {
|
|
138
|
+
theme?.effectiveTextStyle(for: "paragraph").color ?? baseTextColor
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
func notifyHeightChangeIfNeeded(force: Bool = false) {
|
|
142
|
+
guard heightBehavior == .autoGrow else { return }
|
|
143
|
+
let width = bounds.width > 0 ? bounds.width : UIScreen.main.bounds.width
|
|
144
|
+
guard width > 0 else { return }
|
|
145
|
+
if !force {
|
|
146
|
+
let measuredWidth = ceil(width)
|
|
147
|
+
if !autoGrowHeightCheckIsDirty && abs(measuredWidth - lastAutoGrowMeasuredWidth) <= 0.5 {
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
lastHeightNotifyEnsureLayoutNanosForTesting = 0
|
|
152
|
+
lastHeightNotifyUsedRectNanosForTesting = 0
|
|
153
|
+
lastHeightNotifyContentSizeNanosForTesting = 0
|
|
154
|
+
lastHeightNotifySizeThatFitsNanosForTesting = 0
|
|
155
|
+
let measurementStartedAt = DispatchTime.now().uptimeNanoseconds
|
|
156
|
+
let measuredHeight = measuredAutoGrowHeight(forWidth: width)
|
|
157
|
+
lastHeightNotifyMeasureNanosForTesting =
|
|
158
|
+
DispatchTime.now().uptimeNanoseconds - measurementStartedAt
|
|
159
|
+
autoGrowHeightCheckIsDirty = false
|
|
160
|
+
lastAutoGrowMeasuredWidth = ceil(width)
|
|
161
|
+
guard force || abs(measuredHeight - lastAutoGrowMeasuredHeight) > 0.5 else { return }
|
|
162
|
+
lastAutoGrowMeasuredHeight = measuredHeight
|
|
163
|
+
let callbackStartedAt = DispatchTime.now().uptimeNanoseconds
|
|
164
|
+
onHeightMayChange?(measuredHeight)
|
|
165
|
+
lastHeightNotifyCallbackNanosForTesting =
|
|
166
|
+
DispatchTime.now().uptimeNanoseconds - callbackStartedAt
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
func measuredAutoGrowHeight(forWidth width: CGFloat) -> CGFloat {
|
|
170
|
+
guard width > 0 else { return 0 }
|
|
171
|
+
|
|
172
|
+
if abs(bounds.width - width) <= 0.5 {
|
|
173
|
+
let currentHeight = ceil(bounds.height)
|
|
174
|
+
let ensureLayoutStartedAt = DispatchTime.now().uptimeNanoseconds
|
|
175
|
+
editorLayoutManager.ensureLayout(for: textContainer)
|
|
176
|
+
lastHeightNotifyEnsureLayoutNanosForTesting =
|
|
177
|
+
DispatchTime.now().uptimeNanoseconds - ensureLayoutStartedAt
|
|
178
|
+
|
|
179
|
+
let usedRectStartedAt = DispatchTime.now().uptimeNanoseconds
|
|
180
|
+
var usedRect = editorLayoutManager.usedRect(for: textContainer)
|
|
181
|
+
let extraLineFragmentRect = editorLayoutManager.extraLineFragmentRect
|
|
182
|
+
if !extraLineFragmentRect.isEmpty {
|
|
183
|
+
usedRect = usedRect.union(extraLineFragmentRect)
|
|
184
|
+
}
|
|
185
|
+
lastHeightNotifyUsedRectNanosForTesting =
|
|
186
|
+
DispatchTime.now().uptimeNanoseconds - usedRectStartedAt
|
|
187
|
+
let layoutHeight = ceil(
|
|
188
|
+
usedRect.height
|
|
189
|
+
+ textContainerInset.top
|
|
190
|
+
+ textContainerInset.bottom
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
let contentSizeStartedAt = DispatchTime.now().uptimeNanoseconds
|
|
194
|
+
let contentHeight = ceil(contentSize.height)
|
|
195
|
+
lastHeightNotifyContentSizeNanosForTesting =
|
|
196
|
+
DispatchTime.now().uptimeNanoseconds - contentSizeStartedAt
|
|
197
|
+
if currentHeight > 0 {
|
|
198
|
+
if layoutHeight > currentHeight + 0.5 {
|
|
199
|
+
return layoutHeight
|
|
200
|
+
}
|
|
201
|
+
let hostIsTrackingMeasuredHeight =
|
|
202
|
+
autoGrowHostHeight > 0
|
|
203
|
+
&& abs(currentHeight - ceil(autoGrowHostHeight)) <= 1.0
|
|
204
|
+
guard hostIsTrackingMeasuredHeight else {
|
|
205
|
+
return layoutHeight
|
|
206
|
+
}
|
|
207
|
+
let measuredFromLayout = max(layoutHeight, contentHeight)
|
|
208
|
+
if measuredFromLayout > currentHeight + 0.5 {
|
|
209
|
+
return measuredFromLayout
|
|
210
|
+
}
|
|
211
|
+
let sizeThatFitsStartedAt = DispatchTime.now().uptimeNanoseconds
|
|
212
|
+
let fittedHeight = ceil(
|
|
213
|
+
sizeThatFits(
|
|
214
|
+
CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
|
|
215
|
+
).height
|
|
216
|
+
)
|
|
217
|
+
lastHeightNotifySizeThatFitsNanosForTesting =
|
|
218
|
+
DispatchTime.now().uptimeNanoseconds - sizeThatFitsStartedAt
|
|
219
|
+
if fittedHeight > currentHeight + 0.5 {
|
|
220
|
+
return max(measuredFromLayout, fittedHeight)
|
|
221
|
+
}
|
|
222
|
+
return layoutHeight
|
|
223
|
+
}
|
|
224
|
+
return max(layoutHeight, contentHeight)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
let sizeThatFitsStartedAt = DispatchTime.now().uptimeNanoseconds
|
|
228
|
+
let fittedHeight = ceil(
|
|
229
|
+
sizeThatFits(CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)).height
|
|
230
|
+
)
|
|
231
|
+
lastHeightNotifySizeThatFitsNanosForTesting =
|
|
232
|
+
DispatchTime.now().uptimeNanoseconds - sizeThatFitsStartedAt
|
|
233
|
+
return fittedHeight
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
func updateAutoGrowHostHeight(_ height: CGFloat) {
|
|
237
|
+
autoGrowHostHeight = max(0, ceil(height))
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
func invalidateAutoGrowHeightMeasurement() {
|
|
241
|
+
autoGrowHeightCheckIsDirty = true
|
|
242
|
+
lastAutoGrowMeasuredWidth = 0
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
}
|