@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.
Files changed (494) hide show
  1. package/LICENSE +160 -0
  2. package/README.md +259 -0
  3. package/RUST-STANDARD-LIBRARY-NOTICES.html +8266 -0
  4. package/ReactNativeProseEditor.podspec +59 -0
  5. package/THIRD_PARTY_NOTICES.md +31155 -0
  6. package/android/build.gradle +188 -0
  7. package/android/consumer-rules.pro +18 -0
  8. package/android/expo/build.gradle +17 -0
  9. package/android/src/debug/java/com/apollohg/editor/viewer/PreparedProseDrawInstrumentation.kt +7 -0
  10. package/android/src/main/assets/editor-icons/MaterialIcons.json +2236 -0
  11. package/android/src/main/assets/editor-icons/MaterialIcons.ttf +0 -0
  12. package/android/src/main/java/com/apollohg/editor/AndroidApiCompat.kt +19 -0
  13. package/android/src/main/java/com/apollohg/editor/AndroidCollaborationTransport.kt +860 -0
  14. package/android/src/main/java/com/apollohg/editor/CaretGeometry.kt +91 -0
  15. package/android/src/main/java/com/apollohg/editor/CodeHighlighting.kt +141 -0
  16. package/android/src/main/java/com/apollohg/editor/DecodedBitmapBudget.kt +250 -0
  17. package/android/src/main/java/com/apollohg/editor/EditorAddons.kt +133 -0
  18. package/android/src/main/java/com/apollohg/editor/EditorBlockSpacing.kt +51 -0
  19. package/android/src/main/java/com/apollohg/editor/EditorBoxDrawable.kt +16 -0
  20. package/android/src/main/java/com/apollohg/editor/EditorBoxDrawing.kt +234 -0
  21. package/android/src/main/java/com/apollohg/editor/EditorCheckboxSpan.kt +87 -0
  22. package/android/src/main/java/com/apollohg/editor/EditorCodeHighlighting.kt +120 -0
  23. package/android/src/main/java/com/apollohg/editor/EditorDecorationLayer.java +18 -0
  24. package/android/src/main/java/com/apollohg/editor/EditorDocumentLayout.kt +626 -0
  25. package/android/src/main/java/com/apollohg/editor/EditorEditText.kt +1042 -0
  26. package/android/src/main/java/com/apollohg/editor/EditorEditTextAnnotations.kt +191 -0
  27. package/android/src/main/java/com/apollohg/editor/EditorEditTextCaret.kt +100 -0
  28. package/android/src/main/java/com/apollohg/editor/EditorEditTextClipboard.kt +101 -0
  29. package/android/src/main/java/com/apollohg/editor/EditorEditTextComposition.kt +220 -0
  30. package/android/src/main/java/com/apollohg/editor/EditorEditTextConfiguration.kt +316 -0
  31. package/android/src/main/java/com/apollohg/editor/EditorEditTextCorrection.kt +303 -0
  32. package/android/src/main/java/com/apollohg/editor/EditorEditTextDeferredUpdates.kt +327 -0
  33. package/android/src/main/java/com/apollohg/editor/EditorEditTextDeletion.kt +258 -0
  34. package/android/src/main/java/com/apollohg/editor/EditorEditTextDiagnostics.kt +83 -0
  35. package/android/src/main/java/com/apollohg/editor/EditorEditTextDragDrop.kt +67 -0
  36. package/android/src/main/java/com/apollohg/editor/EditorEditTextExternalComposition.kt +357 -0
  37. package/android/src/main/java/com/apollohg/editor/EditorEditTextHardwareInput.kt +277 -0
  38. package/android/src/main/java/com/apollohg/editor/EditorEditTextImages.kt +280 -0
  39. package/android/src/main/java/com/apollohg/editor/EditorEditTextInputLifecycle.kt +183 -0
  40. package/android/src/main/java/com/apollohg/editor/EditorEditTextInputPreparation.kt +79 -0
  41. package/android/src/main/java/com/apollohg/editor/EditorEditTextInputTraits.kt +384 -0
  42. package/android/src/main/java/com/apollohg/editor/EditorEditTextLayout.kt +100 -0
  43. package/android/src/main/java/com/apollohg/editor/EditorEditTextNativeMutation.kt +243 -0
  44. package/android/src/main/java/com/apollohg/editor/EditorEditTextPlaceholder.kt +154 -0
  45. package/android/src/main/java/com/apollohg/editor/EditorEditTextRenderPatch.kt +347 -0
  46. package/android/src/main/java/com/apollohg/editor/EditorEditTextRendering.kt +313 -0
  47. package/android/src/main/java/com/apollohg/editor/EditorEditTextRustCommands.kt +281 -0
  48. package/android/src/main/java/com/apollohg/editor/EditorEditTextSelection.kt +352 -0
  49. package/android/src/main/java/com/apollohg/editor/EditorEditTextState.kt +113 -0
  50. package/android/src/main/java/com/apollohg/editor/EditorEditTextTaskMarkers.kt +92 -0
  51. package/android/src/main/java/com/apollohg/editor/EditorEditTextTextCommit.kt +327 -0
  52. package/android/src/main/java/com/apollohg/editor/EditorEditTextToolbar.kt +84 -0
  53. package/android/src/main/java/com/apollohg/editor/EditorEditTextUpdates.kt +245 -0
  54. package/android/src/main/java/com/apollohg/editor/EditorGlyphHeightCursorDrawable.kt +42 -0
  55. package/android/src/main/java/com/apollohg/editor/EditorHeightBehavior.kt +13 -0
  56. package/android/src/main/java/com/apollohg/editor/EditorInputConnection.kt +923 -0
  57. package/android/src/main/java/com/apollohg/editor/EditorInputCoordinates.kt +191 -0
  58. package/android/src/main/java/com/apollohg/editor/EditorInputCorrection.kt +107 -0
  59. package/android/src/main/java/com/apollohg/editor/EditorInputCursorGeometry.kt +128 -0
  60. package/android/src/main/java/com/apollohg/editor/EditorInputSnapshots.kt +134 -0
  61. package/android/src/main/java/com/apollohg/editor/EditorInputSurroundingDeletion.kt +321 -0
  62. package/android/src/main/java/com/apollohg/editor/EditorKeyboardToolbarView.kt +851 -0
  63. package/android/src/main/java/com/apollohg/editor/EditorMentionStyle.kt +192 -0
  64. package/android/src/main/java/com/apollohg/editor/EditorReconciliationWatcher.kt +46 -0
  65. package/android/src/main/java/com/apollohg/editor/EditorStyleSheet.kt +303 -0
  66. package/android/src/main/java/com/apollohg/editor/EditorStyleSheetSpans.kt +253 -0
  67. package/android/src/main/java/com/apollohg/editor/EditorSurfaceInputConnection.kt +67 -0
  68. package/android/src/main/java/com/apollohg/editor/EditorTextDecorationDrawing.kt +143 -0
  69. package/android/src/main/java/com/apollohg/editor/EditorTextSurface.kt +712 -0
  70. package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceDragDrop.kt +94 -0
  71. package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceInteraction.kt +708 -0
  72. package/android/src/main/java/com/apollohg/editor/EditorTheme.kt +650 -0
  73. package/android/src/main/java/com/apollohg/editor/EditorV2Adapter.kt +912 -0
  74. package/android/src/main/java/com/apollohg/editor/EditorV2AdapterMutations.kt +402 -0
  75. package/android/src/main/java/com/apollohg/editor/EditorV2AdapterRendering.kt +123 -0
  76. package/android/src/main/java/com/apollohg/editor/EditorV2AdapterSelection.kt +203 -0
  77. package/android/src/main/java/com/apollohg/editor/EditorV2Backend.kt +120 -0
  78. package/android/src/main/java/com/apollohg/editor/EditorV2Driver.kt +87 -0
  79. package/android/src/main/java/com/apollohg/editor/EditorV2Registry.kt +97 -0
  80. package/android/src/main/java/com/apollohg/editor/EditorV2RenderValidation.kt +409 -0
  81. package/android/src/main/java/com/apollohg/editor/ExpoAutoGrowStyleSizePublisher.kt +34 -0
  82. package/android/src/main/java/com/apollohg/editor/ImageResizeOverlayView.kt +266 -0
  83. package/android/src/main/java/com/apollohg/editor/ImeTextCoordinateMapper.kt +102 -0
  84. package/android/src/main/java/com/apollohg/editor/KeyboardToolbarImeAnimationController.kt +101 -0
  85. package/android/src/main/java/com/apollohg/editor/MentionSuggestionChipView.kt +234 -0
  86. package/android/src/main/java/com/apollohg/editor/NativeCollaborationTransportRegistry.kt +493 -0
  87. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoView.kt +813 -0
  88. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewAtoms.kt +68 -0
  89. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewBinding.kt +126 -0
  90. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewDiagnostics.kt +208 -0
  91. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewErrors.kt +146 -0
  92. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewEvents.kt +150 -0
  93. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewExternalComposition.kt +39 -0
  94. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewFocus.kt +176 -0
  95. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewLifecycle.kt +302 -0
  96. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewMentions.kt +259 -0
  97. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewNativeActions.kt +179 -0
  98. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewOutsideTap.kt +214 -0
  99. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewPendingUpdates.kt +376 -0
  100. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewProperties.kt +234 -0
  101. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewPropertyRetries.kt +197 -0
  102. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewToolbar.kt +285 -0
  103. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewTypes.kt +28 -0
  104. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewUpdates.kt +271 -0
  105. package/android/src/main/java/com/apollohg/editor/NativeEditorModule.kt +687 -0
  106. package/android/src/main/java/com/apollohg/editor/NativeEditorOutsideTapDispatcher.kt +380 -0
  107. package/android/src/main/java/com/apollohg/editor/NativeEditorV2Numbers.kt +45 -0
  108. package/android/src/main/java/com/apollohg/editor/NativeEditorViewRegistry.kt +372 -0
  109. package/android/src/main/java/com/apollohg/editor/NativeImagePipeline.kt +22 -0
  110. package/android/src/main/java/com/apollohg/editor/NativeToolbar.kt +193 -0
  111. package/android/src/main/java/com/apollohg/editor/NativeToolbarIcons.kt +177 -0
  112. package/android/src/main/java/com/apollohg/editor/NativeToolbarItem.kt +274 -0
  113. package/android/src/main/java/com/apollohg/editor/OkHttpCollaborationSocket.kt +102 -0
  114. package/android/src/main/java/com/apollohg/editor/OrderedListMarkerFormatter.kt +130 -0
  115. package/android/src/main/java/com/apollohg/editor/PointerTransparentView.java +18 -0
  116. package/android/src/main/java/com/apollohg/editor/PositionBridge.kt +128 -0
  117. package/android/src/main/java/com/apollohg/editor/ProseViewerView.kt +854 -0
  118. package/android/src/main/java/com/apollohg/editor/RemoteSelectionOverlayView.kt +314 -0
  119. package/android/src/main/java/com/apollohg/editor/RenderBlockSpans.kt +314 -0
  120. package/android/src/main/java/com/apollohg/editor/RenderBridge.kt +224 -0
  121. package/android/src/main/java/com/apollohg/editor/RenderBridgeBlockStyles.kt +407 -0
  122. package/android/src/main/java/com/apollohg/editor/RenderBridgeElements.kt +544 -0
  123. package/android/src/main/java/com/apollohg/editor/RenderBridgeInlineAndAtoms.kt +631 -0
  124. package/android/src/main/java/com/apollohg/editor/RenderBridgeParagraphs.kt +215 -0
  125. package/android/src/main/java/com/apollohg/editor/RenderImageDecoder.kt +748 -0
  126. package/android/src/main/java/com/apollohg/editor/RenderImageLoader.kt +900 -0
  127. package/android/src/main/java/com/apollohg/editor/RenderLayoutConstants.kt +117 -0
  128. package/android/src/main/java/com/apollohg/editor/RenderMediaSpans.kt +337 -0
  129. package/android/src/main/java/com/apollohg/editor/RenderParagraphSpans.kt +182 -0
  130. package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +951 -0
  131. package/android/src/main/java/com/apollohg/editor/SharedNativeImagePipeline.kt +78 -0
  132. package/android/src/main/java/com/apollohg/editor/UniffiEditorV2Backend.kt +261 -0
  133. package/android/src/main/java/com/apollohg/editor/viewer/AndroidProseLayoutEngine.kt +1656 -0
  134. package/android/src/main/java/com/apollohg/editor/viewer/FabricAttachmentSidecars.kt +80 -0
  135. package/android/src/main/java/com/apollohg/editor/viewer/FabricLeaseHandleBridge.kt +59 -0
  136. package/android/src/main/java/com/apollohg/editor/viewer/FallbackSelectionGeometry.kt +450 -0
  137. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseDrawingView.kt +678 -0
  138. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseInstrumentation.kt +608 -0
  139. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayout.kt +186 -0
  140. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayoutCache.kt +393 -0
  141. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayoutRegistry.kt +828 -0
  142. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseTheme.kt +316 -0
  143. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseViewerManager.kt +900 -0
  144. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseViewerPackage.kt +16 -0
  145. package/android/src/main/java/com/apollohg/editor/viewer/PreparedViewerAtoms.kt +89 -0
  146. package/android/src/main/java/com/apollohg/editor/viewer/ViewerCodeHighlighting.kt +91 -0
  147. package/android/src/main/java/com/apollohg/editor/viewer/ViewerDocument.kt +453 -0
  148. package/android/src/main/java/com/apollohg/editor/viewer/ViewerFontEnvironment.kt +282 -0
  149. package/android/src/main/java/com/apollohg/editor/viewer/ViewerImagePipeline.kt +460 -0
  150. package/android/src/main/jni/CMakeLists.txt +85 -0
  151. package/android/src/main/jni/PreparedProseViewerMeasurementsManager.cpp +334 -0
  152. package/android/src/main/jni/ReactNativeProseEditorSpec.h +17 -0
  153. package/android/src/main/jni/reactnativeproseeditor.h +6 -0
  154. package/android/src/main/res/values/attrs.xml +6 -0
  155. package/android/src/release/java/com/apollohg/editor/viewer/PreparedProseDrawInstrumentation.kt +9 -0
  156. package/app.plugin.js +62 -0
  157. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseMeasurementsManager.h +62 -0
  158. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerComponentDescriptor.h +30 -0
  159. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerShadowNode.cpp +192 -0
  160. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerShadowNode.h +46 -0
  161. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerState.h +145 -0
  162. package/dist/AtomHost.d.ts +17 -0
  163. package/dist/AtomHost.js +135 -0
  164. package/dist/DefaultAtomChip.d.ts +2 -0
  165. package/dist/DefaultAtomChip.js +22 -0
  166. package/dist/EditorAddon.d.ts +32 -0
  167. package/dist/EditorAddon.js +29 -0
  168. package/dist/EditorAddonNormalization.d.ts +6 -0
  169. package/dist/EditorAddonNormalization.js +48 -0
  170. package/dist/EditorMentionThemeNormalization.d.ts +8 -0
  171. package/dist/EditorMentionThemeNormalization.js +22 -0
  172. package/dist/EditorMentionThemeValidation.d.ts +12 -0
  173. package/dist/EditorMentionThemeValidation.js +95 -0
  174. package/dist/EditorStyleSheet.d.ts +4 -0
  175. package/dist/EditorStyleSheet.js +10 -0
  176. package/dist/EditorStyleSheetNormalization.d.ts +3 -0
  177. package/dist/EditorStyleSheetNormalization.js +226 -0
  178. package/dist/EditorStyleSheetTypes.d.ts +151 -0
  179. package/dist/EditorStyleSheetTypes.js +2 -0
  180. package/dist/EditorTheme.d.ts +117 -0
  181. package/dist/EditorTheme.js +41 -0
  182. package/dist/EditorToolbar.d.ts +4 -0
  183. package/dist/EditorToolbar.js +17 -0
  184. package/dist/EditorToolbarComponent.d.ts +13 -0
  185. package/dist/EditorToolbarComponent.js +24 -0
  186. package/dist/EditorToolbarItems.d.ts +9 -0
  187. package/dist/EditorToolbarItems.js +58 -0
  188. package/dist/EditorToolbarRegistry.d.ts +59 -0
  189. package/dist/EditorToolbarRegistry.js +175 -0
  190. package/dist/EditorToolbarTypes.d.ts +273 -0
  191. package/dist/EditorToolbarTypes.js +2 -0
  192. package/dist/EditorToolbarVisuals.d.ts +154 -0
  193. package/dist/EditorToolbarVisuals.js +228 -0
  194. package/dist/EditorUpdateRevision.d.ts +8 -0
  195. package/dist/EditorUpdateRevision.js +22 -0
  196. package/dist/ExternalTextComposition.d.ts +45 -0
  197. package/dist/ExternalTextComposition.js +537 -0
  198. package/dist/ImageLoadingPolicy.d.ts +54 -0
  199. package/dist/ImageLoadingPolicy.js +60 -0
  200. package/dist/NativeEditorBoundaryError.d.ts +111 -0
  201. package/dist/NativeEditorBoundaryError.js +268 -0
  202. package/dist/NativeEditorBridge.d.ts +9 -0
  203. package/dist/NativeEditorBridge.js +37 -0
  204. package/dist/NativeEditorCollaborationTransport.d.ts +154 -0
  205. package/dist/NativeEditorCollaborationTransport.js +275 -0
  206. package/dist/NativeEditorCreateConfig.d.ts +16 -0
  207. package/dist/NativeEditorCreateConfig.js +249 -0
  208. package/dist/NativeEditorCreateJson.d.ts +76 -0
  209. package/dist/NativeEditorCreateJson.js +474 -0
  210. package/dist/NativeEditorCreateValidation.d.ts +32 -0
  211. package/dist/NativeEditorCreateValidation.js +150 -0
  212. package/dist/NativeEditorDocumentBridge.d.ts +72 -0
  213. package/dist/NativeEditorDocumentBridge.js +305 -0
  214. package/dist/NativeEditorDocumentHandle.d.ts +70 -0
  215. package/dist/NativeEditorDocumentHandle.js +89 -0
  216. package/dist/NativeEditorLocalAwareness.d.ts +34 -0
  217. package/dist/NativeEditorLocalAwareness.js +153 -0
  218. package/dist/NativeEditorNativeModule.d.ts +48 -0
  219. package/dist/NativeEditorNativeModule.js +34 -0
  220. package/dist/NativeEditorRenderNormalization.d.ts +22 -0
  221. package/dist/NativeEditorRenderNormalization.js +274 -0
  222. package/dist/NativeEditorResultNormalization.d.ts +108 -0
  223. package/dist/NativeEditorResultNormalization.js +400 -0
  224. package/dist/NativeEditorTypes.d.ts +318 -0
  225. package/dist/NativeEditorTypes.js +15 -0
  226. package/dist/NativeEditorV2Decimal.d.ts +5 -0
  227. package/dist/NativeEditorV2Decimal.js +18 -0
  228. package/dist/NativeProseViewer.d.ts +122 -0
  229. package/dist/NativeProseViewer.js +130 -0
  230. package/dist/NativeRichTextEditor.d.ts +3 -0
  231. package/dist/NativeRichTextEditor.js +6 -0
  232. package/dist/ResourceLimits.d.ts +100 -0
  233. package/dist/ResourceLimits.js +80 -0
  234. package/dist/RichTextEditor.d.ts +4 -0
  235. package/dist/RichTextEditor.js +25 -0
  236. package/dist/RichTextEditorNativeTypes.d.ts +122 -0
  237. package/dist/RichTextEditorNativeTypes.js +2 -0
  238. package/dist/RichTextEditorNativeView.d.ts +12 -0
  239. package/dist/RichTextEditorNativeView.js +15 -0
  240. package/dist/RichTextEditorSerialization.d.ts +53 -0
  241. package/dist/RichTextEditorSerialization.js +283 -0
  242. package/dist/RichTextEditorTypes.d.ts +281 -0
  243. package/dist/RichTextEditorTypes.js +2 -0
  244. package/dist/ViewerConfiguration.d.ts +22 -0
  245. package/dist/ViewerConfiguration.js +6 -0
  246. package/dist/YjsCollaboration.d.ts +146 -0
  247. package/dist/YjsCollaboration.js +496 -0
  248. package/dist/addons.d.ts +193 -0
  249. package/dist/addons.js +122 -0
  250. package/dist/atomConstants.d.ts +3 -0
  251. package/dist/atomConstants.js +6 -0
  252. package/dist/atomInstances.d.ts +35 -0
  253. package/dist/atomInstances.js +79 -0
  254. package/dist/atomPolicy.d.ts +4 -0
  255. package/dist/atomPolicy.js +47 -0
  256. package/dist/atomUpdates.d.ts +2 -0
  257. package/dist/atomUpdates.js +38 -0
  258. package/dist/atoms.d.ts +92 -0
  259. package/dist/atoms.js +222 -0
  260. package/dist/attributeValidation.d.ts +4 -0
  261. package/dist/attributeValidation.js +97 -0
  262. package/dist/contentExpression.d.ts +6 -0
  263. package/dist/contentExpression.js +335 -0
  264. package/dist/index.d.ts +21 -0
  265. package/dist/index.js +78 -0
  266. package/dist/listMarkers.d.ts +15 -0
  267. package/dist/listMarkers.js +21 -0
  268. package/dist/schemaDefinition.d.ts +143 -0
  269. package/dist/schemaDefinition.js +206 -0
  270. package/dist/schemaDocument.d.ts +17 -0
  271. package/dist/schemaDocument.js +69 -0
  272. package/dist/schemaDocumentConstruction.d.ts +5 -0
  273. package/dist/schemaDocumentConstruction.js +125 -0
  274. package/dist/schemaNormalization.d.ts +29 -0
  275. package/dist/schemaNormalization.js +313 -0
  276. package/dist/schemaPresets.d.ts +68 -0
  277. package/dist/schemaPresets.js +198 -0
  278. package/dist/schemaResolution.d.ts +9 -0
  279. package/dist/schemaResolution.js +211 -0
  280. package/dist/schemas.d.ts +5 -0
  281. package/dist/schemas.js +28 -0
  282. package/dist/specs/PreparedProseViewerNativeComponent.d.ts +37 -0
  283. package/dist/specs/PreparedProseViewerNativeComponent.js +6 -0
  284. package/dist/useEditorToolbarInteractions.d.ts +12 -0
  285. package/dist/useEditorToolbarInteractions.js +218 -0
  286. package/dist/useEditorToolbarItems.d.ts +8 -0
  287. package/dist/useEditorToolbarItems.js +280 -0
  288. package/dist/useEditorToolbarPresentation.d.ts +4 -0
  289. package/dist/useEditorToolbarPresentation.js +203 -0
  290. package/dist/useEditorToolbarState.d.ts +63 -0
  291. package/dist/useEditorToolbarState.js +108 -0
  292. package/dist/useFocusPreservingFrames.d.ts +17 -0
  293. package/dist/useFocusPreservingFrames.js +108 -0
  294. package/dist/useNativeEditor.d.ts +66 -0
  295. package/dist/useNativeEditor.js +370 -0
  296. package/dist/useRichTextEditorCommands.d.ts +21 -0
  297. package/dist/useRichTextEditorCommands.js +299 -0
  298. package/dist/useRichTextEditorEvents.d.ts +18 -0
  299. package/dist/useRichTextEditorEvents.js +216 -0
  300. package/dist/useRichTextEditorMentions.d.ts +11 -0
  301. package/dist/useRichTextEditorMentions.js +316 -0
  302. package/dist/useRichTextEditorPresentation.d.ts +5 -0
  303. package/dist/useRichTextEditorPresentation.js +178 -0
  304. package/dist/useRichTextEditorState.d.ts +180 -0
  305. package/dist/useRichTextEditorState.js +405 -0
  306. package/dist/useRichTextEditorUpdates.d.ts +10 -0
  307. package/dist/useRichTextEditorUpdates.js +308 -0
  308. package/dist/useViewerAtoms.d.ts +38 -0
  309. package/dist/useViewerAtoms.js +288 -0
  310. package/expo-module.config.json +13 -0
  311. package/ios/EditorAddons.swift +354 -0
  312. package/ios/EditorCodeHighlighting.swift +184 -0
  313. package/ios/EditorCore.xcframework/Info.plist +44 -0
  314. package/ios/EditorCore.xcframework/ios-arm64/libeditor_core.a +0 -0
  315. package/ios/EditorCore.xcframework/ios-arm64_x86_64-simulator/libeditor_core.a +0 -0
  316. package/ios/EditorInteractionOverlays.swift +697 -0
  317. package/ios/EditorLayoutManager.swift +971 -0
  318. package/ios/EditorNodeTypes.swift +37 -0
  319. package/ios/EditorStyleSheet.swift +461 -0
  320. package/ios/EditorTextView+AttributedPatch.swift +305 -0
  321. package/ios/EditorTextView+Binding.swift +61 -0
  322. package/ios/EditorTextView+Caret.swift +333 -0
  323. package/ios/EditorTextView+Commands.swift +203 -0
  324. package/ios/EditorTextView+Delegate.swift +65 -0
  325. package/ios/EditorTextView+Diagnostics.swift +225 -0
  326. package/ios/EditorTextView+DragDrop.swift +290 -0
  327. package/ios/EditorTextView+ExternalComposition.swift +364 -0
  328. package/ios/EditorTextView+Images.swift +354 -0
  329. package/ios/EditorTextView+InputTraits.swift +200 -0
  330. package/ios/EditorTextView+KeyboardInput.swift +318 -0
  331. package/ios/EditorTextView+Layout.swift +245 -0
  332. package/ios/EditorTextView+MarkedText.swift +267 -0
  333. package/ios/EditorTextView+NativeInputLifecycle.swift +372 -0
  334. package/ios/EditorTextView+NativeMutation.swift +471 -0
  335. package/ios/EditorTextView+Reconciliation.swift +97 -0
  336. package/ios/EditorTextView+RenderPatch.swift +573 -0
  337. package/ios/EditorTextView+Rendering.swift +539 -0
  338. package/ios/EditorTextView+Selection.swift +542 -0
  339. package/ios/EditorTextView.swift +953 -0
  340. package/ios/EditorTheme.swift +626 -0
  341. package/ios/EditorV2Adapter+Commands.swift +204 -0
  342. package/ios/EditorV2Adapter+Envelope.swift +238 -0
  343. package/ios/EditorV2Adapter+Mutation.swift +392 -0
  344. package/ios/EditorV2Adapter+Registry.swift +185 -0
  345. package/ios/EditorV2Adapter+RenderState.swift +360 -0
  346. package/ios/EditorV2Adapter+RenderValidation.swift +420 -0
  347. package/ios/EditorV2Adapter+Selection.swift +329 -0
  348. package/ios/EditorV2Adapter+TextCommands.swift +430 -0
  349. package/ios/EditorV2Adapter.swift +376 -0
  350. package/ios/EditorV2Shadow.swift +353 -0
  351. package/ios/Generated_editor_core.swift +2378 -0
  352. package/ios/NativeCodeHighlighting.swift +159 -0
  353. package/ios/NativeCollaborationSocket.swift +144 -0
  354. package/ios/NativeCollaborationTransport+Protocol.swift +258 -0
  355. package/ios/NativeCollaborationTransport+Socket.swift +379 -0
  356. package/ios/NativeCollaborationTransport+Validation.swift +103 -0
  357. package/ios/NativeCollaborationTransport.swift +322 -0
  358. package/ios/NativeCollaborationTransportRegistry.swift +521 -0
  359. package/ios/NativeEditorExpoView+AccessoryRetry.swift +219 -0
  360. package/ios/NativeEditorExpoView+Binding.swift +268 -0
  361. package/ios/NativeEditorExpoView+Diagnostics.swift +66 -0
  362. package/ios/NativeEditorExpoView+Events.swift +131 -0
  363. package/ios/NativeEditorExpoView+Focus.swift +169 -0
  364. package/ios/NativeEditorExpoView+MentionRetry.swift +288 -0
  365. package/ios/NativeEditorExpoView+Mentions.swift +288 -0
  366. package/ios/NativeEditorExpoView+Properties.swift +300 -0
  367. package/ios/NativeEditorExpoView+Toolbar.swift +86 -0
  368. package/ios/NativeEditorExpoView+Updates.swift +312 -0
  369. package/ios/NativeEditorExpoView.swift +349 -0
  370. package/ios/NativeEditorModule.swift +856 -0
  371. package/ios/NativeEditorViewRegistry.swift +226 -0
  372. package/ios/NativeToolbar+ButtonStyle.swift +214 -0
  373. package/ios/NativeToolbar+Buttons.swift +228 -0
  374. package/ios/NativeToolbar+Diagnostics.swift +114 -0
  375. package/ios/NativeToolbar+Menu.swift +101 -0
  376. package/ios/NativeToolbar+Models.swift +519 -0
  377. package/ios/NativeToolbar+Placeholder.swift +39 -0
  378. package/ios/NativeToolbar.swift +612 -0
  379. package/ios/OrderedListMarkerFormatter.swift +103 -0
  380. package/ios/PositionBridge.swift +596 -0
  381. package/ios/ProseViewerView.swift +462 -0
  382. package/ios/RenderBridge+Atoms.swift +288 -0
  383. package/ios/RenderBridge+Attachments.swift +246 -0
  384. package/ios/RenderBridge+BlockBoundaries.swift +313 -0
  385. package/ios/RenderBridge+Style.swift +343 -0
  386. package/ios/RenderBridge.swift +704 -0
  387. package/ios/RichTextEditorView.swift +930 -0
  388. package/ios/SharedNativeImagePipeline+Cache.swift +189 -0
  389. package/ios/SharedNativeImagePipeline+Transport.swift +328 -0
  390. package/ios/SharedNativeImagePipeline.swift +533 -0
  391. package/ios/Viewer/CoreTextProseLayoutEngine+AttributedText.swift +436 -0
  392. package/ios/Viewer/CoreTextProseLayoutEngine+Models.swift +322 -0
  393. package/ios/Viewer/CoreTextProseLayoutEngine.swift +635 -0
  394. package/ios/Viewer/Fabric/PREPPreparedProseViewerComponentView.h +4 -0
  395. package/ios/Viewer/Fabric/PREPPreparedProseViewerComponentView.mm +767 -0
  396. package/ios/Viewer/Fabric/PreparedProseMeasurementsManager.mm +118 -0
  397. package/ios/Viewer/NativeSVGImageDecoder.h +9 -0
  398. package/ios/Viewer/NativeSVGImageDecoder.mm +106 -0
  399. package/ios/Viewer/NativeSVGPreflight.h +11 -0
  400. package/ios/Viewer/NativeSVGPreflight.mm +219 -0
  401. package/ios/Viewer/PreparedProseDrawingView.swift +639 -0
  402. package/ios/Viewer/PreparedProseInstrumentation.swift +387 -0
  403. package/ios/Viewer/PreparedProseLayout.swift +326 -0
  404. package/ios/Viewer/PreparedProseLayoutCache.swift +766 -0
  405. package/ios/Viewer/PreparedProseLayoutRegistry+Artifacts.swift +377 -0
  406. package/ios/Viewer/PreparedProseLayoutRegistry+Fabric.swift +582 -0
  407. package/ios/Viewer/PreparedProseLayoutRegistry+FabricOwnership.swift +128 -0
  408. package/ios/Viewer/PreparedProseLayoutRegistry.swift +381 -0
  409. package/ios/Viewer/ViewerDocument.swift +575 -0
  410. package/ios/Viewer/ViewerFontEnvironment.swift +283 -0
  411. package/ios/Viewer/ViewerImagePipeline.swift +478 -0
  412. package/ios/editor_coreFFI/editor_coreFFI.h +1023 -0
  413. package/ios/editor_coreFFI/module.modulemap +7 -0
  414. package/package.json +151 -0
  415. package/react-native.config.js +17 -0
  416. package/rust/android/arm64-v8a/libeditor_core.so +0 -0
  417. package/rust/android/armeabi-v7a/libeditor_core.so +0 -0
  418. package/rust/android/x86/libeditor_core.so +0 -0
  419. package/rust/android/x86_64/libeditor_core.so +0 -0
  420. package/rust/bindings/kotlin/uniffi/editor_core/editor_core.kt +3146 -0
  421. package/src/AtomHost.tsx +180 -0
  422. package/src/DefaultAtomChip.tsx +27 -0
  423. package/src/EditorAddon.ts +65 -0
  424. package/src/EditorAddonNormalization.ts +49 -0
  425. package/src/EditorMentionThemeNormalization.ts +25 -0
  426. package/src/EditorMentionThemeValidation.ts +133 -0
  427. package/src/EditorStyleSheet.ts +9 -0
  428. package/src/EditorStyleSheetNormalization.ts +219 -0
  429. package/src/EditorStyleSheetTypes.ts +189 -0
  430. package/src/EditorTheme.ts +196 -0
  431. package/src/EditorToolbar.tsx +31 -0
  432. package/src/EditorToolbarComponent.tsx +23 -0
  433. package/src/EditorToolbarItems.tsx +64 -0
  434. package/src/EditorToolbarRegistry.tsx +254 -0
  435. package/src/EditorToolbarTypes.tsx +322 -0
  436. package/src/EditorToolbarVisuals.tsx +270 -0
  437. package/src/EditorUpdateRevision.ts +26 -0
  438. package/src/ExternalTextComposition.ts +658 -0
  439. package/src/ImageLoadingPolicy.ts +125 -0
  440. package/src/NativeEditorBoundaryError.ts +345 -0
  441. package/src/NativeEditorBridge.ts +93 -0
  442. package/src/NativeEditorCollaborationTransport.ts +493 -0
  443. package/src/NativeEditorCreateConfig.ts +326 -0
  444. package/src/NativeEditorCreateJson.ts +579 -0
  445. package/src/NativeEditorCreateValidation.ts +178 -0
  446. package/src/NativeEditorDocumentBridge.ts +485 -0
  447. package/src/NativeEditorDocumentHandle.ts +168 -0
  448. package/src/NativeEditorLocalAwareness.ts +168 -0
  449. package/src/NativeEditorNativeModule.ts +97 -0
  450. package/src/NativeEditorRenderNormalization.ts +320 -0
  451. package/src/NativeEditorResultNormalization.ts +469 -0
  452. package/src/NativeEditorTypes.ts +366 -0
  453. package/src/NativeEditorV2Decimal.ts +13 -0
  454. package/src/NativeProseViewer.tsx +356 -0
  455. package/src/NativeRichTextEditor.tsx +33 -0
  456. package/src/ResourceLimits.ts +187 -0
  457. package/src/RichTextEditor.tsx +27 -0
  458. package/src/RichTextEditorNativeTypes.tsx +144 -0
  459. package/src/RichTextEditorNativeView.tsx +21 -0
  460. package/src/RichTextEditorSerialization.tsx +381 -0
  461. package/src/RichTextEditorTypes.tsx +327 -0
  462. package/src/ViewerConfiguration.ts +23 -0
  463. package/src/YjsCollaboration.ts +692 -0
  464. package/src/addons.ts +311 -0
  465. package/src/atomConstants.ts +3 -0
  466. package/src/atomInstances.ts +123 -0
  467. package/src/atomPolicy.ts +47 -0
  468. package/src/atomUpdates.ts +52 -0
  469. package/src/atoms.ts +379 -0
  470. package/src/attributeValidation.ts +116 -0
  471. package/src/contentExpression.ts +338 -0
  472. package/src/index.ts +295 -0
  473. package/src/listMarkers.ts +18 -0
  474. package/src/schemaDefinition.ts +395 -0
  475. package/src/schemaDocument.ts +92 -0
  476. package/src/schemaDocumentConstruction.ts +148 -0
  477. package/src/schemaNormalization.ts +367 -0
  478. package/src/schemaPresets.ts +250 -0
  479. package/src/schemaResolution.ts +242 -0
  480. package/src/schemas.ts +43 -0
  481. package/src/specs/PreparedProseViewerNativeComponent.ts +40 -0
  482. package/src/useEditorToolbarInteractions.tsx +329 -0
  483. package/src/useEditorToolbarItems.tsx +390 -0
  484. package/src/useEditorToolbarPresentation.tsx +483 -0
  485. package/src/useEditorToolbarState.tsx +172 -0
  486. package/src/useFocusPreservingFrames.ts +171 -0
  487. package/src/useNativeEditor.ts +534 -0
  488. package/src/useRichTextEditorCommands.tsx +478 -0
  489. package/src/useRichTextEditorEvents.tsx +342 -0
  490. package/src/useRichTextEditorMentions.tsx +441 -0
  491. package/src/useRichTextEditorPresentation.tsx +563 -0
  492. package/src/useRichTextEditorState.tsx +620 -0
  493. package/src/useRichTextEditorUpdates.tsx +403 -0
  494. package/src/useViewerAtoms.tsx +427 -0
