@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,573 @@
1
+ import os
2
+ import UIKit
3
+
4
+ extension EditorTextView {
5
+ struct TopLevelChildMetadata {
6
+ var startOffset: Int
7
+ var containsAttachment: Bool
8
+ var containsPositionAdjustments: Bool
9
+ }
10
+
11
+ private struct TopLevelChildMetadataSlice {
12
+ let startIndex: Int
13
+ let entries: [TopLevelChildMetadata]
14
+ }
15
+
16
+ struct ParsedRenderPatch {
17
+ let baseDocumentVersion: UInt64?
18
+ let startIndex: Int
19
+ let deleteCount: Int
20
+ let renderBlocks: [[[String: Any]]]
21
+ }
22
+
23
+ enum DerivedRenderPatch {
24
+ case unchanged
25
+ case patch(ParsedRenderPatch)
26
+ }
27
+
28
+ func parseRenderBlocks(_ value: Any?) -> [[[String: Any]]]? {
29
+ value as? [[[String: Any]]]
30
+ }
31
+
32
+ func parseRenderPatch(_ value: Any?) -> ParsedRenderPatch? {
33
+ guard let raw = value as? [String: Any],
34
+ let startIndex = RenderBridge.jsonInt(raw["startIndex"]),
35
+ let deleteCount = RenderBridge.jsonInt(raw["deleteCount"]),
36
+ let renderBlocks = parseRenderBlocks(raw["renderBlocks"])
37
+ else {
38
+ return nil
39
+ }
40
+ let baseDocumentVersion: UInt64?
41
+ if raw.keys.contains("baseDocumentVersion") {
42
+ guard let parsed = canonicalDocumentVersion(raw["baseDocumentVersion"])
43
+ else { return nil }
44
+ baseDocumentVersion = parsed
45
+ } else {
46
+ baseDocumentVersion = nil
47
+ }
48
+
49
+ return ParsedRenderPatch(
50
+ baseDocumentVersion: baseDocumentVersion,
51
+ startIndex: startIndex,
52
+ deleteCount: deleteCount,
53
+ renderBlocks: renderBlocks
54
+ )
55
+ }
56
+
57
+ func canonicalDocumentVersion(_ value: Any?) -> UInt64? {
58
+ guard let text = value as? String,
59
+ let version = UInt64(text),
60
+ String(version) == text
61
+ else { return nil }
62
+ return version
63
+ }
64
+
65
+ func patchMatchesCurrentRenderBlocks(
66
+ _ patch: ParsedRenderPatch,
67
+ updateDocumentVersion: UInt64?
68
+ ) -> Bool {
69
+ if let baseDocumentVersion = patch.baseDocumentVersion {
70
+ return baseDocumentVersion == currentRenderBlocksDocumentVersion
71
+ }
72
+ return updateDocumentVersion == nil && currentRenderBlocksDocumentVersion == nil
73
+ }
74
+
75
+ func retainCurrentRenderBlocks(
76
+ _ blocks: [[[String: Any]]]?,
77
+ documentVersion: UInt64?
78
+ ) {
79
+ currentRenderBlocks = blocks
80
+ currentRenderBlocksDocumentVersion = blocks == nil ? nil : documentVersion
81
+ }
82
+
83
+ func invalidateCurrentRenderBlocks() {
84
+ currentRenderBlocks = nil
85
+ currentRenderBlocksDocumentVersion = nil
86
+ }
87
+
88
+ func recoverRenderPatchBaseMismatch(notifyDelegate: Bool) -> Bool {
89
+ invalidateCurrentRenderBlocks()
90
+ guard !recoveringRenderPatchBaseMismatch,
91
+ editorId != 0,
92
+ let adapter = EditorV2Registry.adapter(forLegacyId: editorId),
93
+ let recovery = adapter.recoverNativeRender()
94
+ else { return false }
95
+ recoveringRenderPatchBaseMismatch = true
96
+ defer { recoveringRenderPatchBaseMismatch = false }
97
+ return applyUpdateJSON(recovery, notifyDelegate: notifyDelegate)
98
+ }
99
+
100
+ func mergeRenderBlocks(
101
+ applying patch: ParsedRenderPatch,
102
+ to current: [[[String: Any]]]
103
+ ) -> [[[String: Any]]]? {
104
+ guard patch.startIndex >= 0,
105
+ patch.deleteCount >= 0,
106
+ patch.startIndex <= current.count,
107
+ patch.startIndex + patch.deleteCount <= current.count
108
+ else {
109
+ return nil
110
+ }
111
+
112
+ var merged = current
113
+ merged.replaceSubrange(
114
+ patch.startIndex..<(patch.startIndex + patch.deleteCount),
115
+ with: patch.renderBlocks
116
+ )
117
+ return merged
118
+ }
119
+
120
+ private func renderBlockEquals(
121
+ _ lhs: [[String: Any]],
122
+ _ rhs: [[String: Any]]
123
+ ) -> Bool {
124
+ guard lhs.count == rhs.count else { return false }
125
+ for (lhsElement, rhsElement) in zip(lhs, rhs) {
126
+ guard renderElementEquals(lhsElement, rhsElement) else { return false }
127
+ }
128
+ return true
129
+ }
130
+
131
+ private func voidNodeMetadata(in renderBlock: [[String: Any]]) -> [(type: String, docPos: NSNumber)]? {
132
+ let nodes = renderBlock.compactMap { element -> (type: String, docPos: NSNumber)? in
133
+ guard let elementType = element["type"] as? String,
134
+ elementType == "voidInline" || elementType == "voidBlock",
135
+ let nodeType = element["nodeType"] as? String,
136
+ let docPos = RenderBridge.jsonUInt32(element["docPos"])
137
+ else {
138
+ return nil
139
+ }
140
+ return (nodeType, NSNumber(value: docPos))
141
+ }
142
+ return nodes
143
+ }
144
+
145
+ func refreshRetainedPositionalMetadata(
146
+ startingAt retainedStart: Int,
147
+ updatedRenderBlocks: [[[String: Any]]]
148
+ ) -> Bool {
149
+ guard let currentTopLevelChildMetadata,
150
+ currentTopLevelChildMetadata.count == updatedRenderBlocks.count,
151
+ retainedStart >= 0,
152
+ retainedStart <= currentTopLevelChildMetadata.count
153
+ else {
154
+ return false
155
+ }
156
+
157
+ for index in retainedStart..<currentTopLevelChildMetadata.count {
158
+ let start = currentTopLevelChildMetadata[index].startOffset
159
+ let end = index + 1 < currentTopLevelChildMetadata.count
160
+ ? currentTopLevelChildMetadata[index + 1].startOffset
161
+ : textStorage.length
162
+ guard start >= 0, end >= start, end <= textStorage.length else { return false }
163
+ let range = NSRange(location: start, length: end - start)
164
+ textStorage.addAttribute(
165
+ RenderBridgeAttributes.topLevelChildIndex,
166
+ value: NSNumber(value: index),
167
+ range: range
168
+ )
169
+
170
+ guard let expectedVoidNodes = voidNodeMetadata(in: updatedRenderBlocks[index]) else {
171
+ return false
172
+ }
173
+ var actualVoidNodes: [(type: String, range: NSRange)] = []
174
+ textStorage.enumerateAttribute(
175
+ RenderBridgeAttributes.voidNodeType,
176
+ in: range,
177
+ options: [.longestEffectiveRangeNotRequired]
178
+ ) { value, nodeRange, _ in
179
+ if let type = value as? String {
180
+ actualVoidNodes.append((type, nodeRange))
181
+ }
182
+ }
183
+ guard actualVoidNodes.count == expectedVoidNodes.count,
184
+ zip(actualVoidNodes, expectedVoidNodes).allSatisfy({ $0.type == $1.type })
185
+ else {
186
+ return false
187
+ }
188
+ for (actual, expected) in zip(actualVoidNodes, expectedVoidNodes) {
189
+ textStorage.addAttribute(
190
+ RenderBridgeAttributes.docPos,
191
+ value: expected.docPos,
192
+ range: actual.range
193
+ )
194
+ }
195
+ }
196
+ return true
197
+ }
198
+
199
+ private func renderElementEquals(_ lhs: [String: Any], _ rhs: [String: Any]) -> Bool {
200
+ if (lhs as NSDictionary).isEqual(to: rhs) { return true }
201
+ var comparableLhs = lhs
202
+ var comparableRhs = rhs
203
+ comparableLhs.removeValue(forKey: "docPos")
204
+ comparableRhs.removeValue(forKey: "docPos")
205
+ comparableLhs.removeValue(forKey: "topLevelChildIndex")
206
+ comparableRhs.removeValue(forKey: "topLevelChildIndex")
207
+ return (comparableLhs as NSDictionary).isEqual(to: comparableRhs)
208
+ }
209
+
210
+ func deriveRenderPatch(
211
+ from current: [[[String: Any]]],
212
+ to updated: [[[String: Any]]]
213
+ ) -> DerivedRenderPatch {
214
+ let sharedCount = min(current.count, updated.count)
215
+
216
+ var prefix = 0
217
+ while prefix < sharedCount, renderBlockEquals(current[prefix], updated[prefix]) {
218
+ prefix += 1
219
+ }
220
+
221
+ if prefix == current.count, prefix == updated.count {
222
+ return .unchanged
223
+ }
224
+
225
+ var suffix = 0
226
+ while suffix < (sharedCount - prefix),
227
+ renderBlockEquals(
228
+ current[current.count - suffix - 1],
229
+ updated[updated.count - suffix - 1]
230
+ ) {
231
+ suffix += 1
232
+ }
233
+
234
+ let startIndex = prefix
235
+ let deleteCount = current.count - prefix - suffix
236
+ let endIndex = updated.count - suffix
237
+ let replacementBlocks = Array(updated[startIndex..<endIndex])
238
+
239
+ return .patch(
240
+ ParsedRenderPatch(
241
+ baseDocumentVersion: currentRenderBlocksDocumentVersion,
242
+ startIndex: startIndex,
243
+ deleteCount: deleteCount,
244
+ renderBlocks: replacementBlocks
245
+ )
246
+ )
247
+ }
248
+
249
+ func topLevelChildIndex(from value: Any?) -> Int? {
250
+ if let number = value as? NSNumber {
251
+ return number.intValue
252
+ }
253
+ return value as? Int
254
+ }
255
+
256
+ private func topLevelChildMetadataSlice(
257
+ from attributedString: NSAttributedString
258
+ ) -> TopLevelChildMetadataSlice? {
259
+ guard attributedString.length > 0 else {
260
+ return TopLevelChildMetadataSlice(startIndex: 0, entries: [])
261
+ }
262
+
263
+ var entriesByIndex: [Int: TopLevelChildMetadata] = [:]
264
+ var orderedIndexes: [Int] = []
265
+
266
+ attributedString.enumerateAttributes(
267
+ in: NSRange(location: 0, length: attributedString.length),
268
+ options: []
269
+ ) { attrs, range, _ in
270
+ guard let index = topLevelChildIndex(from: attrs[RenderBridgeAttributes.topLevelChildIndex]) else {
271
+ return
272
+ }
273
+ if entriesByIndex[index] == nil {
274
+ entriesByIndex[index] = TopLevelChildMetadata(
275
+ startOffset: range.location,
276
+ containsAttachment: false,
277
+ containsPositionAdjustments: false
278
+ )
279
+ orderedIndexes.append(index)
280
+ }
281
+ if attrs[.attachment] != nil {
282
+ entriesByIndex[index]?.containsAttachment = true
283
+ }
284
+ if attrs[RenderBridgeAttributes.syntheticPlaceholder] as? Bool == true
285
+ || attrs[RenderBridgeAttributes.listMarkerContext] != nil {
286
+ entriesByIndex[index]?.containsPositionAdjustments = true
287
+ }
288
+ }
289
+
290
+ guard !orderedIndexes.isEmpty else { return nil }
291
+ orderedIndexes.sort()
292
+ guard let startIndex = orderedIndexes.first else { return nil }
293
+
294
+ var entries: [TopLevelChildMetadata] = []
295
+ entries.reserveCapacity(orderedIndexes.count)
296
+ for (offset, index) in orderedIndexes.enumerated() {
297
+ guard index == startIndex + offset,
298
+ let entry = entriesByIndex[index]
299
+ else {
300
+ return nil
301
+ }
302
+ entries.append(entry)
303
+ }
304
+
305
+ return TopLevelChildMetadataSlice(startIndex: startIndex, entries: entries)
306
+ }
307
+
308
+ func refreshTopLevelChildMetadata(
309
+ from attributedString: NSAttributedString
310
+ ) {
311
+ guard let slice = topLevelChildMetadataSlice(from: attributedString),
312
+ slice.startIndex == 0
313
+ else {
314
+ currentTopLevelChildMetadata = nil
315
+ return
316
+ }
317
+ currentTopLevelChildMetadata = slice.entries
318
+ }
319
+
320
+ private func applyTopLevelChildMetadataPatch(
321
+ _ patch: ParsedRenderPatch,
322
+ replaceRange: NSRange,
323
+ renderedPatchMetadata: TopLevelChildMetadataSlice?,
324
+ renderedPatchLength: Int
325
+ ) {
326
+ guard var currentMetadata = currentTopLevelChildMetadata else {
327
+ currentTopLevelChildMetadata = nil
328
+ return
329
+ }
330
+
331
+ let newEntries: [TopLevelChildMetadata]
332
+ if let renderedPatchMetadata,
333
+ renderedPatchMetadata.entries.isEmpty {
334
+ newEntries = []
335
+ } else if let renderedPatchMetadata,
336
+ renderedPatchMetadata.startIndex == patch.startIndex {
337
+ let patchEntries = renderedPatchMetadata.entries.prefix(patch.renderBlocks.count)
338
+ guard patchEntries.count == patch.renderBlocks.count else {
339
+ currentTopLevelChildMetadata = nil
340
+ return
341
+ }
342
+ newEntries = patchEntries.map { entry in
343
+ TopLevelChildMetadata(
344
+ startOffset: replaceRange.location + entry.startOffset,
345
+ containsAttachment: entry.containsAttachment,
346
+ containsPositionAdjustments: entry.containsPositionAdjustments
347
+ )
348
+ }
349
+ } else {
350
+ currentTopLevelChildMetadata = nil
351
+ return
352
+ }
353
+
354
+ guard patch.startIndex >= 0,
355
+ patch.deleteCount >= 0,
356
+ patch.startIndex <= currentMetadata.count,
357
+ patch.startIndex + patch.deleteCount <= currentMetadata.count
358
+ else {
359
+ currentTopLevelChildMetadata = nil
360
+ return
361
+ }
362
+
363
+ currentMetadata.replaceSubrange(
364
+ patch.startIndex..<(patch.startIndex + patch.deleteCount),
365
+ with: newEntries
366
+ )
367
+
368
+ let delta = renderedPatchLength - replaceRange.length
369
+ if delta != 0 {
370
+ let shiftStart = patch.startIndex + newEntries.count
371
+ for index in shiftStart..<currentMetadata.count {
372
+ currentMetadata[index].startOffset += delta
373
+ }
374
+ }
375
+
376
+ currentTopLevelChildMetadata = currentMetadata
377
+ }
378
+
379
+ private func hasTopLevelChildMetadata() -> Bool {
380
+ currentTopLevelChildMetadata != nil
381
+ }
382
+
383
+ private func firstCharacterOffset(forTopLevelChildIndex index: Int) -> Int? {
384
+ guard let currentTopLevelChildMetadata,
385
+ index >= 0,
386
+ index < currentTopLevelChildMetadata.count
387
+ else {
388
+ return nil
389
+ }
390
+ return currentTopLevelChildMetadata[index].startOffset
391
+ }
392
+
393
+ private func replacementRangeForRenderPatch(
394
+ startIndex: Int,
395
+ deleteCount: Int
396
+ ) -> NSRange? {
397
+ let startLocation: Int
398
+ if let resolvedStart = firstCharacterOffset(forTopLevelChildIndex: startIndex) {
399
+ startLocation = resolvedStart
400
+ } else if deleteCount == 0 {
401
+ startLocation = textStorage.length
402
+ } else {
403
+ return nil
404
+ }
405
+
406
+ let endIndexExclusive = startIndex + deleteCount
407
+ let endLocation = firstCharacterOffset(forTopLevelChildIndex: endIndexExclusive)
408
+ ?? textStorage.length
409
+ guard startLocation <= endLocation else { return nil }
410
+ return NSRange(location: startLocation, length: endLocation - startLocation)
411
+ }
412
+
413
+ func applyRenderPatchIfPossible(_ patch: ParsedRenderPatch) -> PatchApplyTrace {
414
+ let eligibilityStartedAt = DispatchTime.now().uptimeNanoseconds
415
+ guard hasTopLevelChildMetadata(),
416
+ let fullReplaceRange = replacementRangeForRenderPatch(
417
+ startIndex: patch.startIndex,
418
+ deleteCount: patch.deleteCount
419
+ )
420
+ else {
421
+ return PatchApplyTrace(
422
+ applied: false,
423
+ eligibilityNanos: DispatchTime.now().uptimeNanoseconds - eligibilityStartedAt,
424
+ trimNanos: 0,
425
+ metadataNanos: 0,
426
+ buildRenderNanos: 0,
427
+ applyRenderNanos: 0,
428
+ applyRenderReplaceUtf16Length: 0,
429
+ applyRenderReplacementUtf16Length: 0,
430
+ applyRenderTextMutationNanos: 0,
431
+ applyRenderBeginEditingNanos: 0,
432
+ applyRenderEndEditingNanos: 0,
433
+ applyRenderStringMutationNanos: 0,
434
+ applyRenderAttributeMutationNanos: 0,
435
+ applyRenderAuthorizedTextNanos: 0,
436
+ applyRenderCacheInvalidationNanos: 0,
437
+ usedSmallPatchTextMutation: false
438
+ )
439
+ }
440
+
441
+ let buildStartedAt = DispatchTime.now().uptimeNanoseconds
442
+ let attrStr = withImageLoadOwner {
443
+ RenderBridge.renderBlocks(
444
+ fromArray: patch.renderBlocks,
445
+ startIndex: patch.startIndex,
446
+ includeLeadingInterBlockSeparator: patch.startIndex > 0,
447
+ // Replacement ranges already extend to the following child
448
+ // boundary, whose separator is rendered by that retained
449
+ // child. A trailing separator is therefore needed only when
450
+ // inserting before the first existing child.
451
+ includeTrailingInterBlockSeparator: patch.startIndex == 0
452
+ && patch.deleteCount == 0
453
+ && !(currentTopLevelChildMetadata?.isEmpty ?? true),
454
+ baseFont: baseFont,
455
+ textColor: baseTextColor,
456
+ theme: theme,
457
+ atomConfiguration: atomRenderConfiguration
458
+ )
459
+ }
460
+ let buildRenderNanos = DispatchTime.now().uptimeNanoseconds - buildStartedAt
461
+ let renderedPatchMetadata = topLevelChildMetadataSlice(from: attrStr)
462
+ let renderedPatchContainsAttachment =
463
+ renderedPatchMetadata?.entries.contains(where: \.containsAttachment)
464
+ ?? attributedStringContainsAttachment(attrStr)
465
+ let renderedPatchContainsListMarkerContext =
466
+ attributedStringContainsListMarkerContext(attrStr)
467
+ let renderedPatchContainsPositionAdjustments =
468
+ renderedPatchMetadata?.entries.contains(where: \.containsPositionAdjustments)
469
+ ?? attributedStringContainsPositionAdjustments(attrStr)
470
+ guard !topLevelChildrenContainAttachment(
471
+ startIndex: patch.startIndex,
472
+ deleteCount: patch.deleteCount
473
+ ),
474
+ !renderedPatchContainsAttachment
475
+ else {
476
+ return PatchApplyTrace(
477
+ applied: false,
478
+ eligibilityNanos: DispatchTime.now().uptimeNanoseconds - eligibilityStartedAt,
479
+ trimNanos: 0,
480
+ metadataNanos: 0,
481
+ buildRenderNanos: buildRenderNanos,
482
+ applyRenderNanos: 0,
483
+ applyRenderReplaceUtf16Length: 0,
484
+ applyRenderReplacementUtf16Length: 0,
485
+ applyRenderTextMutationNanos: 0,
486
+ applyRenderBeginEditingNanos: 0,
487
+ applyRenderEndEditingNanos: 0,
488
+ applyRenderStringMutationNanos: 0,
489
+ applyRenderAttributeMutationNanos: 0,
490
+ applyRenderAuthorizedTextNanos: 0,
491
+ applyRenderCacheInvalidationNanos: 0,
492
+ usedSmallPatchTextMutation: false
493
+ )
494
+ }
495
+ guard !textStorageRangeContainsListMarkerContext(fullReplaceRange),
496
+ !renderedPatchContainsListMarkerContext
497
+ else {
498
+ return PatchApplyTrace(
499
+ applied: false,
500
+ eligibilityNanos: DispatchTime.now().uptimeNanoseconds - eligibilityStartedAt,
501
+ trimNanos: 0,
502
+ metadataNanos: 0,
503
+ buildRenderNanos: buildRenderNanos,
504
+ applyRenderNanos: 0,
505
+ applyRenderReplaceUtf16Length: 0,
506
+ applyRenderReplacementUtf16Length: 0,
507
+ applyRenderTextMutationNanos: 0,
508
+ applyRenderBeginEditingNanos: 0,
509
+ applyRenderEndEditingNanos: 0,
510
+ applyRenderStringMutationNanos: 0,
511
+ applyRenderAttributeMutationNanos: 0,
512
+ applyRenderAuthorizedTextNanos: 0,
513
+ applyRenderCacheInvalidationNanos: 0,
514
+ usedSmallPatchTextMutation: false
515
+ )
516
+ }
517
+ let eligibilityNanos =
518
+ DispatchTime.now().uptimeNanoseconds - eligibilityStartedAt - buildRenderNanos
519
+ let positionCacheUpdate: PositionCacheUpdate =
520
+ if topLevelChildrenContainPositionAdjustments(
521
+ startIndex: patch.startIndex,
522
+ deleteCount: patch.deleteCount
523
+ ) || renderedPatchContainsPositionAdjustments {
524
+ .attributed
525
+ } else {
526
+ .plainText
527
+ }
528
+ let trimStartedAt = DispatchTime.now().uptimeNanoseconds
529
+ let patchToApply = trimmedAttributedPatch(replacing: fullReplaceRange, with: attrStr)
530
+ let trimNanos = DispatchTime.now().uptimeNanoseconds - trimStartedAt
531
+ let applyTrace = applyAttributedRender(
532
+ patchToApply.replacement,
533
+ replaceRange: patchToApply.replaceRange,
534
+ usedPatch: true,
535
+ positionCacheUpdate: positionCacheUpdate,
536
+ authorizedReplaceRange: fullReplaceRange,
537
+ authorizedReplacementText: attrStr.string,
538
+ authorizedReplacementAttributedText: attrStr
539
+ )
540
+ if theme?.styleSheet != nil {
541
+ textStorage.beginEditing()
542
+ RenderBridge.collapseStyledSiblingMargins(in: textStorage)
543
+ textStorage.endEditing()
544
+ }
545
+ let metadataStartedAt = DispatchTime.now().uptimeNanoseconds
546
+ applyTopLevelChildMetadataPatch(
547
+ patch,
548
+ replaceRange: fullReplaceRange,
549
+ renderedPatchMetadata: renderedPatchMetadata,
550
+ renderedPatchLength: attrStr.length
551
+ )
552
+ let metadataNanos = DispatchTime.now().uptimeNanoseconds - metadataStartedAt
553
+ return PatchApplyTrace(
554
+ applied: true,
555
+ eligibilityNanos: eligibilityNanos,
556
+ trimNanos: trimNanos,
557
+ metadataNanos: metadataNanos,
558
+ buildRenderNanos: buildRenderNanos,
559
+ applyRenderNanos: applyTrace.totalNanos,
560
+ applyRenderReplaceUtf16Length: applyTrace.replaceUtf16Length,
561
+ applyRenderReplacementUtf16Length: applyTrace.replacementUtf16Length,
562
+ applyRenderTextMutationNanos: applyTrace.textMutationNanos,
563
+ applyRenderBeginEditingNanos: applyTrace.beginEditingNanos,
564
+ applyRenderEndEditingNanos: applyTrace.endEditingNanos,
565
+ applyRenderStringMutationNanos: applyTrace.stringMutationNanos,
566
+ applyRenderAttributeMutationNanos: applyTrace.attributeMutationNanos,
567
+ applyRenderAuthorizedTextNanos: applyTrace.authorizedTextNanos,
568
+ applyRenderCacheInvalidationNanos: applyTrace.cacheInvalidationNanos,
569
+ usedSmallPatchTextMutation: applyTrace.usedSmallPatchTextMutation
570
+ )
571
+ }
572
+
573
+ }