@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,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
+ }