@@ -0,0 +1,1042 @@
1
+ package com.apollohg.editor
2
+
3
+ import android.content.Context
4
+ import android.graphics.Canvas
5
+ import android.graphics.Color
6
+ import android.graphics.Rect
7
+ import android.graphics.RectF
8
+ import android.text.Annotation
9
+ import android.text.Selection
10
+ import android.text.SpannableStringBuilder
11
+ import android.text.Spanned
12
+ import android.util.AttributeSet
13
+ import android.view.DragEvent
14
+ import android.view.KeyEvent
15
+ import android.view.MotionEvent
16
+ import android.view.accessibility.AccessibilityNodeInfo
17
+ import android.view.inputmethod.EditorInfo
18
+ import android.view.inputmethod.InputConnection
19
+ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
20
+
21
+ /**
22
+ * Rendering surface that routes input through [EditorV2Driver].
23
+ * IME composition is displayed transiently, then committed against the authorized selection.
24
+ * View methods and driver calls run synchronously on the main thread.
25
+ */
26
+ class EditorEditText @JvmOverloads constructor(
27
+ context: Context,
28
+ attrs: AttributeSet? = null,
29
+ defStyleAttr: Int = android.R.attr.editTextStyle
30
+ ) : EditorTextSurface(context, attrs, defStyleAttr) {
31
+
32
+ internal data class AuthoritativeInputSnapshot(
33
+ val renderedText: CharSequence,
34
+ val selectionStart: Int,
35
+ val selectionEnd: Int
36
+ )
37
+ data class ApplyUpdateTrace(
38
+ val attemptedPatch: Boolean,
39
+ val usedPatch: Boolean,
40
+ val skippedRender: Boolean,
41
+ val parseNanos: Long,
42
+ val resolveRenderBlocksNanos: Long,
43
+ val patchEligibilityNanos: Long,
44
+ val buildRenderNanos: Long,
45
+ val applyRenderNanos: Long,
46
+ val selectionNanos: Long,
47
+ val postApplyNanos: Long,
48
+ val totalNanos: Long
49
+ )
50
+
51
+ internal data class ImeInitialSurroundingText(
52
+ val text: String,
53
+ val selectionStart: Int,
54
+ val selectionEnd: Int,
55
+ val originalSelectionStart: Int,
56
+ val originalSelectionEnd: Int,
57
+ val removedPlaceholderCount: Int
58
+ )
59
+
60
+ data class SelectedImageGeometry(val docPos: Int, val rect: RectF)
61
+
62
+ data class MentionHit(
63
+ /** A Rust u32 retained in a signed [Long] without narrowing. */
64
+ val docPos: Long,
65
+ val label: String
66
+ )
67
+
68
+ data class CommandPreparation(val ready: Boolean, val updateJSON: String?)
69
+
70
+ data class ExternalEditorUpdatePreparation(
71
+ val ready: Boolean,
72
+ /** A preflight mutation's already-adopted render snapshot, if one occurred. */
73
+ val adoptedUpdateJSON: String?
74
+ )
75
+
76
+ data class LinkHit(val href: String, val text: String)
77
+
78
+ internal data class AccessibleAnnotation(
79
+ val target: AccessibleAnnotationTarget,
80
+ val label: String,
81
+ val role: String,
82
+ val bounds: Rect,
83
+ val annotation: Annotation,
84
+ val start: Int,
85
+ val end: Int
86
+ )
87
+
88
+ internal data class InteractiveAnnotationHit(
89
+ val target: AccessibleAnnotationTarget,
90
+ val annotation: Annotation,
91
+ val start: Int,
92
+ val end: Int
93
+ )
94
+
95
+ internal sealed interface AccessibleAnnotationTarget {
96
+ /** A Rust u32 retained in a signed [Long] without narrowing. */
97
+ data class Mention(val docPos: Long, val label: String) : AccessibleAnnotationTarget
98
+ data class Link(val href: String, val text: String) : AccessibleAnnotationTarget
99
+ }
100
+
101
+ /**
102
+ * Listener interface for editor events, parallel to iOS's EditorTextViewDelegate.
103
+ */
104
+ interface EditorListener {
105
+ /** Called when the editor's selection changes (anchor and head as scalar offsets). */
106
+ fun onSelectionChanged(anchor: Int, head: Int)
107
+
108
+ /** Called when the editor content is updated after a Rust operation. */
109
+ fun onEditorUpdate(updateJSON: String)
110
+
111
+ fun onExternalTextCompositionEnded(resultJson: String) = Unit
112
+ }
113
+
114
+ /** The editor session public ID (used to look up the [EditorV2Driver] adapter). */
115
+ var editorId: Long = 0
116
+
117
+ /**
118
+ * Controls whether user input is accepted.
119
+ *
120
+ * When false, all user-input mutation entry points (typing, deletion,
121
+ * paste, composition) are blocked. Unlike [isEnabled], this preserves
122
+ * focus, text selection, and copy capability.
123
+ */
124
+ var isEditable: Boolean = true
125
+ set(value) {
126
+ if (field == value) return
127
+ if (!value) {
128
+ discardTransientNativeInputForReadOnly()
129
+ }
130
+ field = value
131
+ if (value) {
132
+ restartInputForEditorIfFocused("editable")
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Guard flag to prevent re-entrant input interception while we're
138
+ * applying state from Rust (calling [setText] or modifying text storage).
139
+ */
140
+ var isApplyingRustState = false
141
+
142
+ /** Listener for editor events. */
143
+ var editorListener: EditorListener? = null
144
+ var onSelectionOrContentMayChange: (() -> Unit)? = null
145
+ var onContentSizeMayChange: (() -> Unit)? = null
146
+
147
+ /** The base font size in pixels used for unstyled text. */
148
+ internal var baseFontSize: Float = textSize
149
+
150
+ /** The base text color as an ARGB int. */
151
+ internal var baseTextColor: Int = currentTextColor
152
+
153
+ /** The base background color before theme overrides. */
154
+ internal var baseBackgroundColor: Int = android.graphics.Color.WHITE
155
+
156
+ /** Optional render theme supplied by React. */
157
+ internal val codeHighlightingSession = CodeHighlightingSession()
158
+ internal var codeHighlightingConfiguration: NativeCodeHighlightingConfig? = null
159
+ internal var reuseImagesDuringThemeUpdate = false
160
+ internal var standaloneRenderJSON: String? = null
161
+ var theme: EditorTheme? = null
162
+ internal set
163
+
164
+ internal var atomRenderConfiguration: AtomRenderConfiguration? = null
165
+ internal set
166
+ internal var atomHeightRenderApplyCount = 0
167
+
168
+ var placeholderText: String = ""
169
+ set(value) {
170
+ if (field == value) return
171
+ field = value
172
+ requestLayout()
173
+ invalidate()
174
+ }
175
+
176
+ var heightBehavior: EditorHeightBehavior = EditorHeightBehavior.FIXED
177
+ internal set
178
+
179
+ // Cached once per view instance so paired-tap tracking doesn't re-query
180
+ // ViewConfiguration on every MotionEvent.
181
+ internal val touchSlopPx: Float by lazy(LazyThreadSafetyMode.NONE) {
182
+ android.view.ViewConfiguration.get(context).scaledTouchSlop.toFloat()
183
+ }
184
+ internal var imageResizingEnabled = true
185
+ internal val decodedBitmapOwnerId: Long = DecodedBitmapBudget.nextOwnerId()
186
+ internal var imageLoadingPolicy: ImageLoadingPolicy = ImageLoadingPolicy.DEFAULT
187
+ internal set
188
+ internal var imageLoadGeneration: Long = 0L
189
+ internal val imageLoadHandles = mutableListOf<RenderImageLoader.LoadHandle>()
190
+ internal var nativeAutoCapitalize = DEFAULT_AUTO_CAPITALIZE
191
+ internal var nativeAutoCorrect = DEFAULT_AUTO_CORRECT
192
+ internal var nativeKeyboardType = DEFAULT_KEYBOARD_TYPE
193
+
194
+ internal var contentInsets: EditorContentInsets? = null
195
+ internal var viewportBottomInsetPx: Int = 0
196
+ internal var viewportBottomOcclusionTopOnScreenPx: Int? = null
197
+ internal val caretVisibilityLocationOnScreen = IntArray(2)
198
+ internal var caretVisibilityRequestPosted = false
199
+
200
+ /**
201
+ * The plain text from the last Rust-authorized render.
202
+ * Used by [ReconciliationWatcher] to detect unauthorized divergence.
203
+ */
204
+ internal var lastAuthorizedText: String = ""
205
+
206
+ /**
207
+ * Number of reconciliation events triggered during this EditText's lifetime.
208
+ * Useful for monitoring and kill-condition analysis.
209
+ */
210
+ var reconciliationCount: Int = 0
211
+ internal set
212
+
213
+ internal var lastHandledHardwareKeySignature: HardwareKeyEventSignature? = null
214
+ internal var recentHandledHardwareKeyDownSignature: HardwareKeyEventSignature? = null
215
+ internal var recentHandledHardwareKeyDownUptimeMs: Long = 0L
216
+ internal var activeInputConnection: EditorInputConnection? = null
217
+ internal var inputConnectionGeneration: Long = 0L
218
+ internal var imeTextCoordinateRevision: Long = 0L
219
+ internal var cachedImeTextCoordinateRevision: Long = -1L
220
+ internal var cachedImeTextCoordinateMapper: ImeTextCoordinateMapper? = null
221
+ internal var composingText: String? = null
222
+ internal var composingReplacementStartUtf16: Int? = null
223
+ internal var composingReplacementEndUtf16: Int? = null
224
+ internal var composingReplacementAuthorizedTextRevision: Long? = null
225
+ internal var didInvalidateCompositionReplacementRange = false
226
+ internal var externalTextComposition: ExternalTextCompositionState? = null
227
+ internal val externalCompositionMarker = Any()
228
+ internal val externalTextCompositionTerminalResults = mutableMapOf<String, String>()
229
+ internal var nativeTextMutationAfterBlurWindow: NativeTextMutationAfterBlurWindow? = null
230
+ internal var nativeTextMutationAdoptionSuppression: NativeTextMutationAdoptionSuppression? =
231
+ null
232
+ internal var lastAuthorizedTextRevision: Long = 0L
233
+ internal var lastAuthorizedRenderedText: CharSequence? = null
234
+ internal var explicitSelectedImageRange: ImageSelectionRange? = null
235
+ internal var suppressedImageSelectionHighlightColor: Int? = null
236
+ internal var pendingImageGesture: ImageGesture? = null
237
+ internal var lastRenderAppliedPatchForTesting: Boolean = false
238
+ internal var captureApplyUpdateTraceForTesting: Boolean = false
239
+ internal var lastApplyUpdateTraceForTesting: ApplyUpdateTrace? = null
240
+ internal val imeTraceForTesting = java.util.ArrayDeque<String>()
241
+ internal var imeTraceSequence: Long = 0L
242
+ internal var lastImeTraceUptimeMs: Long = 0L
243
+ internal var currentRenderBlocksJson: org.json.JSONArray? = null
244
+ internal var currentRenderBlocksDocumentVersion: String? = null
245
+ internal var currentRenderBlocksNeedFullApply = false
246
+ internal var authorizedVisibleTextNeedsRebuild = false
247
+ internal var logicalSelectionSnapshot: LogicalSelectionSnapshot? = null
248
+ internal var lastAllowedAtomCaretSelection: Pair<Int, Int>? = null
249
+ private var localTextDrag: LocalTextDrag? = null
250
+ internal var lastAppliedDocumentVersion: String? = null
251
+ internal var restartImageLoadsOnAttach = false
252
+ internal var renderAppearanceRevision: Long = 1L
253
+ internal var lastAppliedRenderAppearanceRevision: Long = 0L
254
+ internal var pendingOptimisticRenderText: String? = null
255
+ internal var deferredRustUpdateApplicationDepth: Int = 0
256
+ internal var deferredRustUpdateJSON: String? = null
257
+ internal var deferredRustUpdateLineBoundaryRefreshSource: String? = null
258
+ internal var deferredRustUpdateGeneration: Long = 0L
259
+ internal var recoveringRenderPatchBaseMismatch = false
260
+ internal var externalUpdatePreparationCaptureDepth: Int = 0
261
+ internal var capturedExternalUpdatePreparationJSON: String? = null
262
+ internal var lineBoundaryInputRefreshGeneration: Long = 0L
263
+ internal var restartInputSelectionUpdateGeneration: Long = 0L
264
+ internal var onDeleteRangeInRustForTesting: ((Int, Int) -> Unit)? = null
265
+ internal var onDeleteBackwardAtSelectionScalarInRustForTesting: ((Int, Int) -> Unit)? = null
266
+ internal var onToggleTaskItemCheckedAtSelectionScalarInRustForTesting: (
267
+ (
268
+ Int,
269
+ Int
270
+ ) -> Unit
271
+ )? = null
272
+ internal var onInsertTextInRustForTesting: ((String, Int) -> Unit)? = null
273
+ internal var onSplitBlockInRustForTesting: ((Int) -> Unit)? = null
274
+ internal var onReplaceTextInRustForTesting: ((Int, Int, String) -> Unit)? = null
275
+ internal var onSetSelectionScalarInRustForTesting: ((Int, Int) -> Unit)? = null
276
+ internal var onDeleteAndSplitScalarInRustForTesting: ((Int, Int) -> Unit)? = null
277
+ internal var onInsertContentHtmlInRustForTesting: ((String) -> Unit)? = null
278
+ internal var onResizeImageAtDocPosForTesting: ((Int, Int, Int) -> Unit)? = null
279
+ internal var onMoveSelectionScalarForTesting: ((Int, Int, Int) -> Unit)? = null
280
+ internal var onBeforeRenderRefresh: (() -> Unit)? = null
281
+ internal var blockExternalEditorUpdatePreparationForTesting = false
282
+ internal var blockExternalEditorCommandPreparationForTesting = false
283
+ internal var throwOnNextApplyUpdateForTesting: Throwable? = null
284
+
285
+ /**
286
+ * The v2 driver for this editor session: when an adapter is attached,
287
+ * every engine mutation below routes through it (typed v2
288
+ * transactions/results). It is the ONLY engine path — a null driver
289
+ * means the view has no engine traffic.
290
+ */
291
+ internal var v2Driver: EditorV2Driver? = null
292
+ set(value) {
293
+ if (field === value) return
294
+ (field as? EditorV2Adapter)?.releaseNativeBindingOwner(nativeBindingToken)
295
+ field = value
296
+ invalidateCurrentRenderBlocks()
297
+ (value as? EditorV2Adapter)?.claimNativeBindingIfUnowned(nativeBindingToken)
298
+ }
299
+ internal val nativeBindingToken = nextNativeBindingToken.incrementAndGet()
300
+
301
+ internal fun ownsNativeBinding(adapter: EditorV2Adapter): Boolean =
302
+ ownsNativeBindingImpl(adapter)
303
+
304
+ fun lastRenderAppliedPatch(): Boolean = lastRenderAppliedPatchImpl()
305
+
306
+ fun lastApplyUpdateTrace(): ApplyUpdateTrace? = lastApplyUpdateTraceImpl()
307
+
308
+ internal fun hasDeferredRustUpdateApplicationForTesting(): Boolean =
309
+ hasDeferredRustUpdateApplicationForTestingImpl()
310
+
311
+ internal fun inputConnectionGenerationForTesting(): Long =
312
+ inputConnectionGenerationForTestingImpl()
313
+
314
+ internal fun authorizedTextForTesting(): String = authorizedTextForTestingImpl()
315
+
316
+ internal fun applyRustUpdateJSONForTesting(updateJSON: String) =
317
+ applyRustUpdateJSONForTestingImpl(updateJSON)
318
+
319
+ internal fun recordImeTraceForTesting(event: String, details: String = "") =
320
+ recordImeTraceForTestingImpl(event, details)
321
+
322
+ internal fun clearImeTraceForTesting() = clearImeTraceForTestingImpl()
323
+
324
+ internal fun imeTraceSnapshotForTesting(): List<String> = imeTraceSnapshotForTestingImpl()
325
+
326
+ init {
327
+ initializeEditorView()
328
+ }
329
+
330
+ internal val legacyCursorClipPaint = android.graphics.Paint(
331
+ android.graphics.Paint.ANTI_ALIAS_FLAG
332
+ )
333
+ internal val caretWidthPx: Float by lazy { resolveCaretWidth(attrs, defStyleAttr) }
334
+ internal val caretColor: Int by lazy { resolveCaretColor() }
335
+ internal var editorAccessibilityHint: CharSequence? = null
336
+
337
+ fun setEditorAccessibilityHint(hint: CharSequence?) = setEditorAccessibilityHintImpl(hint)
338
+
339
+ override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo) {
340
+ super.onInitializeAccessibilityNodeInfo(info)
341
+ AccessibilityNodeInfoCompat.wrap(info).tooltipText = editorAccessibilityHint
342
+ }
343
+
344
+ internal fun nativeCursorDrawRect(): RectF? = nativeCursorDrawRectImpl()
345
+
346
+ fun setAutoCapitalize(autoCapitalize: String?) = setAutoCapitalizeImpl(autoCapitalize)
347
+
348
+ fun setAutoCorrect(autoCorrect: Boolean?) = setAutoCorrectImpl(autoCorrect)
349
+
350
+ fun setKeyboardType(keyboardType: String?) = setKeyboardTypeImpl(keyboardType)
351
+
352
+ fun setPrivateImeOptionsForEditor(value: String?) = setPrivateImeOptionsForEditorImpl(value)
353
+
354
+ /**
355
+ * Create a custom [EditorInputConnection] that intercepts all input
356
+ * from the soft keyboard.
357
+ */
358
+ override fun onSurfaceInputStateChanged() {
359
+ activeInputConnection?.publishInputStateIfNeeded()
360
+ }
361
+
362
+ override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? {
363
+ val baseConnection = super.onCreateInputConnection(outAttrs) ?: return null
364
+ return configureInputConnection(baseConnection, outAttrs)
365
+ }
366
+
367
+ override fun dispatchKeyEvent(event: KeyEvent): Boolean {
368
+ if (!isEditable && isReadOnlyTextMutationKeyEvent(event)) {
369
+ return true
370
+ }
371
+ if (!commitExternalTextCompositionBeforeInteractionIfNeeded()) return true
372
+ if (handleCompositionKeyEvent(event) { super.dispatchKeyEvent(event) }) {
373
+ return true
374
+ }
375
+ if (handleHardwareKeyEvent(event)) {
376
+ return true
377
+ }
378
+ if (handlePrintableHardwareKeyEvent(event) { super.dispatchKeyEvent(event) }) {
379
+ return true
380
+ }
381
+ return super.dispatchKeyEvent(event)
382
+ }
383
+
384
+ internal fun handleCompositionKeyEvent(
385
+ event: KeyEvent,
386
+ applyBaseEvent: () -> Boolean
387
+ ): Boolean = handleCompositionKeyEventImpl(event, applyBaseEvent)
388
+
389
+ override fun onDraw(canvas: android.graphics.Canvas) {
390
+ updateAtomBoundaryCursorVisibility()
391
+ drawStyleSheetBoxes(canvas)
392
+ super.onDraw(canvas)
393
+ layout?.let {
394
+ val saved = canvas.save()
395
+ canvas.translate(compoundPaddingLeft.toFloat(), extendedPaddingTop.toFloat())
396
+ EditorTextDecorationDrawing.draw(canvas, it)
397
+ canvas.restoreToCount(saved)
398
+ }
399
+
400
+ val placeholderLayout =
401
+ buildPlaceholderLayout(width - compoundPaddingLeft - compoundPaddingRight) ?: return
402
+
403
+ val previousColor = paint.color
404
+ val saveCount = canvas.save()
405
+ val placeholderInsets =
406
+ placeholderContentInsets(width - compoundPaddingLeft - compoundPaddingRight)
407
+ canvas.translate(
408
+ compoundPaddingLeft + placeholderInsets.left,
409
+ extendedPaddingTop + placeholderInsets.top
410
+ )
411
+ placeholderLayout.draw(canvas)
412
+ EditorTextDecorationDrawing.draw(canvas, placeholderLayout)
413
+ canvas.restoreToCount(saveCount)
414
+ paint.color = previousColor
415
+ }
416
+
417
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
418
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec)
419
+
420
+ val placeholderHeight = resolvePlaceholderHeightForMeasuredWidth(measuredWidth) ?: 0
421
+ val desiredHeight = maxOf(
422
+ measuredHeight,
423
+ placeholderHeight
424
+ )
425
+ val resolvedHeight = when (MeasureSpec.getMode(heightMeasureSpec)) {
426
+ MeasureSpec.EXACTLY -> measuredHeight
427
+
428
+ MeasureSpec.AT_MOST -> desiredHeight.coerceAtMost(
429
+ MeasureSpec.getSize(heightMeasureSpec)
430
+ )
431
+
432
+ else -> desiredHeight
433
+ }
434
+
435
+ if (resolvedHeight != measuredHeight) {
436
+ setMeasuredDimension(measuredWidth, resolvedHeight)
437
+ }
438
+ }
439
+
440
+ override fun onTouchEvent(event: MotionEvent): Boolean {
441
+ if (event.actionMasked == MotionEvent.ACTION_DOWN &&
442
+ imageSpanHitAt(event.x, event.y) == null
443
+ ) {
444
+ clearExplicitSelectedImageRange()
445
+ }
446
+ if (handleTaskListMarkerTap(event)) {
447
+ // End the text gesture so its pending long press cannot select the marker.
448
+ val cancel = MotionEvent.obtain(event)
449
+ cancel.action = MotionEvent.ACTION_CANCEL
450
+ super.onTouchEvent(cancel)
451
+ cancel.recycle()
452
+ parent?.requestDisallowInterceptTouchEvent(false)
453
+ return true
454
+ }
455
+ if (handleImageTap(event)) {
456
+ return true
457
+ }
458
+ if (heightBehavior == EditorHeightBehavior.FIXED && !interaction.hasScrollContainer()) {
459
+ val canScroll = canScrollVertically(-1) || canScrollVertically(1)
460
+ if (canScroll) {
461
+ when (event.actionMasked) {
462
+ MotionEvent.ACTION_DOWN,
463
+ MotionEvent.ACTION_MOVE -> parent?.requestDisallowInterceptTouchEvent(true)
464
+
465
+ MotionEvent.ACTION_UP,
466
+ MotionEvent.ACTION_CANCEL -> parent?.requestDisallowInterceptTouchEvent(false)
467
+ }
468
+ }
469
+ }
470
+ return super.onTouchEvent(event)
471
+ }
472
+
473
+ override fun onDragEvent(event: DragEvent): Boolean = when (event.action) {
474
+ DragEvent.ACTION_DRAG_STARTED -> {
475
+ val drag = localTextDragFor(event)
476
+ localTextDrag = drag
477
+ drag != null || super.onDragEvent(event)
478
+ }
479
+
480
+ DragEvent.ACTION_DROP -> {
481
+ val drag = localTextDrag
482
+ localTextDrag = null
483
+ if (drag == null) {
484
+ super.onDragEvent(event)
485
+ } else {
486
+ val currentText = text?.toString().orEmpty()
487
+ val destinationUtf16 = getOffsetForPosition(event.x, event.y)
488
+ .coerceIn(0, currentText.length)
489
+ val destination = PositionBridge.utf16ToScalar(destinationUtf16, currentText)
490
+ performLocalSelectionDrop(drag, destination) || super.onDragEvent(event)
491
+ }
492
+ }
493
+
494
+ DragEvent.ACTION_DRAG_ENDED -> {
495
+ val handled = localTextDrag != null
496
+ localTextDrag = null
497
+ super.onDragEvent(event) || handled
498
+ }
499
+
500
+ DragEvent.ACTION_DRAG_ENTERED,
501
+ DragEvent.ACTION_DRAG_LOCATION,
502
+ DragEvent.ACTION_DRAG_EXITED -> super.onDragEvent(event) || localTextDrag != null
503
+
504
+ else -> super.onDragEvent(event)
505
+ }
506
+
507
+ internal fun performLocalSelectionDropForTesting(
508
+ scalarFrom: Int,
509
+ scalarTo: Int,
510
+ destination: Int,
511
+ documentVersion: String?
512
+ ): Boolean =
513
+ performLocalSelectionDropForTestingImpl(scalarFrom, scalarTo, destination, documentVersion)
514
+
515
+ override fun performClick(): Boolean = super.performClick()
516
+
517
+ /**
518
+ * The core's `documentIsEmpty` from the most recent editor update, or null
519
+ * when the current render arrived without one.
520
+ */
521
+ internal var coreReportedDocumentIsEmpty: Boolean? = null
522
+
523
+ /** Adopt the core's authoritative empty state from an editor update. */
524
+ fun setCoreReportedDocumentIsEmpty(isEmpty: Boolean?) =
525
+ setCoreReportedDocumentIsEmptyImpl(isEmpty)
526
+
527
+ fun shouldDisplayPlaceholderForTesting(): Boolean = shouldDisplayPlaceholderForTestingImpl()
528
+
529
+ /**
530
+ * Bind this EditText to a Rust editor instance and optionally apply initial content.
531
+ *
532
+ * @param id The editor session public ID.
533
+ * @param initialHTML Optional HTML to set as initial content.
534
+ */
535
+ fun bindEditor(id: Long, initialHTML: String? = null, notifyListener: Boolean = true) =
536
+ bindEditorImpl(id, initialHTML, notifyListener)
537
+
538
+ /**
539
+ * Unbind from the current editor instance.
540
+ */
541
+ fun unbindEditor() = unbindEditorImpl()
542
+
543
+ internal fun handleEditorDestroyedFromRegistry(destroyedEditorId: Long) =
544
+ handleEditorDestroyedFromRegistryImpl(destroyedEditorId)
545
+
546
+ fun setBaseStyle(fontSizePx: Float, textColor: Int, backgroundColor: Int) =
547
+ setBaseStyleImpl(fontSizePx, textColor, backgroundColor)
548
+
549
+ fun applyTheme(theme: EditorTheme?) = applyThemeImpl(theme)
550
+
551
+ fun applyAtomRenderConfiguration(configuration: AtomRenderConfiguration?): Boolean =
552
+ applyAtomRenderConfigurationImpl(configuration)
553
+
554
+ internal fun applyAtomHeight(
555
+ atomKey: String,
556
+ heightPx: Int,
557
+ configuration: AtomRenderConfiguration?
558
+ ): Boolean = applyAtomHeightImpl(atomKey, heightPx, configuration)
559
+
560
+ internal fun atomHeightRenderApplyCountForTesting(): Int =
561
+ atomHeightRenderApplyCountForTestingImpl()
562
+
563
+ fun setHeightBehavior(heightBehavior: EditorHeightBehavior) =
564
+ setHeightBehaviorImpl(heightBehavior)
565
+
566
+ fun setViewportBottomInsetPx(bottomInsetPx: Int) = setViewportBottomInsetPxImpl(bottomInsetPx)
567
+
568
+ fun setViewportBottomOcclusionTopOnScreenPx(topPx: Int?) =
569
+ setViewportBottomOcclusionTopOnScreenPxImpl(topPx)
570
+
571
+ fun setImageResizingEnabled(enabled: Boolean) = setImageResizingEnabledImpl(enabled)
572
+
573
+ fun setImageLoadingPolicyJson(policyJson: String?) = setImageLoadingPolicyJsonImpl(policyJson)
574
+
575
+ internal fun currentImageLoadGeneration(): Long = currentImageLoadGenerationImpl()
576
+
577
+ internal fun registerImageLoad(handle: RenderImageLoader.LoadHandle) =
578
+ registerImageLoadImpl(handle)
579
+
580
+ internal fun activeImageLoadHandleCountForTesting(): Int =
581
+ activeImageLoadHandleCountForTestingImpl()
582
+
583
+ internal fun onImageSpanSizeMayChange(span: BlockImageSpan) = onImageSpanSizeMayChangeImpl(span)
584
+
585
+ fun resolveAutoGrowHeight(): Int = resolveAutoGrowHeightImpl()
586
+
587
+ internal fun caretRect(): RectF? = caretRectImpl()
588
+
589
+ /**
590
+ * Handle committed text from the IME (typed characters, autocomplete).
591
+ *
592
+ * Called by [EditorInputConnection.commitText]. Routes the text through
593
+ * the Rust editor instead of directly inserting into the EditText.
594
+ */
595
+ fun handleTextCommit(text: String, newCursorPosition: Int = 1) =
596
+ handleTextCommitImpl(text, newCursorPosition)
597
+
598
+ internal fun runWithTransientInputMutationGuard(block: () -> Boolean): Boolean =
599
+ runWithTransientInputMutationGuardImpl(block)
600
+
601
+ fun beginExternalTextComposition(sessionId: String): String =
602
+ beginExternalTextCompositionImpl(sessionId)
603
+
604
+ fun updateExternalTextComposition(sessionId: String, text: String): String =
605
+ updateExternalTextCompositionImpl(sessionId, text)
606
+
607
+ fun commitExternalTextComposition(sessionId: String, finalText: String): String =
608
+ commitExternalTextCompositionImpl(sessionId, finalText)
609
+
610
+ fun cancelExternalTextComposition(sessionId: String, cause: String): String =
611
+ cancelExternalTextCompositionImpl(sessionId, cause)
612
+
613
+ internal fun commitExternalTextCompositionBeforeInteractionIfNeeded(): Boolean =
614
+ commitExternalTextCompositionBeforeInteractionIfNeededImpl()
615
+
616
+ internal fun hasActiveExternalTextCompositionForEditor(): Boolean =
617
+ hasActiveExternalTextCompositionForEditorImpl()
618
+
619
+ internal fun authorizedUtf16Range(start: Int, end: Int): Pair<Int, Int> =
620
+ authorizedUtf16RangeImpl(start, end)
621
+
622
+ internal fun isCurrentTextAuthorizedForEditor(): Boolean =
623
+ isCurrentTextAuthorizedForEditorImpl()
624
+
625
+ internal fun captureCompositionReplacementRangeIfNeeded() =
626
+ captureCompositionReplacementRangeIfNeededImpl()
627
+
628
+ internal fun setCompositionReplacementRange(start: Int, end: Int) =
629
+ setCompositionReplacementRangeImpl(start, end)
630
+
631
+ internal fun compositionReplacementRange(): Pair<Int, Int>? = compositionReplacementRangeImpl()
632
+
633
+ internal fun consumeInvalidatedCompositionReplacementRangeForEditor(): Boolean =
634
+ consumeInvalidatedCompositionReplacementRangeForEditorImpl()
635
+
636
+ internal fun hasInvalidatedCompositionReplacementRangeForEditor(): Boolean =
637
+ hasInvalidatedCompositionReplacementRangeForEditorImpl()
638
+
639
+ internal fun setComposingTextForEditor(text: String?) = setComposingTextForEditorImpl(text)
640
+
641
+ internal fun composingTextForEditor(): String? = composingTextForEditorImpl()
642
+
643
+ internal fun samsungSentenceCapsComposingTextForEditor(composingText: String?): String? =
644
+ samsungSentenceCapsComposingTextForEditorImpl(composingText)
645
+
646
+ internal fun applyTransientComposingTextStyleForEditor() =
647
+ applyTransientComposingTextStyleForEditorImpl()
648
+
649
+ internal fun composingTextFromVisibleReplacementForEditor(): String? =
650
+ composingTextFromVisibleReplacementForEditorImpl()
651
+
652
+ internal fun clearCompositionTrackingForEditor() = clearCompositionTrackingForEditorImpl()
653
+
654
+ internal fun retireInputConnectionForHostDetach() = retireInputConnectionForHostDetachImpl()
655
+
656
+ internal fun isEditorDestroyedForInput(): Boolean = isEditorDestroyedForInputImpl()
657
+
658
+ internal fun isInputConnectionCurrentForEditor(
659
+ boundEditorId: Long,
660
+ boundGeneration: Long
661
+ ): Boolean = isInputConnectionCurrentForEditorImpl(boundEditorId, boundGeneration)
662
+
663
+ internal fun imeTextCoordinateMapperForEditor(
664
+ boundGeneration: Long = inputConnectionGeneration
665
+ ): ImeTextCoordinateMapper? = imeTextCoordinateMapperForEditorImpl(boundGeneration)
666
+
667
+ internal fun restoreAuthorizedTextIfNeeded() = restoreAuthorizedTextIfNeededImpl()
668
+
669
+ fun discardTransientNativeInputForEditorRebind() =
670
+ discardTransientNativeInputForEditorRebindImpl()
671
+
672
+ internal fun discardTransientNativeInputForExternalRecovery() =
673
+ discardTransientNativeInputForExternalRecoveryImpl()
674
+
675
+ fun prepareForExternalEditorUpdate(): Boolean = prepareForExternalEditorUpdateImpl()
676
+
677
+ /**
678
+ * Performs external-update preflight while retaining a mutation snapshot
679
+ * for the caller that will apply it. This prevents a second state render
680
+ * after a composing commit has already produced and adopted one.
681
+ */
682
+ internal fun hasPendingCompositionForExternalRefresh(): Boolean =
683
+ hasPendingCompositionForExternalRefreshImpl()
684
+
685
+ fun prepareForExternalEditorUpdateWithResult(): ExternalEditorUpdatePreparation =
686
+ prepareExternalUpdateWithResultImpl()
687
+
688
+ fun prepareForExternalEditorCommand(): CommandPreparation =
689
+ prepareForExternalEditorCommandImpl()
690
+
691
+ fun handleCompositionCommit(
692
+ text: String,
693
+ replacementStartUtf16: Int,
694
+ replacementEndUtf16: Int,
695
+ newCursorPosition: Int = 1
696
+ ) = handleCompositionCommitImpl(
697
+ text,
698
+ replacementStartUtf16,
699
+ replacementEndUtf16,
700
+ newCursorPosition
701
+ )
702
+
703
+ fun handleCorrectionCommit(
704
+ startUtf16: Int,
705
+ endUtf16: Int,
706
+ renderedOldText: String,
707
+ newText: String
708
+ ): Boolean = handleCorrectionCommitImpl(startUtf16, endUtf16, renderedOldText, newText)
709
+
710
+ fun handleMissingOldTextCorrectionCommit(
711
+ startUtf16: Int,
712
+ endUtf16: Int,
713
+ renderedOldText: String,
714
+ newText: String
715
+ ): Boolean =
716
+ handleMissingOldTextCorrectionCommitImpl(startUtf16, endUtf16, renderedOldText, newText)
717
+
718
+ internal fun missingOldTextCorrectionTokenRangeForEditor(
719
+ text: String,
720
+ offsetUtf16: Int
721
+ ): Pair<Int, Int>? = missingOldTextCorrectionTokenRangeForEditorImpl(text, offsetUtf16)
722
+
723
+ /**
724
+ * Handle surrounding text deletion from the IME.
725
+ *
726
+ * Called by [EditorInputConnection.deleteSurroundingText].
727
+ *
728
+ * @param beforeLength Number of UTF-16 code units to delete before the cursor.
729
+ * @param afterLength Number of UTF-16 code units to delete after the cursor.
730
+ */
731
+ fun handleDelete(beforeLength: Int, afterLength: Int) =
732
+ handleDeleteImpl(beforeLength, afterLength)
733
+
734
+ /**
735
+ * Handle backspace key press (hardware keyboard or key event).
736
+ *
737
+ * If there's a range selection, deletes the range. Otherwise deletes
738
+ * the grapheme cluster before the cursor.
739
+ */
740
+ fun handleBackspace() = handleBackspaceImpl()
741
+
742
+ fun handleForwardDelete() = handleForwardDeleteImpl()
743
+
744
+ /**
745
+ * Handle return/enter key as a block split operation.
746
+ */
747
+ fun handleReturnKey() = handleReturnKeyImpl()
748
+
749
+ /**
750
+ * Handle Shift+Enter as an inline hard break insertion.
751
+ */
752
+ fun handleHardBreak() = handleHardBreakImpl()
753
+
754
+ /**
755
+ * Handle hardware Tab / Shift+Tab as list indent / outdent when the caret is in a list.
756
+ */
757
+ fun handleTab(shiftPressed: Boolean): Boolean = handleTabImpl(shiftPressed)
758
+
759
+ fun handleHardwareKeyDown(keyCode: Int, shiftPressed: Boolean): Boolean =
760
+ handleHardwareKeyDownImpl(keyCode, shiftPressed)
761
+
762
+ internal fun isReadOnlyTextMutationKeyEvent(event: KeyEvent): Boolean =
763
+ isReadOnlyTextMutationKeyEventImpl(event)
764
+
765
+ fun handleHardwareKeyEvent(event: KeyEvent?): Boolean = handleHardwareKeyEventImpl(event)
766
+
767
+ internal fun handlePrintableHardwareKeyEvent(
768
+ event: KeyEvent,
769
+ applyBaseEvent: () -> Boolean
770
+ ): Boolean = handlePrintableHardwareKeyEventImpl(event, applyBaseEvent)
771
+
772
+ fun performToolbarToggleMark(markName: String) = performToolbarToggleMarkImpl(markName)
773
+
774
+ fun performToolbarToggleList(listType: String, isActive: Boolean) =
775
+ performToolbarToggleListImpl(listType, isActive)
776
+
777
+ fun performToolbarToggleBlockquote() = performToolbarToggleBlockquoteImpl()
778
+
779
+ fun performToolbarToggleHeading(level: Int) = performToolbarToggleHeadingImpl(level)
780
+
781
+ fun performToolbarIndentListItem() = performToolbarIndentListItemImpl()
782
+
783
+ fun performToolbarOutdentListItem() = performToolbarOutdentListItemImpl()
784
+
785
+ fun performToolbarInsertNode(nodeType: String) = performToolbarInsertNodeImpl(nodeType)
786
+
787
+ fun performToolbarUndo() = performToolbarUndoImpl()
788
+
789
+ fun performToolbarRedo() = performToolbarRedoImpl()
790
+
791
+ /**
792
+ * Intercept paste operations to route content through Rust.
793
+ *
794
+ * Attempts to extract HTML from the clipboard first (for rich text paste),
795
+ * falling back to plain text.
796
+ */
797
+ override fun onTextContextMenuItem(id: Int): Boolean {
798
+ if (!isEditable && isMutatingContextMenuItem(id)) return true
799
+ if (id == android.R.id.cut) {
800
+ handleCut()
801
+ return true
802
+ }
803
+ if (id == android.R.id.paste || id == android.R.id.pasteAsPlainText) {
804
+ handlePaste(plainTextOnly = id == android.R.id.pasteAsPlainText)
805
+ return true
806
+ }
807
+ return super.onTextContextMenuItem(id)
808
+ }
809
+
810
+ /**
811
+ * Block accessibility-initiated text mutations (paste, cut, set text) when not editable.
812
+ * Selection and copy actions remain available.
813
+ */
814
+ override fun performAccessibilityAction(action: Int, arguments: android.os.Bundle?): Boolean {
815
+ if (!isEditable && (
816
+ action == android.view.accessibility.AccessibilityNodeInfo.ACTION_SET_TEXT ||
817
+ action == android.view.accessibility.AccessibilityNodeInfo.ACTION_PASTE ||
818
+ action == android.view.accessibility.AccessibilityNodeInfo.ACTION_CUT
819
+ )
820
+ ) {
821
+ return false
822
+ }
823
+ if (action == android.view.accessibility.AccessibilityNodeInfo.ACTION_SET_TEXT) {
824
+ return handleAccessibilitySetText(arguments)
825
+ }
826
+ return super.performAccessibilityAction(action, arguments)
827
+ }
828
+
829
+ /**
830
+ * Override to notify the listener when selection changes.
831
+ *
832
+ * Converts the EditText selection to scalar offsets and notifies both
833
+ * the listener and the Rust editor.
834
+ */
835
+ override fun onSelectionChanged(selStart: Int, selEnd: Int) {
836
+ super.onSelectionChanged(selStart, selEnd)
837
+ updateImageSelectionHighlightAppearance(selStart, selEnd)
838
+ if (restoreSelectionFromAtomBoundaryIfNeeded(selStart, selEnd)) return
839
+ canonicalListCaretOffset(selStart, selEnd)?.let { canonicalOffset ->
840
+ setSelection(canonicalOffset)
841
+ return
842
+ }
843
+ ensureSelectionVisible()
844
+ if (isApplyingRustState) return
845
+ val wasExternallyComposing = externalTextComposition != null
846
+ if (!commitExternalTextCompositionBeforeInteractionIfNeeded()) return
847
+ if (wasExternallyComposing) {
848
+ val editable = text
849
+ if (editable != null) {
850
+ val restoredStart = selStart.coerceIn(0, editable.length)
851
+ val restoredEnd = selEnd.coerceIn(0, editable.length)
852
+ if (selectionStart != restoredStart || selectionEnd != restoredEnd) {
853
+ runWithTransientInputMutationGuard {
854
+ Selection.setSelection(editable, restoredStart, restoredEnd)
855
+ true
856
+ }
857
+ }
858
+ }
859
+ }
860
+ val spannable = text as? Spanned
861
+ if (spannable != null && isExactImageSpanRange(spannable, selStart, selEnd)) {
862
+ explicitSelectedImageRange = ImageSelectionRange(selStart, selEnd)
863
+ }
864
+ onSelectionOrContentMayChange?.invoke()
865
+
866
+ syncCurrentSelectionToRust()
867
+ }
868
+
869
+ // Samsung Keyboard may call finishComposingText() and then commitText(" ")
870
+ // for one space tap. Defer the render from finishComposingText() by one
871
+ // loop so setText() does not restart input before the pending space arrives.
872
+ internal fun runWithDeferredRustUpdateApplication(block: () -> Unit) =
873
+ runWithDeferredRustUpdateApplicationImpl(block)
874
+
875
+ internal fun authorizeCurrentVisibleTextForPendingImeOperationForEditor(
876
+ logicalCursorAfter: Int? = null
877
+ ) = authorizeCurrentVisibleTextForPendingImeOperationForEditorImpl(logicalCursorAfter)
878
+
879
+ internal fun captureAuthoritativeInputSnapshotForEditor(): AuthoritativeInputSnapshot =
880
+ captureAuthoritativeInputSnapshotImpl()
881
+
882
+ internal fun deleteScalarRangeForPendingImeOperationForEditor(
883
+ scalarFrom: Int,
884
+ scalarTo: Int
885
+ ): EditorV2NativeIntentResult? =
886
+ deleteScalarRangeForPendingImeOperationForEditorImpl(scalarFrom, scalarTo)
887
+
888
+ internal fun promoteOptimisticInputForEditor(
889
+ render: EditorV2NativeMutationRender,
890
+ logicalCursorAfter: Int
891
+ ) = promoteOptimisticInputForEditorImpl(render, logicalCursorAfter)
892
+
893
+ internal fun restoreAuthoritativeInputForEditor(
894
+ snapshot: AuthoritativeInputSnapshot,
895
+ recoveryUpdateJson: String? = null
896
+ ) = restoreAuthoritativeInputForEditorImpl(snapshot, recoveryUpdateJson)
897
+
898
+ internal fun handleStructuralBackspace() = handleStructuralBackspaceImpl()
899
+
900
+ internal fun handleStructuralDelete(
901
+ utf16From: Int,
902
+ utf16To: Int,
903
+ scalarFrom: Int,
904
+ scalarTo: Int
905
+ ) = handleStructuralDeleteImpl(utf16From, utf16To, scalarFrom, scalarTo)
906
+
907
+ internal fun applyVisibleCompositionCommitForPendingImeOperationForEditor(
908
+ committedText: String,
909
+ replacementStartUtf16: Int,
910
+ replacementEndUtf16: Int,
911
+ newCursorPosition: Int
912
+ ): Boolean = applyVisibleCompositionCommitForPendingImeOperationForEditorImpl(
913
+ committedText,
914
+ replacementStartUtf16,
915
+ replacementEndUtf16,
916
+ newCursorPosition
917
+ )
918
+
919
+ internal fun commitVisibleCompositionMutationForPendingImeOperation(
920
+ committedText: String,
921
+ newCursorPosition: Int
922
+ ): Boolean = commitVisibleCompositionMutationForPendingImeOperationImpl(
923
+ committedText,
924
+ newCursorPosition
925
+ )
926
+
927
+ internal fun currentScalarSelection(): Pair<Int, Int>? = currentScalarSelectionImpl()
928
+
929
+ internal fun currentLogicalScalarSelectionForInput(): Pair<Int, Int>? =
930
+ currentLogicalScalarSelectionForInputImpl()
931
+
932
+ internal fun renderedRangeContainsGeneratedStructure(start: Int, endExclusive: Int): Boolean =
933
+ renderedRangeContainsGeneratedStructureImpl(start, endExclusive)
934
+
935
+ internal fun compositionContentRangeForEditor(start: Int, end: Int): Pair<Int, Int>? =
936
+ compositionContentRangeForEditorImpl(start, end)
937
+
938
+ internal fun cursorCapsModeForEditor(reqModes: Int, baseCapsMode: Int): Int =
939
+ cursorCapsModeForEditorImpl(reqModes, baseCapsMode)
940
+
941
+ internal fun initialSurroundingTextForImeForEditor(
942
+ mapper: ImeTextCoordinateMapper? = null
943
+ ): ImeInitialSurroundingText? = initialSurroundingTextForImeForEditorImpl(mapper)
944
+
945
+ fun selectedImageGeometry(): SelectedImageGeometry? = selectedImageGeometryImpl()
946
+
947
+ fun resizeImageAtDocPos(docPos: Int, widthPx: Float, heightPx: Float) =
948
+ resizeImageAtDocPosImpl(docPos, widthPx, heightPx)
949
+
950
+ /**
951
+ * Apply a full render update from Rust to the EditText.
952
+ *
953
+ * Parses the update JSON, converts render elements to [android.text.SpannableStringBuilder]
954
+ * via [RenderBridge], and replaces the EditText's content.
955
+ *
956
+ * @param updateJSON The JSON string from an [EditorV2Driver] transaction result.
957
+ */
958
+ fun applyUpdateJSON(
959
+ updateJSON: String,
960
+ notifyListener: Boolean = true,
961
+ refreshInputConnectionForExternalUpdate: Boolean = false
962
+ ): Boolean =
963
+ applyUpdateJSONImpl(updateJSON, notifyListener, refreshInputConnectionForExternalUpdate)
964
+
965
+ /**
966
+ * Apply a render JSON string (just render elements, no update wrapper).
967
+ *
968
+ * Used for initial content loading (set_html / set_json return render
969
+ * elements directly, not wrapped in an EditorUpdate).
970
+ *
971
+ * @param renderJSON The JSON array string of render elements.
972
+ */
973
+ fun applyRenderJSON(renderJSON: String) = applyRenderJSONImpl(renderJSON)
974
+
975
+ fun mentionHitAt(x: Float, y: Float): MentionHit? = mentionHitAtImpl(x, y)
976
+
977
+ fun linkHitAt(x: Float, y: Float): LinkHit? = linkHitAtImpl(x, y)
978
+
979
+ internal fun accessibleAnnotations(): List<AccessibleAnnotation> = accessibleAnnotationsImpl()
980
+
981
+ internal fun interactiveAnnotationHitAt(x: Float, y: Float): InteractiveAnnotationHit? =
982
+ interactiveAnnotationHitAtImpl(x, y)
983
+
984
+ internal var pendingTaskMarkerDownScalar: Int? = null
985
+ internal var pendingTaskMarkerDownX: Float = 0f
986
+ internal var pendingTaskMarkerDownY: Float = 0f
987
+
988
+ override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
989
+ super.onFocusChanged(focused, direction, previouslyFocusedRect)
990
+ updateImageSelectionHighlightAppearance(focused = focused)
991
+ if (focused) {
992
+ clearNativeTextMutationAfterBlurWindow()
993
+ } else {
994
+ beginNativeTextMutationAfterBlurWindow()
995
+ clearExplicitSelectedImageRange()
996
+ }
997
+ }
998
+
999
+ override fun onAttachedToWindow() {
1000
+ super.onAttachedToWindow()
1001
+ refreshCodeHighlighting()
1002
+ if (restartImageLoadsOnAttach) {
1003
+ restartImageLoadsOnAttach = false
1004
+ rebuildLatestRenderForImages()
1005
+ }
1006
+ }
1007
+
1008
+ override fun onDetachedFromWindow() {
1009
+ codeHighlightingSession.cancel()
1010
+ restartImageLoadsOnAttach = hasRenderedImageSpans()
1011
+ cancelPendingImageLoads()
1012
+ (text as? Spanned)?.getSpans(0, length(), BlockImageSpan::class.java)
1013
+ ?.forEach(BlockImageSpan::close)
1014
+ super.onDetachedFromWindow()
1015
+ }
1016
+
1017
+ internal fun baseTextContextMenuItem(id: Int): Boolean = super.onTextContextMenuItem(id)
1018
+
1019
+ internal fun baseAccessibilityAction(action: Int, arguments: android.os.Bundle?): Boolean =
1020
+ super.performAccessibilityAction(action, arguments)
1021
+
1022
+ internal val editorSuggestedMinimumHeight: Int get() = suggestedMinimumHeight
1023
+ internal fun editorHorizontalScrollRange(): Int = computeHorizontalScrollRange()
1024
+ internal fun editorVerticalScrollRange(): Int = computeVerticalScrollRange()
1025
+
1026
+ companion object {
1027
+ private val nextNativeBindingToken = java.util.concurrent.atomic.AtomicLong(
1028
+ Long.MAX_VALUE / 2
1029
+ )
1030
+ internal const val DEFAULT_AUTO_CAPITALIZE = "sentences"
1031
+ internal const val DEFAULT_AUTO_CORRECT = true
1032
+ internal const val DEFAULT_KEYBOARD_TYPE = "default"
1033
+ internal const val EMPTY_BLOCK_PLACEHOLDER = '\u200B'
1034
+ internal const val IME_TRACE_LIMIT_FOR_TESTING = 80
1035
+ internal const val IME_TRACE_LOG_TAG = "NativeEditorIme"
1036
+ internal const val NATIVE_TEXT_MUTATION_AFTER_BLUR_WINDOW_MS = 750L
1037
+ internal const val RECENT_HANDLED_HARDWARE_KEY_DOWN_WINDOW_MS = 750L
1038
+ internal const val LOG_TAG = "NativeEditor"
1039
+
1040
+ internal const val MARKER_TAP_HORIZONTAL_SLOP_DP = 8f
1041
+ }
1042
+ }