@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,117 @@
|
|
|
1
|
+
package com.apollohg.editor
|
|
2
|
+
|
|
3
|
+
import kotlin.math.roundToInt
|
|
4
|
+
import org.json.JSONArray
|
|
5
|
+
import org.json.JSONObject
|
|
6
|
+
|
|
7
|
+
object LayoutConstants {
|
|
8
|
+
/** Base indentation per depth level (pixels at base scale). */
|
|
9
|
+
const val INDENT_PER_DEPTH: Float = 24f
|
|
10
|
+
|
|
11
|
+
/** Width reserved for the list bullet/number (pixels at base scale). */
|
|
12
|
+
const val LIST_MARKER_WIDTH: Float = 36f
|
|
13
|
+
|
|
14
|
+
/** Gap between the list marker and the text that follows (pixels at base scale). */
|
|
15
|
+
const val LIST_MARKER_TEXT_GAP: Float = 8f
|
|
16
|
+
|
|
17
|
+
/** Height of the horizontal rule separator line (pixels). */
|
|
18
|
+
const val HORIZONTAL_RULE_HEIGHT: Float = 1f
|
|
19
|
+
|
|
20
|
+
/** Vertical padding above and below the horizontal rule (pixels). */
|
|
21
|
+
const val HORIZONTAL_RULE_VERTICAL_PADDING: Float = 8f
|
|
22
|
+
|
|
23
|
+
/** Total leading inset reserved for each blockquote depth. */
|
|
24
|
+
const val BLOCKQUOTE_INDENT: Float = 18f
|
|
25
|
+
|
|
26
|
+
/** Width of the rendered blockquote border bar (pixels at base scale). */
|
|
27
|
+
const val BLOCKQUOTE_BORDER_WIDTH: Float = 3f
|
|
28
|
+
|
|
29
|
+
/** Gap between the blockquote border bar and the text that follows. */
|
|
30
|
+
const val BLOCKQUOTE_MARKER_GAP: Float = 8f
|
|
31
|
+
|
|
32
|
+
/** Bullet character for unordered list items. */
|
|
33
|
+
const val UNORDERED_LIST_BULLET: String = "\u2022 "
|
|
34
|
+
|
|
35
|
+
/** Scale factor applied only to unordered list marker glyphs. */
|
|
36
|
+
const val UNORDERED_LIST_MARKER_FONT_SCALE: Float = 2.0f
|
|
37
|
+
|
|
38
|
+
/** Rendered marker text for task list items. Must stay in sync with the
|
|
39
|
+
* Rust core's task_list_marker_string (render/mod.rs) — the marker's
|
|
40
|
+
* scalar length is part of the position-mapping contract. */
|
|
41
|
+
const val TASK_LIST_MARKER_CHECKED: String = "☑ "
|
|
42
|
+
const val TASK_LIST_MARKER_UNCHECKED: String = "☐ "
|
|
43
|
+
|
|
44
|
+
/** Scale factor applied to task checkbox marker glyphs. */
|
|
45
|
+
const val TASK_LIST_MARKER_FONT_SCALE: Float = 1.55f
|
|
46
|
+
|
|
47
|
+
/** Default visual treatment for link text when no explicit theme color exists. */
|
|
48
|
+
const val DEFAULT_LINK_COLOR: Int = 0xFF1B73E8.toInt()
|
|
49
|
+
|
|
50
|
+
/** Object replacement character used for void block elements. */
|
|
51
|
+
const val OBJECT_REPLACEMENT_CHARACTER: String = "\uFFFC"
|
|
52
|
+
|
|
53
|
+
/** Zero-width placeholder used to preserve trailing hard-break lines. */
|
|
54
|
+
const val SYNTHETIC_PLACEHOLDER_CHARACTER: String = "\u200B"
|
|
55
|
+
|
|
56
|
+
/** Background color for inline code spans (light gray). */
|
|
57
|
+
const val CODE_BACKGROUND_COLOR: Int = 0x1A000000 // 10% black
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
data class BlockContext(
|
|
61
|
+
val nodeType: String,
|
|
62
|
+
val depth: Int,
|
|
63
|
+
val listContext: JSONObject?,
|
|
64
|
+
val topLevelChildIndex: Int? = null,
|
|
65
|
+
var markerPending: Boolean = false,
|
|
66
|
+
var renderStart: Int = 0,
|
|
67
|
+
val language: String? = null
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
data class AtomRenderConfiguration(
|
|
71
|
+
val registeredNodeTypes: Set<String>,
|
|
72
|
+
val estimatedHeightsDp: Map<String, Float>,
|
|
73
|
+
val measuredHeightsPx: Map<String, Int>
|
|
74
|
+
) {
|
|
75
|
+
fun reservedHeightPx(atomKey: String, nodeType: String, density: Float): Int =
|
|
76
|
+
measuredHeightsPx[atomKey]
|
|
77
|
+
?: ((estimatedHeightsDp[nodeType] ?: 0f) * density).roundToInt()
|
|
78
|
+
|
|
79
|
+
companion object {
|
|
80
|
+
fun fromJson(json: String?): AtomRenderConfiguration? {
|
|
81
|
+
if (json == null) return null
|
|
82
|
+
val raw = try {
|
|
83
|
+
JSONObject(json)
|
|
84
|
+
} catch (_: Exception) {
|
|
85
|
+
return null
|
|
86
|
+
}
|
|
87
|
+
val nodeTypes = buildSet {
|
|
88
|
+
val values = raw.optJSONArray("nodeTypes") ?: JSONArray()
|
|
89
|
+
for (index in 0 until values.length()) {
|
|
90
|
+
(values.opt(index) as? String)?.let(::add)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
val estimatedHeights = buildMap {
|
|
94
|
+
val values = raw.optJSONObject("estimatedHeights") ?: JSONObject()
|
|
95
|
+
for (nodeType in values.keys()) {
|
|
96
|
+
val height = (values.opt(nodeType) as? Number)?.toFloat() ?: continue
|
|
97
|
+
if (height.isFinite() && height >= 0f) {
|
|
98
|
+
put(nodeType, height)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return AtomRenderConfiguration(nodeTypes, estimatedHeights, emptyMap())
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
internal data class PendingLeadingMargin(
|
|
108
|
+
val indentPx: Int,
|
|
109
|
+
val restIndentPx: Int?,
|
|
110
|
+
val blockquoteIndentPx: Int = 0,
|
|
111
|
+
val blockquoteStripeColor: Int? = null,
|
|
112
|
+
val blockquoteStripeWidthPx: Int = 0,
|
|
113
|
+
val blockquoteGapWidthPx: Int = 0,
|
|
114
|
+
val blockquoteBaseIndentPx: Int = 0
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
internal data class PendingCodeBlockSpan(val start: Int, val end: Int)
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
package com.apollohg.editor
|
|
2
|
+
|
|
3
|
+
import android.graphics.Canvas
|
|
4
|
+
import android.graphics.Color
|
|
5
|
+
import android.graphics.Paint
|
|
6
|
+
import android.graphics.RectF
|
|
7
|
+
import android.text.style.ReplacementSpan
|
|
8
|
+
import android.util.Log
|
|
9
|
+
import android.view.View
|
|
10
|
+
import java.lang.ref.WeakReference
|
|
11
|
+
import java.util.concurrent.atomic.AtomicBoolean
|
|
12
|
+
import java.util.concurrent.atomic.AtomicReference
|
|
13
|
+
|
|
14
|
+
internal class AtomBlockSpan(
|
|
15
|
+
val atomKey: String,
|
|
16
|
+
val nodeType: String,
|
|
17
|
+
val docPos: Int,
|
|
18
|
+
var reservedHeightPx: Int,
|
|
19
|
+
val hasStableAtomId: Boolean,
|
|
20
|
+
val isDirectRootChild: Boolean
|
|
21
|
+
) : ReplacementSpan() {
|
|
22
|
+
override fun getSize(
|
|
23
|
+
paint: Paint,
|
|
24
|
+
text: CharSequence,
|
|
25
|
+
start: Int,
|
|
26
|
+
end: Int,
|
|
27
|
+
fm: Paint.FontMetricsInt?
|
|
28
|
+
): Int {
|
|
29
|
+
fm?.apply {
|
|
30
|
+
ascent = -reservedHeightPx
|
|
31
|
+
top = ascent
|
|
32
|
+
descent = 0
|
|
33
|
+
bottom = 0
|
|
34
|
+
}
|
|
35
|
+
return 0
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
override fun draw(
|
|
39
|
+
canvas: Canvas,
|
|
40
|
+
text: CharSequence,
|
|
41
|
+
start: Int,
|
|
42
|
+
end: Int,
|
|
43
|
+
x: Float,
|
|
44
|
+
top: Int,
|
|
45
|
+
y: Int,
|
|
46
|
+
bottom: Int,
|
|
47
|
+
paint: Paint
|
|
48
|
+
) = Unit
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
internal class BlockImageSpan(
|
|
52
|
+
private val source: String,
|
|
53
|
+
hostView: View?,
|
|
54
|
+
private val density: Float,
|
|
55
|
+
private val preferredWidthDp: Float?,
|
|
56
|
+
private val preferredHeightDp: Float?,
|
|
57
|
+
internal var imageStyle: EditorElementStyle? = null
|
|
58
|
+
) : ReplacementSpan() {
|
|
59
|
+
internal var ancestorWidthInset: Float = 0f
|
|
60
|
+
private val hostRef = WeakReference(hostView)
|
|
61
|
+
private val policy = (hostView as? EditorEditText)?.imageLoadingPolicy
|
|
62
|
+
?: ImageLoadingPolicy.DEFAULT
|
|
63
|
+
private val generation = (hostView as? EditorEditText)?.currentImageLoadGeneration()
|
|
64
|
+
private val boundEditorId = (hostView as? EditorEditText)?.editorId
|
|
65
|
+
private val boundDriver = WeakReference((hostView as? EditorEditText)?.v2Driver)
|
|
66
|
+
private val hadBoundDriver = boundDriver.get() != null
|
|
67
|
+
private val ownerId = (hostView as? EditorEditText)?.decodedBitmapOwnerId
|
|
68
|
+
?: DecodedBitmapBudget.nextOwnerId()
|
|
69
|
+
private val preparedSource = NativeImagePipeline.prepare(source, policy)
|
|
70
|
+
|
|
71
|
+
private val retired = AtomicBoolean(false)
|
|
72
|
+
private val bitmapLease = AtomicReference<DecodedBitmapLease?>()
|
|
73
|
+
private val loadHandle = AtomicReference<RenderImageLoader.LoadHandle?>()
|
|
74
|
+
|
|
75
|
+
@Volatile
|
|
76
|
+
private var lastDrawRect: RectF? = null
|
|
77
|
+
|
|
78
|
+
init {
|
|
79
|
+
if (preparedSource != null) {
|
|
80
|
+
val handle = NativeImagePipeline.load(
|
|
81
|
+
preparedSource,
|
|
82
|
+
ownerId,
|
|
83
|
+
DecodedBitmapPriority.VISIBLE
|
|
84
|
+
) { loaded ->
|
|
85
|
+
val currentHost = hostRef.get()
|
|
86
|
+
if (
|
|
87
|
+
retired.get() ||
|
|
88
|
+
(
|
|
89
|
+
currentHost is EditorEditText &&
|
|
90
|
+
!canReuseFor(currentHost)
|
|
91
|
+
)
|
|
92
|
+
) {
|
|
93
|
+
loaded?.close()
|
|
94
|
+
return@load
|
|
95
|
+
}
|
|
96
|
+
if (loaded == null) {
|
|
97
|
+
Log.w(
|
|
98
|
+
RenderImageDecoder.LOG_TAG,
|
|
99
|
+
"BlockImageSpan: loader returned null for image source"
|
|
100
|
+
)
|
|
101
|
+
return@load
|
|
102
|
+
}
|
|
103
|
+
val previous = bitmapLease.getAndSet(loaded)
|
|
104
|
+
if (retired.get()) {
|
|
105
|
+
if (bitmapLease.compareAndSet(loaded, null)) loaded.close()
|
|
106
|
+
previous?.close()
|
|
107
|
+
return@load
|
|
108
|
+
}
|
|
109
|
+
previous?.close()
|
|
110
|
+
currentHost?.post {
|
|
111
|
+
if (
|
|
112
|
+
currentHost is EditorEditText &&
|
|
113
|
+
!canReuseFor(currentHost)
|
|
114
|
+
) {
|
|
115
|
+
close()
|
|
116
|
+
return@post
|
|
117
|
+
}
|
|
118
|
+
if (currentHost is EditorEditText) {
|
|
119
|
+
currentHost.onImageSpanSizeMayChange(this@BlockImageSpan)
|
|
120
|
+
} else {
|
|
121
|
+
currentHost.requestLayout()
|
|
122
|
+
currentHost.invalidate()
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (!loadHandle.compareAndSet(null, handle) || retired.get()) {
|
|
127
|
+
loadHandle.getAndSet(null)?.cancel()
|
|
128
|
+
}
|
|
129
|
+
handle.onFinished { loadHandle.compareAndSet(handle, null) }
|
|
130
|
+
(hostView as? EditorEditText)?.registerImageLoad(handle)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
internal fun matches(source: String, width: Float?, height: Float?): Boolean =
|
|
135
|
+
!retired.get() && this.source == source && preferredWidthDp == width &&
|
|
136
|
+
preferredHeightDp == height
|
|
137
|
+
|
|
138
|
+
internal fun canReuseFor(host: EditorEditText): Boolean {
|
|
139
|
+
val sameDriver = if (hadBoundDriver) {
|
|
140
|
+
boundDriver.get()?.let { it === host.v2Driver } == true
|
|
141
|
+
} else {
|
|
142
|
+
host.v2Driver ==
|
|
143
|
+
null
|
|
144
|
+
}
|
|
145
|
+
return !retired.get() && hostRef.get() === host && sameDriver &&
|
|
146
|
+
boundEditorId == host.editorId &&
|
|
147
|
+
generation == host.currentImageLoadGeneration() && policy == host.imageLoadingPolicy
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
internal fun reloadedFor(hostView: View): BlockImageSpan = BlockImageSpan(
|
|
151
|
+
source = source,
|
|
152
|
+
hostView = hostView,
|
|
153
|
+
density = density,
|
|
154
|
+
preferredWidthDp = preferredWidthDp,
|
|
155
|
+
preferredHeightDp = preferredHeightDp,
|
|
156
|
+
imageStyle = imageStyle
|
|
157
|
+
).also { it.ancestorWidthInset = ancestorWidthInset }
|
|
158
|
+
|
|
159
|
+
internal fun close() {
|
|
160
|
+
if (!retired.compareAndSet(false, true)) return
|
|
161
|
+
loadHandle.getAndSet(null)?.cancel()
|
|
162
|
+
bitmapLease.getAndSet(null)?.close()
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
override fun getSize(
|
|
166
|
+
paint: Paint,
|
|
167
|
+
text: CharSequence,
|
|
168
|
+
start: Int,
|
|
169
|
+
end: Int,
|
|
170
|
+
fm: Paint.FontMetricsInt?
|
|
171
|
+
): Int {
|
|
172
|
+
val (widthPx, heightPx) = currentSizePx()
|
|
173
|
+
val inset = imageStyle?.box?.outerInset?.scaled(density) ?: EditorEdges()
|
|
174
|
+
if (fm != null) {
|
|
175
|
+
fm.ascent = -heightPx - (inset.top + inset.bottom).toInt()
|
|
176
|
+
fm.descent = 0
|
|
177
|
+
fm.top = fm.ascent
|
|
178
|
+
fm.bottom = 0
|
|
179
|
+
}
|
|
180
|
+
return widthPx + (inset.left + inset.right).toInt()
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
override fun draw(
|
|
184
|
+
canvas: Canvas,
|
|
185
|
+
text: CharSequence,
|
|
186
|
+
start: Int,
|
|
187
|
+
end: Int,
|
|
188
|
+
x: Float,
|
|
189
|
+
top: Int,
|
|
190
|
+
y: Int,
|
|
191
|
+
bottom: Int,
|
|
192
|
+
paint: Paint
|
|
193
|
+
) {
|
|
194
|
+
val rect = boxRect(x, y.toFloat())
|
|
195
|
+
val host = hostRef.get()
|
|
196
|
+
val documentRect =
|
|
197
|
+
((host as? EditorTextSurface)?.layout as? EditorDocumentLayout)?.imageBounds(
|
|
198
|
+
this
|
|
199
|
+
)
|
|
200
|
+
lastDrawRect = RectF(documentRect ?: rect).apply {
|
|
201
|
+
if (host != null) {
|
|
202
|
+
offset(
|
|
203
|
+
(host as? android.widget.TextView)?.compoundPaddingLeft?.toFloat()
|
|
204
|
+
?: host.paddingLeft.toFloat(),
|
|
205
|
+
(host as? android.widget.TextView)?.extendedPaddingTop?.toFloat()
|
|
206
|
+
?: host.paddingTop.toFloat()
|
|
207
|
+
)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
val loadedBitmap = bitmapLease.get()?.bitmap
|
|
211
|
+
imageStyle?.let {
|
|
212
|
+
val box = it.box.scaled(density)
|
|
213
|
+
EditorBoxDrawing.draw(canvas, rect, box)
|
|
214
|
+
if (loadedBitmap !=
|
|
215
|
+
null
|
|
216
|
+
) {
|
|
217
|
+
EditorBoxDrawing.drawImage(canvas, loadedBitmap, rect, box, it.resizeMode)
|
|
218
|
+
}
|
|
219
|
+
return
|
|
220
|
+
}
|
|
221
|
+
if (loadedBitmap != null) {
|
|
222
|
+
canvas.drawBitmap(loadedBitmap, null, rect, null)
|
|
223
|
+
return
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
val previousColor = paint.color
|
|
227
|
+
val previousStyle = paint.style
|
|
228
|
+
paint.color = Color.argb(24, 0, 0, 0)
|
|
229
|
+
paint.style = Paint.Style.FILL
|
|
230
|
+
canvas.drawRoundRect(rect, 16f * density, 16f * density, paint)
|
|
231
|
+
paint.color = Color.argb(120, 0, 0, 0)
|
|
232
|
+
val iconRadius = minOf(rect.width(), rect.height()) * 0.12f
|
|
233
|
+
canvas.drawCircle(rect.centerX(), rect.centerY(), iconRadius, paint)
|
|
234
|
+
paint.color = previousColor
|
|
235
|
+
paint.style = previousStyle
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
internal fun boxRect(x: Float, baseline: Float): RectF {
|
|
239
|
+
val (widthPx, heightPx) = currentSizePx()
|
|
240
|
+
val box = imageStyle?.box?.scaled(density) ?: EditorBoxStyle()
|
|
241
|
+
return RectF(
|
|
242
|
+
x + box.margin.left,
|
|
243
|
+
baseline - heightPx - box.inset.top - box.inset.bottom - box.margin.bottom,
|
|
244
|
+
x + box.margin.left + widthPx + box.inset.left + box.inset.right,
|
|
245
|
+
baseline - box.margin.bottom
|
|
246
|
+
)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
internal fun currentSizePx(): Pair<Int, Int> {
|
|
250
|
+
val maxWidth = resolvedMaxWidth()
|
|
251
|
+
val loadedBitmap = bitmapLease.get()?.bitmap
|
|
252
|
+
val fallbackAspectRatio = if (loadedBitmap != null && loadedBitmap.width > 0 &&
|
|
253
|
+
loadedBitmap.height > 0
|
|
254
|
+
) {
|
|
255
|
+
loadedBitmap.height.toFloat() / loadedBitmap.width.toFloat()
|
|
256
|
+
} else {
|
|
257
|
+
0.56f
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
var widthPx = checkedPixels(preferredWidthDp)
|
|
261
|
+
var heightPx = checkedPixels(preferredHeightDp)
|
|
262
|
+
|
|
263
|
+
if (widthPx == null && heightPx == null && loadedBitmap != null && loadedBitmap.width > 0 &&
|
|
264
|
+
loadedBitmap.height > 0
|
|
265
|
+
) {
|
|
266
|
+
widthPx = loadedBitmap.width.toFloat()
|
|
267
|
+
heightPx = loadedBitmap.height.toFloat()
|
|
268
|
+
} else if (widthPx == null && heightPx != null) {
|
|
269
|
+
widthPx = heightPx / fallbackAspectRatio
|
|
270
|
+
} else if (heightPx == null && widthPx != null) {
|
|
271
|
+
heightPx = widthPx * fallbackAspectRatio
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (widthPx == null || heightPx == null) {
|
|
275
|
+
val placeholderWidth = maxWidth.coerceAtLeast(160f * density)
|
|
276
|
+
val placeholderHeight = minOf(
|
|
277
|
+
180f * density,
|
|
278
|
+
placeholderWidth * fallbackAspectRatio
|
|
279
|
+
).coerceAtLeast(96f * density)
|
|
280
|
+
widthPx = placeholderWidth
|
|
281
|
+
heightPx = placeholderHeight
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (!widthPx.isFinite() || widthPx <= 0f || !heightPx.isFinite() || heightPx <= 0f) {
|
|
285
|
+
widthPx = maxWidth
|
|
286
|
+
heightPx = minOf(maxWidth * 0.56f, policy.maxDecodeDimensionPx.toFloat())
|
|
287
|
+
}
|
|
288
|
+
val maximumDimension = policy.maxDecodeDimensionPx.toFloat()
|
|
289
|
+
val scale = minOf(
|
|
290
|
+
1f,
|
|
291
|
+
maxWidth / widthPx.coerceAtLeast(1f),
|
|
292
|
+
maximumDimension / heightPx.coerceAtLeast(1f)
|
|
293
|
+
)
|
|
294
|
+
return Pair(
|
|
295
|
+
checkedPositiveInt(widthPx * scale),
|
|
296
|
+
checkedPositiveInt(heightPx * scale)
|
|
297
|
+
)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
internal fun currentDrawRect(): RectF? = lastDrawRect?.let(::RectF)
|
|
301
|
+
|
|
302
|
+
private fun resolvedMaxWidth(): Float {
|
|
303
|
+
val host = hostRef.get()
|
|
304
|
+
val hostWidth = host?.let {
|
|
305
|
+
maxOf(it.width, it.measuredWidth) -
|
|
306
|
+
((it as? android.widget.TextView)?.totalPaddingLeft ?: it.paddingLeft) -
|
|
307
|
+
((it as? android.widget.TextView)?.totalPaddingRight ?: it.paddingRight)
|
|
308
|
+
} ?: 0
|
|
309
|
+
val inset = imageStyle?.box?.outerInset?.scaled(density) ?: EditorEdges()
|
|
310
|
+
val candidate =
|
|
311
|
+
(if (hostWidth > 0) hostWidth.toDouble() else 240.0 * density.toDouble()) - inset.left -
|
|
312
|
+
inset.right -
|
|
313
|
+
ancestorWidthInset
|
|
314
|
+
return candidate
|
|
315
|
+
.takeIf { it.isFinite() && it > 0.0 }
|
|
316
|
+
?.coerceAtMost(policy.maxDecodeDimensionPx.toDouble())
|
|
317
|
+
?.toFloat()
|
|
318
|
+
?: policy.maxDecodeDimensionPx.toFloat()
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
private fun checkedPixels(preferredDp: Float?): Float? {
|
|
322
|
+
val value = preferredDp ?: return null
|
|
323
|
+
if (!value.isFinite() || value <= 0f || !density.isFinite() || density <= 0f) return null
|
|
324
|
+
val pixels = value.toDouble() * density.toDouble()
|
|
325
|
+
return pixels.takeIf {
|
|
326
|
+
it.isFinite() && it > 0.0 && it <= Int.MAX_VALUE.toDouble()
|
|
327
|
+
}?.toFloat()
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
private fun checkedPositiveInt(value: Float): Int = value
|
|
331
|
+
.takeIf { it.isFinite() && it > 0f }
|
|
332
|
+
?.toDouble()
|
|
333
|
+
?.coerceAtMost(Int.MAX_VALUE.toDouble())
|
|
334
|
+
?.toInt()
|
|
335
|
+
?.coerceAtLeast(1)
|
|
336
|
+
?: 1
|
|
337
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
package com.apollohg.editor
|
|
2
|
+
|
|
3
|
+
import android.graphics.Canvas
|
|
4
|
+
import android.graphics.Paint
|
|
5
|
+
import android.text.Spanned
|
|
6
|
+
import android.text.style.LineHeightSpan
|
|
7
|
+
import android.text.style.ReplacementSpan
|
|
8
|
+
|
|
9
|
+
class FixedLineHeightSpan(private val lineHeightPx: Int) : LineHeightSpan {
|
|
10
|
+
override fun chooseHeight(
|
|
11
|
+
text: CharSequence,
|
|
12
|
+
start: Int,
|
|
13
|
+
end: Int,
|
|
14
|
+
spanstartv: Int,
|
|
15
|
+
v: Int,
|
|
16
|
+
fm: android.graphics.Paint.FontMetricsInt
|
|
17
|
+
) {
|
|
18
|
+
val paragraphSpacing = if (end > start && text[end - 1] == '\n' && text is Spanned) {
|
|
19
|
+
text.getSpans(end - 1, end, ParagraphSpacerSpan::class.java)
|
|
20
|
+
.maxOfOrNull { it.spacingPx }
|
|
21
|
+
?: 0
|
|
22
|
+
} else {
|
|
23
|
+
0
|
|
24
|
+
}
|
|
25
|
+
val currentHeight = fm.descent - paragraphSpacing - fm.ascent
|
|
26
|
+
if (lineHeightPx <= 0 || currentHeight <= 0) return
|
|
27
|
+
if (lineHeightPx == currentHeight) return
|
|
28
|
+
|
|
29
|
+
val extra = lineHeightPx - currentHeight
|
|
30
|
+
fm.descent += extra
|
|
31
|
+
fm.bottom = fm.descent
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Adds vertical spacing after a paragraph by increasing the descent of the
|
|
37
|
+
* inter-block newline character.
|
|
38
|
+
*
|
|
39
|
+
* Uses [ReplacementSpan] (not [LineHeightSpan]/[android.text.style.ParagraphStyle])
|
|
40
|
+
* because Android's StaticLayout normalizes ParagraphStyle metrics across all
|
|
41
|
+
* lines in a paragraph, making per-line spacing impossible.
|
|
42
|
+
*
|
|
43
|
+
* ReplacementSpan only affects the single character it covers, so the extra
|
|
44
|
+
* descent applies only to the newline's line — creating a gap below the
|
|
45
|
+
* preceding paragraph without inflating other lines.
|
|
46
|
+
*/
|
|
47
|
+
class ParagraphSpacerSpan(
|
|
48
|
+
internal val spacingPx: Int,
|
|
49
|
+
private val baseFontSize: Int,
|
|
50
|
+
private val textColor: Int
|
|
51
|
+
) : ReplacementSpan() {
|
|
52
|
+
override fun getSize(
|
|
53
|
+
paint: Paint,
|
|
54
|
+
text: CharSequence,
|
|
55
|
+
start: Int,
|
|
56
|
+
end: Int,
|
|
57
|
+
fm: Paint.FontMetricsInt?
|
|
58
|
+
): Int {
|
|
59
|
+
if (fm != null && spacingPx > 0) {
|
|
60
|
+
// Keep the natural ascent/top (from baseFontSize) so the newline
|
|
61
|
+
// line doesn't shrink above the baseline. Add spacing as descent.
|
|
62
|
+
val savedSize = paint.textSize
|
|
63
|
+
paint.textSize = baseFontSize.toFloat()
|
|
64
|
+
paint.getFontMetricsInt(fm)
|
|
65
|
+
paint.textSize = savedSize
|
|
66
|
+
fm.descent += spacingPx
|
|
67
|
+
fm.bottom = fm.descent
|
|
68
|
+
}
|
|
69
|
+
return 0
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
override fun draw(
|
|
73
|
+
canvas: Canvas,
|
|
74
|
+
text: CharSequence,
|
|
75
|
+
start: Int,
|
|
76
|
+
end: Int,
|
|
77
|
+
x: Float,
|
|
78
|
+
top: Int,
|
|
79
|
+
y: Int,
|
|
80
|
+
bottom: Int,
|
|
81
|
+
paint: Paint
|
|
82
|
+
) {
|
|
83
|
+
// Draw nothing — pure spacing.
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
class MarkerGapSpan(private val widthPx: Float) : ReplacementSpan() {
|
|
88
|
+
override fun getSize(
|
|
89
|
+
paint: Paint,
|
|
90
|
+
text: CharSequence,
|
|
91
|
+
start: Int,
|
|
92
|
+
end: Int,
|
|
93
|
+
fm: Paint.FontMetricsInt?
|
|
94
|
+
): Int = kotlin.math.ceil(widthPx).toInt()
|
|
95
|
+
|
|
96
|
+
override fun draw(
|
|
97
|
+
canvas: Canvas,
|
|
98
|
+
text: CharSequence,
|
|
99
|
+
start: Int,
|
|
100
|
+
end: Int,
|
|
101
|
+
x: Float,
|
|
102
|
+
top: Int,
|
|
103
|
+
y: Int,
|
|
104
|
+
bottom: Int,
|
|
105
|
+
paint: Paint
|
|
106
|
+
) = Unit
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
internal class OrderedListMarkerSpan(internal val label: String) : ReplacementSpan() {
|
|
110
|
+
override fun getSize(
|
|
111
|
+
paint: Paint,
|
|
112
|
+
text: CharSequence,
|
|
113
|
+
start: Int,
|
|
114
|
+
end: Int,
|
|
115
|
+
fm: Paint.FontMetricsInt?
|
|
116
|
+
): Int = kotlin.math.ceil(paint.measureText(label).toDouble()).toInt()
|
|
117
|
+
|
|
118
|
+
override fun draw(
|
|
119
|
+
canvas: Canvas,
|
|
120
|
+
text: CharSequence,
|
|
121
|
+
start: Int,
|
|
122
|
+
end: Int,
|
|
123
|
+
x: Float,
|
|
124
|
+
top: Int,
|
|
125
|
+
y: Int,
|
|
126
|
+
bottom: Int,
|
|
127
|
+
paint: Paint
|
|
128
|
+
) {
|
|
129
|
+
canvas.drawText(label, x, y.toFloat(), paint)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
class CenteredBulletSpan(
|
|
134
|
+
private val textColor: Int,
|
|
135
|
+
private val markerWidthPx: Float,
|
|
136
|
+
private val bulletRadiusPx: Float,
|
|
137
|
+
private val bodyFontSizePx: Float,
|
|
138
|
+
private val markerGapToTextPx: Float
|
|
139
|
+
) : ReplacementSpan() {
|
|
140
|
+
override fun getSize(
|
|
141
|
+
paint: Paint,
|
|
142
|
+
text: CharSequence,
|
|
143
|
+
start: Int,
|
|
144
|
+
end: Int,
|
|
145
|
+
fm: Paint.FontMetricsInt?
|
|
146
|
+
): Int = kotlin.math.ceil(markerWidthPx).toInt()
|
|
147
|
+
|
|
148
|
+
override fun draw(
|
|
149
|
+
canvas: Canvas,
|
|
150
|
+
text: CharSequence,
|
|
151
|
+
start: Int,
|
|
152
|
+
end: Int,
|
|
153
|
+
x: Float,
|
|
154
|
+
top: Int,
|
|
155
|
+
y: Int,
|
|
156
|
+
bottom: Int,
|
|
157
|
+
paint: Paint
|
|
158
|
+
) {
|
|
159
|
+
val previousColor = paint.color
|
|
160
|
+
val previousStyle = paint.style
|
|
161
|
+
val previousSize = paint.textSize
|
|
162
|
+
|
|
163
|
+
paint.color = textColor
|
|
164
|
+
paint.style = Paint.Style.FILL
|
|
165
|
+
|
|
166
|
+
// Use body text metrics (not the marker's inflated font) for centering.
|
|
167
|
+
paint.textSize = bodyFontSizePx
|
|
168
|
+
val fm = paint.fontMetrics
|
|
169
|
+
val centerX = resolvedCenterX(x)
|
|
170
|
+
val centerY = y + (fm.ascent + fm.descent) / 2f
|
|
171
|
+
canvas.drawCircle(centerX, centerY, bulletRadiusPx, paint)
|
|
172
|
+
|
|
173
|
+
paint.color = previousColor
|
|
174
|
+
paint.style = previousStyle
|
|
175
|
+
paint.textSize = previousSize
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
fun textSideGapPx(x: Float): Float = (x + markerWidthPx) - (resolvedCenterX(x) + bulletRadiusPx)
|
|
179
|
+
|
|
180
|
+
private fun resolvedCenterX(x: Float): Float =
|
|
181
|
+
x + markerWidthPx - markerGapToTextPx - bulletRadiusPx
|
|
182
|
+
}
|