react-native-enriched-markdown-scaffold 0.7.4-scaffold.8 → 1.0.2-scaffold.1

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 (469) hide show
  1. package/README.md +54 -8
  2. package/ReactNativeEnrichedMarkdown.podspec +82 -73
  3. package/android/build.gradle +191 -1
  4. package/android/consumer-rules.pro +1 -1
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +9 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +3 -0
  7. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +27 -0
  8. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +9 -0
  9. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +9 -0
  10. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +3 -0
  11. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
  12. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
  13. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +40 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +839 -23
  15. package/android/src/main/baseline-prof.txt +1 -1
  16. package/android/src/main/cpp/jni-adapter.cpp +74 -0
  17. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +175 -11
  18. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +17 -0
  19. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +50 -0
  20. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +48 -1
  21. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +10 -1
  22. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +42 -0
  23. package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +82 -4
  24. package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyPressEvent.kt +24 -0
  25. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +62 -4
  26. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +911 -460
  27. package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
  28. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
  29. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
  30. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
  31. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
  32. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
  33. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +101 -7
  34. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
  35. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
  36. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
  37. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
  38. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
  39. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
  40. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
  41. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
  42. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockSyntaxSentinel.kt +69 -0
  43. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
  44. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
  45. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +180 -27
  46. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
  47. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
  48. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
  49. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +7 -2
  50. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
  51. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
  52. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
  53. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
  54. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
  55. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
  56. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
  58. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
  65. package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
  66. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
  68. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
  69. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
  70. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
  71. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
  72. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
  73. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
  74. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
  75. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
  76. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
  77. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +30 -27
  78. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
  79. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
  80. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +27 -3
  81. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
  82. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
  83. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
  84. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
  85. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
  86. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
  87. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
  88. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
  89. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
  90. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
  91. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
  93. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
  94. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
  95. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
  96. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
  97. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
  98. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
  99. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
  100. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
  101. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +33 -7
  102. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
  103. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
  104. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
  105. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
  106. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
  107. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
  108. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +20 -0
  109. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
  110. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
  111. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
  112. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
  113. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
  114. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
  115. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
  116. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
  117. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +19 -2
  118. package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +388 -0
  119. package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
  120. package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
  121. package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +32 -5
  122. package/android/src/main/jni/CMakeLists.txt +53 -0
  123. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
  124. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
  125. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
  126. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
  127. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
  128. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
  129. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
  130. package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
  131. package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +7 -2
  132. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
  133. package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +2 -0
  134. package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
  135. package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
  136. package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
  137. package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
  138. package/cpp/highlight/HighlightGrammars.hpp +28 -0
  139. package/cpp/highlight/code_highlight_podspec.rb +211 -0
  140. package/cpp/highlight/gen-registry.mjs +155 -0
  141. package/cpp/highlight/grammar-versions.json +159 -0
  142. package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
  143. package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
  144. package/cpp/parser/MD4CParser.cpp +173 -61
  145. package/cpp/parser/MD4CParser.hpp +1 -0
  146. package/cpp/parser/MarkdownASTNode.hpp +2 -1
  147. package/cpp/wasm/ASTSerializer.cpp +2 -0
  148. package/cpp/wasm/build.sh +1 -0
  149. package/cpp/wasm/md4c_wasm.cpp +3 -1
  150. package/docs/ACCESSIBILITY.md +14 -2
  151. package/docs/API_REFERENCE.md +231 -8
  152. package/docs/BREAKING_CHANGES.md +129 -0
  153. package/docs/CODE_HIGHLIGHT.md +133 -0
  154. package/docs/COPY_OPTIONS.md +21 -3
  155. package/docs/ELEMENTS_STRUCTURE.md +52 -4
  156. package/docs/IMAGE_CACHING.md +30 -0
  157. package/docs/INPUT.md +146 -5
  158. package/docs/LATEX_MATH.md +87 -45
  159. package/docs/MACOS.md +1 -1
  160. package/docs/MARKDOWN_STREAMING.md +27 -1
  161. package/docs/NATIVE_ASSETS.md +127 -0
  162. package/docs/RTL.md +1 -1
  163. package/docs/STYLES.md +46 -6
  164. package/docs/TESTING.md +112 -0
  165. package/docs/TEXT.md +16 -6
  166. package/docs/WEB.md +3 -1
  167. package/ios/EnrichedMarkdown.h +7 -0
  168. package/ios/EnrichedMarkdown.mm +262 -67
  169. package/ios/EnrichedMarkdownText.h +7 -0
  170. package/ios/EnrichedMarkdownText.mm +97 -68
  171. package/ios/attachments/ENRMImageAttachment.h +9 -0
  172. package/ios/attachments/ENRMImageAttachment.m +143 -40
  173. package/ios/attachments/ENRMMathInlineAttachment.h +2 -0
  174. package/ios/attachments/ENRMMathInlineAttachment.m +48 -81
  175. package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
  176. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
  177. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
  178. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +40 -0
  179. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +839 -23
  180. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +131 -0
  181. package/ios/input/ENRMAutoLinkDetector.h +2 -1
  182. package/ios/input/ENRMAutoLinkDetector.mm +79 -41
  183. package/ios/input/ENRMBlockEditCoordinator.h +71 -0
  184. package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
  185. package/ios/input/ENRMBlockRange.h +28 -0
  186. package/ios/input/ENRMBlockRange.mm +30 -0
  187. package/ios/input/ENRMBlockStore.h +56 -0
  188. package/ios/input/ENRMBlockStore.mm +275 -0
  189. package/ios/input/ENRMBlockSyntaxSentinel.h +25 -0
  190. package/ios/input/ENRMBlockSyntaxSentinel.mm +80 -0
  191. package/ios/input/ENRMClipboardCoordinator.h +45 -0
  192. package/ios/input/ENRMClipboardCoordinator.mm +120 -0
  193. package/ios/input/ENRMDetectorPipeline.h +2 -1
  194. package/ios/input/ENRMEditPipeline.h +76 -0
  195. package/ios/input/ENRMEditPipeline.mm +228 -0
  196. package/ios/input/ENRMEditSession.h +36 -0
  197. package/ios/input/ENRMEditSession.mm +63 -0
  198. package/ios/input/ENRMFormattingStore.h +17 -0
  199. package/ios/input/ENRMFormattingStore.mm +95 -105
  200. package/ios/input/ENRMInputBlockType.h +91 -0
  201. package/ios/input/ENRMInputBlockType.mm +5 -0
  202. package/ios/input/ENRMInputDecorationDrawer.h +18 -0
  203. package/ios/input/ENRMInputEventEmitter.h +56 -0
  204. package/ios/input/ENRMInputEventEmitter.mm +308 -0
  205. package/ios/input/ENRMInputFormatter.h +29 -69
  206. package/ios/input/ENRMInputFormatter.mm +216 -124
  207. package/ios/input/ENRMInputFormatterStyle.h +99 -0
  208. package/ios/input/ENRMInputFormatterStyle.mm +188 -0
  209. package/ios/input/ENRMInputLayoutManager.h +9 -0
  210. package/ios/input/ENRMInputLayoutManager.mm +30 -0
  211. package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
  212. package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
  213. package/ios/input/ENRMInputParser.h +10 -6
  214. package/ios/input/ENRMInputParser.mm +527 -171
  215. package/ios/input/ENRMInputRemend.mm +2 -2
  216. package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
  217. package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
  218. package/ios/input/ENRMInputTextView.mm +103 -8
  219. package/ios/input/ENRMInputTypingAttributesController.h +42 -0
  220. package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
  221. package/ios/input/ENRMLinkCoordinator.h +41 -0
  222. package/ios/input/ENRMLinkCoordinator.mm +89 -0
  223. package/ios/input/ENRMMarkdownSerializer.h +29 -5
  224. package/ios/input/ENRMMarkdownSerializer.mm +170 -48
  225. package/ios/input/ENRMMathAtom.h +26 -0
  226. package/ios/input/ENRMMathAtom.mm +12 -0
  227. package/ios/input/ENRMMentionCoordinator.h +45 -0
  228. package/ios/input/ENRMMentionCoordinator.mm +167 -0
  229. package/ios/input/ENRMRangeEditAdjustment.h +38 -0
  230. package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
  231. package/ios/input/ENRMRangeStoreUtils.h +39 -0
  232. package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
  233. package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
  234. package/ios/input/EnrichedMarkdownTextInput.h +7 -1
  235. package/ios/input/EnrichedMarkdownTextInput.mm +1104 -1024
  236. package/ios/input/InputStylePropsUtils.h +109 -68
  237. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
  238. package/ios/input/styles/ENRMBlockHandler.h +46 -0
  239. package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
  240. package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
  241. package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
  242. package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
  243. package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
  244. package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
  245. package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
  246. package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
  247. package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
  248. package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
  249. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
  250. package/ios/internals/MeasurementCache.h +33 -7
  251. package/ios/internals/ShadowMeasurementUtils.h +63 -58
  252. package/ios/math/ENRMMathChipController.h +74 -0
  253. package/ios/math/ENRMMathChipController.mm +476 -0
  254. package/ios/math/ENRMRaTeXBridge.swift +4 -1
  255. package/ios/parser/ENRMMarkdownParser.h +1 -8
  256. package/ios/parser/ENRMMarkdownParser.mm +2 -11
  257. package/ios/parser/MarkdownASTNode.h +2 -1
  258. package/ios/parser/MarkdownParserBridge.mm +4 -0
  259. package/ios/renderer/AttributedRenderer.m +20 -2
  260. package/ios/renderer/BaseRenderer.h +17 -2
  261. package/ios/renderer/BaseRenderer.m +30 -0
  262. package/ios/renderer/BlockquoteRenderer.h +1 -1
  263. package/ios/renderer/BlockquoteRenderer.m +144 -35
  264. package/ios/renderer/CodeBlockRenderer.h +1 -1
  265. package/ios/renderer/CodeBlockRenderer.m +27 -23
  266. package/ios/renderer/CodeRenderer.h +1 -1
  267. package/ios/renderer/CodeRenderer.m +3 -1
  268. package/ios/renderer/ENRMImageRenderer.h +1 -1
  269. package/ios/renderer/ENRMImageRenderer.m +5 -1
  270. package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
  271. package/ios/renderer/ENRMMathInlineRenderer.m +5 -1
  272. package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
  273. package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
  274. package/ios/renderer/EmphasisRenderer.h +1 -1
  275. package/ios/renderer/EmphasisRenderer.m +3 -1
  276. package/ios/renderer/HeadingRenderer.h +1 -1
  277. package/ios/renderer/HeadingRenderer.m +13 -6
  278. package/ios/renderer/HighlightRenderer.h +1 -1
  279. package/ios/renderer/HighlightRenderer.m +3 -1
  280. package/ios/renderer/LinkRenderer.h +1 -1
  281. package/ios/renderer/LinkRenderer.m +3 -1
  282. package/ios/renderer/ListItemRenderer.h +13 -1
  283. package/ios/renderer/ListItemRenderer.m +102 -44
  284. package/ios/renderer/ListRenderer.h +2 -2
  285. package/ios/renderer/ListRenderer.m +63 -25
  286. package/ios/renderer/ParagraphRenderer.h +1 -1
  287. package/ios/renderer/ParagraphRenderer.m +16 -8
  288. package/ios/renderer/RenderContext.h +10 -0
  289. package/ios/renderer/RenderContext.m +44 -0
  290. package/ios/renderer/RendererFactory.m +14 -0
  291. package/ios/renderer/StrikethroughRenderer.h +1 -1
  292. package/ios/renderer/StrikethroughRenderer.m +3 -1
  293. package/ios/renderer/StrongRenderer.h +1 -1
  294. package/ios/renderer/StrongRenderer.m +3 -1
  295. package/ios/renderer/SubscriptRenderer.h +1 -1
  296. package/ios/renderer/SubscriptRenderer.m +3 -1
  297. package/ios/renderer/SuperscriptRenderer.h +1 -1
  298. package/ios/renderer/SuperscriptRenderer.m +3 -1
  299. package/ios/renderer/TextRenderer.h +2 -2
  300. package/ios/renderer/TextRenderer.m +3 -1
  301. package/ios/renderer/ThematicBreakRenderer.h +1 -1
  302. package/ios/renderer/ThematicBreakRenderer.m +3 -1
  303. package/ios/renderer/UnderlineRenderer.h +1 -1
  304. package/ios/renderer/UnderlineRenderer.m +3 -1
  305. package/ios/styles/StyleConfig.h +22 -0
  306. package/ios/styles/StyleConfig.mm +132 -0
  307. package/ios/utils/BlockquoteBorder.h +6 -0
  308. package/ios/utils/BlockquoteBorder.m +249 -52
  309. package/ios/utils/CodeBlockBackground.m +16 -2
  310. package/ios/utils/ENRMAtomicSize.h +65 -0
  311. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  312. package/ios/utils/ENRMCodeBlockContent.mm +79 -0
  313. package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
  314. package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
  315. package/ios/utils/ENRMFeatureFlags.h +7 -0
  316. package/ios/utils/ENRMImageDownloader.h +11 -1
  317. package/ios/utils/ENRMImageDownloader.m +60 -16
  318. package/ios/utils/ENRMLocalImageLoader.h +31 -0
  319. package/ios/utils/ENRMLocalImageLoader.m +68 -0
  320. package/ios/utils/ENRMMathFallback.h +26 -0
  321. package/ios/utils/ENRMMathFallback.m +18 -0
  322. package/ios/utils/ENRMTextViewSetup.h +35 -17
  323. package/ios/utils/EditMenuUtils.m +22 -1
  324. package/ios/utils/ImageRequestHeaderUtils.h +35 -0
  325. package/ios/utils/LastElementUtils.h +1 -0
  326. package/ios/utils/ListMarkerDrawer.m +29 -42
  327. package/ios/utils/MarkdownASTSerializer.m +4 -0
  328. package/ios/utils/ParagraphStyleUtils.h +5 -0
  329. package/ios/utils/ParagraphStyleUtils.m +77 -17
  330. package/ios/utils/RenderedMarkdownSegment.h +13 -1
  331. package/ios/utils/RenderedMarkdownSegment.m +20 -0
  332. package/ios/utils/SegmentRenderer.m +17 -4
  333. package/ios/utils/StreamingMarkdownFilter.h +11 -1
  334. package/ios/utils/StreamingMarkdownFilter.m +98 -2
  335. package/ios/utils/StylePropsUtils.h +63 -0
  336. package/ios/utils/TaskListTapUtils.m +24 -0
  337. package/ios/views/ENRMCodeBlockContainerView.h +46 -0
  338. package/ios/views/ENRMCodeBlockContainerView.m +566 -0
  339. package/ios/views/ENRMMathContainerView.h +12 -0
  340. package/ios/views/ENRMMathContainerView.m +71 -1
  341. package/ios/views/TableContainerView.h +18 -0
  342. package/ios/views/TableContainerView.m +259 -159
  343. package/jest.d.ts +1 -0
  344. package/jest.js +5 -0
  345. package/lib/module/EnrichedMarkdownNativeComponent.ts +65 -0
  346. package/lib/module/EnrichedMarkdownTextInput.js +86 -5
  347. package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
  348. package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +89 -5
  349. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +66 -0
  350. package/lib/module/headingDefaults.js +34 -0
  351. package/lib/module/headingDefaults.js.map +1 -0
  352. package/lib/module/index.js.map +1 -1
  353. package/lib/module/jest/index.js +191 -0
  354. package/lib/module/jest/index.js.map +1 -0
  355. package/lib/module/native/EnrichedMarkdownText.js +30 -4
  356. package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
  357. package/lib/module/normalizeMarkdownStyle.js +81 -19
  358. package/lib/module/normalizeMarkdownStyle.js.map +1 -1
  359. package/lib/module/normalizeMarkdownStyle.web.js +56 -18
  360. package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
  361. package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
  362. package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
  363. package/lib/module/normalizeMenuItem.js +1 -1
  364. package/lib/module/utils/textInputState.js +26 -0
  365. package/lib/module/utils/textInputState.js.map +1 -0
  366. package/lib/module/web/EnrichedMarkdownText.js +9 -5
  367. package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
  368. package/lib/module/web/parseMarkdown.js +4 -3
  369. package/lib/module/web/parseMarkdown.js.map +1 -1
  370. package/lib/module/web/renderers/InlineRenderers.js +6 -0
  371. package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
  372. package/lib/module/web/renderers/ListRenderers.js +7 -2
  373. package/lib/module/web/renderers/ListRenderers.js.map +1 -1
  374. package/lib/module/web/renderers/index.js +7 -4
  375. package/lib/module/web/renderers/index.js.map +1 -1
  376. package/lib/module/web/styles.js +83 -6
  377. package/lib/module/web/styles.js.map +1 -1
  378. package/lib/module/web/utils.js +1 -0
  379. package/lib/module/web/utils.js.map +1 -1
  380. package/lib/module/web/wasm/md4c.js +0 -0
  381. package/lib/module/web/wasm/md4c.js.map +1 -1
  382. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +62 -0
  383. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
  384. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +95 -9
  385. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
  386. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +80 -5
  387. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
  388. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +62 -0
  389. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
  390. package/lib/typescript/src/headingDefaults.d.ts +9 -0
  391. package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
  392. package/lib/typescript/src/index.d.ts +2 -2
  393. package/lib/typescript/src/index.d.ts.map +1 -1
  394. package/lib/typescript/src/index.web.d.ts +1 -1
  395. package/lib/typescript/src/index.web.d.ts.map +1 -1
  396. package/lib/typescript/src/jest/index.d.ts +6 -0
  397. package/lib/typescript/src/jest/index.d.ts.map +1 -0
  398. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +3 -3
  399. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
  400. package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
  401. package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
  402. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
  403. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
  404. package/lib/typescript/src/types/MarkdownStyle.d.ts +72 -0
  405. package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
  406. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +27 -0
  407. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
  408. package/lib/typescript/src/types/MarkdownTextProps.d.ts +65 -1
  409. package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
  410. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +19 -0
  411. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
  412. package/lib/typescript/src/types/events.d.ts +19 -0
  413. package/lib/typescript/src/types/events.d.ts.map +1 -1
  414. package/lib/typescript/src/utils/textInputState.d.ts +24 -0
  415. package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
  416. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
  417. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
  418. package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
  419. package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
  420. package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
  421. package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
  422. package/lib/typescript/src/web/renderers/index.d.ts +2 -1
  423. package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
  424. package/lib/typescript/src/web/styles.d.ts +2 -1
  425. package/lib/typescript/src/web/styles.d.ts.map +1 -1
  426. package/lib/typescript/src/web/types.d.ts +6 -2
  427. package/lib/typescript/src/web/types.d.ts.map +1 -1
  428. package/lib/typescript/src/web/utils.d.ts.map +1 -1
  429. package/package.json +36 -9
  430. package/postinstall.mjs +131 -0
  431. package/ratex-version.json +21 -0
  432. package/src/EnrichedMarkdownNativeComponent.ts +65 -0
  433. package/src/EnrichedMarkdownTextInput.tsx +162 -8
  434. package/src/EnrichedMarkdownTextInputNativeComponent.ts +89 -5
  435. package/src/EnrichedMarkdownTextNativeComponent.ts +66 -0
  436. package/src/headingDefaults.ts +21 -0
  437. package/src/index.tsx +9 -0
  438. package/src/index.web.tsx +1 -0
  439. package/src/jest/index.tsx +215 -0
  440. package/src/native/EnrichedMarkdownText.tsx +40 -2
  441. package/src/normalizeMarkdownStyle.ts +102 -16
  442. package/src/normalizeMarkdownStyle.web.ts +63 -15
  443. package/src/normalizeMarkdownTextInputStyle.ts +110 -35
  444. package/src/normalizeMenuItem.ts +1 -1
  445. package/src/types/MarkdownStyle.ts +74 -0
  446. package/src/types/MarkdownStyleInternal.ts +39 -0
  447. package/src/types/MarkdownTextProps.ts +65 -0
  448. package/src/types/MarkdownTextProps.web.ts +19 -0
  449. package/src/types/events.ts +21 -0
  450. package/src/utils/textInputState.ts +35 -0
  451. package/src/web/EnrichedMarkdownText.tsx +16 -2
  452. package/src/web/parseMarkdown.ts +6 -2
  453. package/src/web/renderers/InlineRenderers.tsx +5 -0
  454. package/src/web/renderers/ListRenderers.tsx +14 -2
  455. package/src/web/renderers/index.tsx +6 -2
  456. package/src/web/styles.ts +89 -5
  457. package/src/web/types.ts +6 -1
  458. package/src/web/utils.ts +1 -0
  459. package/src/web/wasm/md4c.js +0 -0
  460. package/vendor-grammars.mjs +511 -0
  461. package/vendor-ratex.mjs +173 -0
  462. package/app.plugin.js +0 -2
  463. package/plugin/build/withAndroidMath.js +0 -19
  464. package/plugin/build/withIosMath.js +0 -28
  465. package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
  466. package/plugin/src/withAndroidMath.ts +0 -24
  467. package/plugin/src/withIosMath.ts +0 -35
  468. package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
  469. package/plugin/tsconfig.build.json +0 -16
@@ -2,6 +2,7 @@
2
2
  #import "ContextMenuUtils.h"
3
3
  #import "ENRMAccessibilityLabels.h"
4
4
  #import "ENRMAsyncRenderCoordinator.h"
5
+ #import "ENRMAtomicSize.h"
5
6
  #import "ENRMImageAttachment.h"
6
7
  #import "ENRMMarkdownParser.h"
7
8
  #import "ENRMTailFadeInAnimator.h"
@@ -10,12 +11,14 @@
10
11
  #import "ENRMTextViewSetup.h"
11
12
  #import "ENRMUIKit.h"
12
13
  #import "EditMenuUtils.h"
14
+ #import "ImageRequestHeaderUtils.h"
13
15
 
14
16
  #import "ENRMFeatureFlags.h"
15
17
 
16
18
  #if ENRICHED_MARKDOWN_MATH
17
19
  #import "ENRMMathContainerView.h"
18
20
  #endif
21
+ #import "ENRMCodeBlockContainerView.h"
19
22
  #import "ENRMSpoilerCapable.h"
20
23
  #import "ENRMSpoilerOverlayView.h"
21
24
  #import "ENRMSpoilerTapUtils.h"
@@ -66,10 +69,12 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
66
69
 
67
70
  static char kENRMSegmentFadeAnimatorKey;
68
71
 
69
- @interface EnrichedMarkdown () <RCTEnrichedMarkdownViewProtocol, UITextViewDelegate>
72
+ @interface EnrichedMarkdown () <RCTEnrichedMarkdownViewProtocol, UITextViewDelegate, ENRMImageLayoutObserver>
73
+ + (ENRMMd4cFlags *)flagsFromProps:(const EnrichedMarkdownMd4cFlagsStruct &)props;
70
74
  - (void)emitLinkPress:(NSString *)url;
71
75
  - (void)emitLinkLongPress:(NSString *)url;
72
76
  - (void)emitTaskListItemPress:(NSInteger)index checked:(BOOL)checked text:(NSString *)text;
77
+ - (void)emitCopyPress:(NSString *)code language:(NSString *)language;
73
78
  - (void)emitContextMenuItemPress:(NSString *)itemText
74
79
  selectedText:(NSString *)selectedText
75
80
  selectionStart:(NSUInteger)selectionStart
@@ -98,8 +103,13 @@ static char kENRMSegmentFadeAnimatorKey;
98
103
  BOOL _allowTrailingMargin;
99
104
  BOOL _selectable;
100
105
  BOOL _enableLinkPreview;
106
+ BOOL _enableTaskListItemToggle;
107
+ BOOL _contextMenuHidden;
101
108
  BOOL _streamingAnimation;
102
109
  ENRMTableStreamingMode _tableStreamingMode;
110
+ ENRMCodeBlockStreamingMode _codeBlockStreamingMode;
111
+ // Trailing code block whose closing fence hasn't streamed in yet, if any.
112
+ ENRMCodeBlockSegment *_pendingCodeBlockSegment;
103
113
 
104
114
  size_t _renderedStyleFingerprint;
105
115
  size_t _pendingStyleFingerprint;
@@ -116,6 +126,8 @@ static char kENRMSegmentFadeAnimatorKey;
116
126
 
117
127
  ENRMWritingDirectionMode _writingDirectionMode;
118
128
  NSWritingDirection _resolvedLayoutDirection;
129
+
130
+ ENRMAtomicSize _lastCommittedSize;
119
131
  }
120
132
 
121
133
  + (ComponentDescriptorProvider)componentDescriptorProvider
@@ -123,43 +135,16 @@ static char kENRMSegmentFadeAnimatorKey;
123
135
  return concreteComponentDescriptorProvider<EnrichedMarkdownComponentDescriptor>();
124
136
  }
125
137
 
126
- /// Clears every piece of state that `updateProps` derives from props, back to the
127
- /// values the default-constructed `EnrichedMarkdownProps` describes.
128
- ///
129
- /// `updateProps` applies most props as a per-field diff against `_props`, so this
130
- /// state is only correct while it stays in phase with the `_props` baseline it was
131
- /// diffed from. `prepareForRecycle` resets `_props`, so it must reset this too —
132
- /// otherwise every field the next consumer leaves at its default silently inherits
133
- /// the previous consumer's value. Called from `initWithFrame:` as well, so the two
134
- /// baselines cannot drift apart.
135
- ///
136
- /// Requires `_fontScaleObserver` to already exist.
137
- - (void)resetPropDerivedState
138
+ + (ENRMMd4cFlags *)flagsFromProps:(const EnrichedMarkdownMd4cFlagsStruct &)props
138
139
  {
139
- // Discarded rather than cleared field-by-field: the style diff can only clear a
140
- // field when new and old differ, which never holds against a reset baseline.
141
- _config = nil;
142
-
143
- _md4cFlags = [ENRMMd4cFlags propsDefaultFlags];
144
- _maxFontSizeMultiplier = 0;
145
- _allowTrailingMargin = NO;
146
- _fontScaleObserver.allowFontScaling = YES;
147
- _streamingAnimation = NO;
148
- _tableStreamingMode = ENRMTableStreamingModeProgressive;
149
- _spoilerOverlay = ENRMSpoilerOverlayParticles;
150
- _lineBreakStrategy = NSLineBreakStrategyNone;
151
- _writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
152
- _contextMenuItemTexts = nil;
153
- _contextMenuItemIcons = nil;
154
- _accessibilityLabels = nil;
155
-
156
- // Written only once a render completes, so stale until the next one lands.
157
- _renderedStyleFingerprint = 0;
158
- _pendingStyleFingerprint = 0;
159
-
160
- _dirtyFlags = ENRMDirtyNone;
161
- _heightUpdateCounter = 0;
162
- _state = nullptr;
140
+ ENRMMd4cFlags *flags = [ENRMMd4cFlags defaultFlags];
141
+ flags.underline = props.underline;
142
+ flags.superscript = props.superscript;
143
+ flags.subscript = props.subscript;
144
+ flags.latexMath = props.latexMath;
145
+ flags.highlight = props.highlight;
146
+ flags.hardSoftBreaks = props.hardSoftBreaks;
147
+ return flags;
163
148
  }
164
149
 
165
150
  - (instancetype)initWithFrame:(CGRect)frame
@@ -170,22 +155,31 @@ static char kENRMSegmentFadeAnimatorKey;
170
155
 
171
156
  self.backgroundColor = [RCTUIColor clearColor];
172
157
  _parser = [[ENRMMarkdownParser alloc] init];
158
+ _md4cFlags = [EnrichedMarkdown flagsFromProps:defaultProps->md4cFlags];
173
159
  _segmentViews = [NSMutableArray array];
174
160
  _segmentSignatures = [NSMutableArray array];
161
+ _dirtyFlags = ENRMDirtyNone;
175
162
  [self configureSegmentViewRegistry];
176
163
 
177
164
  _renderCoordinator =
178
165
  [[ENRMAsyncRenderCoordinator alloc] initWithQueueLabel:"com.swmansion.enriched.markdown.container.render"];
179
166
 
167
+ _maxFontSizeMultiplier = 0;
168
+ _allowTrailingMargin = NO;
180
169
  _selectable = YES;
181
170
  _enableLinkPreview = YES;
171
+ _enableTaskListItemToggle = YES;
172
+ _streamingAnimation = NO;
173
+ _tableStreamingMode = ENRMTableStreamingModeProgressive;
174
+ _codeBlockStreamingMode = ENRMCodeBlockStreamingModeProgressive;
175
+ _contextMenuHidden = NO;
182
176
  _selectionMenuConfig = (ENRMSelectionMenuConfig){.copyAsMarkdown = YES, .copyImageURL = YES};
177
+ _lineBreakStrategy = NSLineBreakStrategyNone;
178
+ _writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
183
179
  _resolvedLayoutDirection =
184
180
  [[RCTI18nUtil sharedInstance] isRTL] ? NSWritingDirectionRightToLeft : NSWritingDirectionLeftToRight;
185
181
 
186
182
  _fontScaleObserver = [[FontScaleObserver alloc] init];
187
- [self resetPropDerivedState];
188
-
189
183
  __weak EnrichedMarkdown *weakSelf = self;
190
184
  _fontScaleObserver.onChange = ^{
191
185
  EnrichedMarkdown *strongSelf = weakSelf;
@@ -273,6 +267,29 @@ static char kENRMSegmentFadeAnimatorKey;
273
267
  }]];
274
268
  #endif
275
269
 
270
+ [handlers addObject:[ENRMSegmentViewHandler handlerWithKind:ENRMSegmentKindCodeBlock
271
+ matchesView:^BOOL(RCTUIView *view, ENRMRenderedSegment *segment) {
272
+ return [view isKindOfClass:[ENRMCodeBlockContainerView class]];
273
+ }
274
+ createView:^RCTUIView *(ENRMRenderedSegment *segment) {
275
+ EnrichedMarkdown *strongSelf = weakSelf;
276
+ if (!strongSelf) {
277
+ return [[RCTUIView alloc] init];
278
+ }
279
+
280
+ ENRMCodeBlockContainerView *view =
281
+ [strongSelf createCodeBlockViewForSegment:segment.codeBlockSegment];
282
+ [strongSelf animateBlockViewIfNeeded:view];
283
+ return view;
284
+ }
285
+ updateView:^(RCTUIView *view, ENRMRenderedSegment *segment) {
286
+ EnrichedMarkdown *strongSelf = weakSelf;
287
+ ENRMCodeBlockContainerView *codeBlockView = (ENRMCodeBlockContainerView *)view;
288
+ codeBlockView.pending =
289
+ strongSelf && segment.codeBlockSegment == strongSelf->_pendingCodeBlockSegment;
290
+ [codeBlockView applyCodeBlockNode:segment.codeBlockSegment.codeBlockNode];
291
+ }]];
292
+
276
293
  _segmentViewRegistry = [[ENRMSegmentViewRegistry alloc] initWithHandlers:handlers];
277
294
  }
278
295
 
@@ -281,6 +298,29 @@ static char kENRMSegmentFadeAnimatorKey;
281
298
  if (_segmentViews.count == 0)
282
299
  return CGSizeZero;
283
300
 
301
+ if (applyFrames) {
302
+ CGFloat overhang = MAX(_config.tableHorizontalOverflow, 0);
303
+ BOOL needsOverhang = NO;
304
+ if (overhang > 0) {
305
+ for (RCTUIView *seg in _segmentViews) {
306
+ if ([seg isKindOfClass:[TableContainerView class]]) {
307
+ needsOverhang = YES;
308
+ break;
309
+ }
310
+ }
311
+ }
312
+ #if TARGET_OS_OSX
313
+ BOOL isClipping = self.layer.masksToBounds;
314
+ if (isClipping && needsOverhang)
315
+ self.layer.masksToBounds = NO;
316
+ else if (!isClipping && !needsOverhang)
317
+ self.layer.masksToBounds = YES;
318
+ #else
319
+ if (self.clipsToBounds != !needsOverhang)
320
+ self.clipsToBounds = !needsOverhang;
321
+ #endif
322
+ }
323
+
284
324
  __block CGFloat yOffset = 0.0;
285
325
  __block CGFloat maxContentWidth = 0.0;
286
326
  const NSUInteger lastIndex = _segmentViews.count - 1;
@@ -290,6 +330,7 @@ static char kENRMSegmentFadeAnimatorKey;
290
330
  const BOOL shouldAddBottomMargin = (!isLast || _allowTrailingMargin);
291
331
 
292
332
  CGFloat segmentHeight = 0;
333
+ const BOOL isTable = [segment isKindOfClass:[TableContainerView class]];
293
334
 
294
335
  if ([segment isKindOfClass:[EnrichedMarkdownInternalText class]]) {
295
336
  EnrichedMarkdownInternalText *textView = (EnrichedMarkdownInternalText *)segment;
@@ -298,7 +339,7 @@ static char kENRMSegmentFadeAnimatorKey;
298
339
  segmentHeight = textSize.height;
299
340
  maxContentWidth = MAX(maxContentWidth, textSize.width);
300
341
 
301
- } else if ([segment isKindOfClass:[TableContainerView class]]) {
342
+ } else if (isTable) {
302
343
  yOffset += _config.tableMarginTop;
303
344
  segmentHeight = [(TableContainerView *)segment measureHeight:width];
304
345
  maxContentWidth = width;
@@ -310,9 +351,23 @@ static char kENRMSegmentFadeAnimatorKey;
310
351
  maxContentWidth = width;
311
352
  }
312
353
  #endif
354
+ else if ([segment isKindOfClass:[ENRMCodeBlockContainerView class]]) {
355
+ yOffset += _config.codeBlockMarginTop;
356
+ segmentHeight = [(ENRMCodeBlockContainerView *)segment measureHeight:width];
357
+ maxContentWidth = width;
358
+ }
313
359
 
314
360
  if (applyFrames) {
315
- CGRect segmentFrame = CGRectMake(0, yOffset, width, segmentHeight);
361
+ CGFloat segmentX = 0;
362
+ CGFloat segmentWidth = width;
363
+ if (isTable) {
364
+ CGFloat overhang = MAX(_config.tableHorizontalOverflow, 0);
365
+ if (overhang > 0) {
366
+ segmentX = -overhang;
367
+ segmentWidth = width + overhang * 2;
368
+ }
369
+ }
370
+ CGRect segmentFrame = CGRectMake(segmentX, yOffset, segmentWidth, segmentHeight);
316
371
  segment.frame = segmentFrame;
317
372
  #if TARGET_OS_OSX
318
373
  if ([segment isKindOfClass:[EnrichedMarkdownInternalText class]]) {
@@ -335,6 +390,9 @@ static char kENRMSegmentFadeAnimatorKey;
335
390
  yOffset += _config.mathMarginBottom;
336
391
  }
337
392
  #endif
393
+ else if ([segment isKindOfClass:[ENRMCodeBlockContainerView class]] && shouldAddBottomMargin) {
394
+ yOffset += _config.codeBlockMarginBottom;
395
+ }
338
396
  }];
339
397
 
340
398
  return CGSizeMake(maxContentWidth, yOffset);
@@ -353,6 +411,11 @@ static char kENRMSegmentFadeAnimatorKey;
353
411
  return CGSizeMake(measuredWidth, measuredHeight);
354
412
  }
355
413
 
414
+ - (CGSize)lastCommittedLayoutSize
415
+ {
416
+ return _lastCommittedSize.load();
417
+ }
418
+
356
419
  - (BOOL)hasRenderedMarkdown:(NSString *)markdown
357
420
  {
358
421
  return _renderedMarkdown != nil && [_renderedMarkdown isEqualToString:markdown];
@@ -396,6 +459,8 @@ static char kENRMSegmentFadeAnimatorKey;
396
459
  {
397
460
  [super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
398
461
 
462
+ _lastCommittedSize.store(CGSizeMake(layoutMetrics.frame.size.width, layoutMetrics.frame.size.height));
463
+
399
464
  NSWritingDirection resolved = _resolvedLayoutDirection;
400
465
  if (layoutMetrics.layoutDirection == LayoutDirection::RightToLeft) {
401
466
  resolved = NSWritingDirectionRightToLeft;
@@ -450,14 +515,22 @@ static char kENRMSegmentFadeAnimatorKey;
450
515
  TableContainerView *tableView = (TableContainerView *)segment;
451
516
  tableView.copyLabel = _selectionMenuLabels.copyLabel;
452
517
  tableView.copyAsMarkdownLabel = _selectionMenuLabels.copyAsMarkdownLabel;
518
+ tableView.contextMenuHidden = _contextMenuHidden;
453
519
  }
454
520
  #if ENRICHED_MARKDOWN_MATH
455
521
  else if ([segment isKindOfClass:[ENRMMathContainerView class]]) {
456
522
  ENRMMathContainerView *mathView = (ENRMMathContainerView *)segment;
457
523
  mathView.copyLabel = _selectionMenuLabels.copyLabel;
458
524
  mathView.copyAsMarkdownLabel = _selectionMenuLabels.copyAsMarkdownLabel;
525
+ mathView.contextMenuHidden = _contextMenuHidden;
459
526
  }
460
527
  #endif
528
+ else if ([segment isKindOfClass:[ENRMCodeBlockContainerView class]]) {
529
+ ENRMCodeBlockContainerView *codeBlockView = (ENRMCodeBlockContainerView *)segment;
530
+ codeBlockView.copyLabel = _selectionMenuLabels.copyLabel;
531
+ codeBlockView.copyAsMarkdownLabel = _selectionMenuLabels.copyAsMarkdownLabel;
532
+ codeBlockView.contextMenuHidden = _contextMenuHidden;
533
+ }
461
534
  }
462
535
  }
463
536
 
@@ -466,6 +539,25 @@ static char kENRMSegmentFadeAnimatorKey;
466
539
  ENRMRequestHeightUpdate<EnrichedMarkdownState>(_state, _heightUpdateCounter, self);
467
540
  }
468
541
 
542
+ // A block image in one of the text segments resolved its box height after
543
+ // loading (maxHeight/aspectRatio sizing). The shadow node measured — and
544
+ // cached — this markdown with the pre-load fallback height, so drop those
545
+ // entries, re-stack segments, and re-measure.
546
+ - (void)imageAttachmentDidResolveLayout
547
+ {
548
+ if (_renderedMarkdown.length > 0) {
549
+ MeasurementCache::shared().removeMatchingMarkdown(std::string(_renderedMarkdown.UTF8String));
550
+ }
551
+
552
+ if (self.bounds.size.width > 0) {
553
+ [self setNeedsLayout];
554
+ CGSize measured = [self measureSize:self.bounds.size.width];
555
+ if (needsHeightUpdate(measured, self.bounds)) {
556
+ [self requestHeightUpdate];
557
+ }
558
+ }
559
+ }
560
+
469
561
  - (void)renderMarkdownContent:(NSString *)markdownString
470
562
  {
471
563
  if (_renderCoordinator.blockAsyncRender)
@@ -482,17 +574,21 @@ static char kENRMSegmentFadeAnimatorKey;
482
574
  BOOL allowTrailingMargin = _allowTrailingMargin;
483
575
  BOOL streamingAnimation = _streamingAnimation;
484
576
  ENRMTableStreamingMode tableStreamingMode = _tableStreamingMode;
577
+ ENRMCodeBlockStreamingMode codeBlockStreamingMode = _codeBlockStreamingMode;
485
578
  NSLineBreakStrategy lineBreakStrategy = _lineBreakStrategy;
486
579
  ENRMWritingDirectionMode writingDirectionMode = _writingDirectionMode;
487
580
  NSWritingDirection resolvedLayoutDirection = _resolvedLayoutDirection;
488
581
 
489
582
  __block NSArray<ENRMRenderedSegment *> *renderedSegments = nil;
490
583
  __block NSString *renderableMarkdown = nil;
584
+ __block BOOL endsInsideOpenCodeFence = NO;
491
585
 
492
586
  [_renderCoordinator
493
587
  scheduleRender:^BOOL {
494
- renderableMarkdown = streamingAnimation ? ENRMRenderableMarkdownForStreaming(markdownString, tableStreamingMode)
495
- : markdownString;
588
+ renderableMarkdown = streamingAnimation
589
+ ? ENRMRenderableMarkdownForStreaming(markdownString, tableStreamingMode,
590
+ codeBlockStreamingMode, &endsInsideOpenCodeFence)
591
+ : markdownString;
496
592
 
497
593
  if (renderableMarkdown.length == 0) {
498
594
  renderedSegments = @[];
@@ -515,7 +611,9 @@ static char kENRMSegmentFadeAnimatorKey;
515
611
  }
516
612
  apply:^{
517
613
  self->_renderedStyleFingerprint = self->_pendingStyleFingerprint;
518
- [self applyRenderedSegments:renderedSegments renderedMarkdown:renderableMarkdown];
614
+ [self applyRenderedSegments:renderedSegments
615
+ renderedMarkdown:renderableMarkdown
616
+ endsInsideOpenCodeFence:endsInsideOpenCodeFence];
519
617
  }];
520
618
  }
521
619
 
@@ -552,8 +650,11 @@ static char kENRMSegmentFadeAnimatorKey;
552
650
 
553
651
  _renderCoordinator.blockAsyncRender = YES;
554
652
  _cachedMarkdown = [markdownString copy];
653
+ BOOL endsInsideOpenCodeFence = NO;
555
654
  NSString *renderableMarkdown =
556
- _streamingAnimation ? ENRMRenderableMarkdownForStreaming(markdownString, _tableStreamingMode) : markdownString;
655
+ _streamingAnimation ? ENRMRenderableMarkdownForStreaming(markdownString, _tableStreamingMode,
656
+ _codeBlockStreamingMode, &endsInsideOpenCodeFence)
657
+ : markdownString;
557
658
  _renderedMarkdown = [renderableMarkdown copy];
558
659
  _renderedStyleFingerprint = _pendingStyleFingerprint;
559
660
 
@@ -566,6 +667,8 @@ static char kENRMSegmentFadeAnimatorKey;
566
667
  return;
567
668
  }
568
669
 
670
+ [self updatePendingCodeBlockSegment:endsInsideOpenCodeFence segments:renderedSegments];
671
+
569
672
  for (ENRMRenderedSegment *segment in renderedSegments) {
570
673
  RCTUIView *view = [_segmentViewRegistry createViewForSegment:segment];
571
674
  [_segmentViews addObject:view];
@@ -574,9 +677,24 @@ static char kENRMSegmentFadeAnimatorKey;
574
677
  }
575
678
  }
576
679
 
577
- - (void)applyRenderedSegments:(NSArray *)renderedSegments renderedMarkdown:(NSString *)renderedMarkdown
680
+ - (void)updatePendingCodeBlockSegment:(BOOL)endsInsideOpenCodeFence segments:(NSArray<ENRMRenderedSegment *> *)segments
681
+ {
682
+ _pendingCodeBlockSegment = nil;
683
+ if (!_streamingAnimation || !endsInsideOpenCodeFence) {
684
+ return;
685
+ }
686
+ ENRMRenderedSegment *last = segments.lastObject;
687
+ if (last.kind == ENRMSegmentKindCodeBlock) {
688
+ _pendingCodeBlockSegment = last.codeBlockSegment;
689
+ }
690
+ }
691
+
692
+ - (void)applyRenderedSegments:(NSArray *)renderedSegments
693
+ renderedMarkdown:(NSString *)renderedMarkdown
694
+ endsInsideOpenCodeFence:(BOOL)endsInsideOpenCodeFence
578
695
  {
579
696
  _renderedMarkdown = [renderedMarkdown copy];
697
+ [self updatePendingCodeBlockSegment:endsInsideOpenCodeFence segments:renderedSegments];
580
698
  BOOL segmentTopologyChanged = _streamingAnimation && [self renderedSegmentsChangeTopology:renderedSegments];
581
699
 
582
700
  ENRMSegmentReconciliationResult *result = [ENRMSegmentReconciler reconcileCurrentViews:_segmentViews
@@ -600,6 +718,15 @@ static char kENRMSegmentFadeAnimatorKey;
600
718
  _segmentViews = result.views;
601
719
  _segmentSignatures = result.signatures;
602
720
 
721
+ // A just-closed block has unchanged content, so the reconciler reuses it
722
+ // without an update; sync pending here to trigger its deferred highlight.
723
+ [_segmentViews enumerateObjectsUsingBlock:^(RCTUIView *segment, NSUInteger i, BOOL *stop) {
724
+ if ([segment isKindOfClass:[ENRMCodeBlockContainerView class]]) {
725
+ ((ENRMCodeBlockContainerView *)segment).pending =
726
+ self->_pendingCodeBlockSegment != nil && i == self->_segmentViews.count - 1;
727
+ }
728
+ }];
729
+
603
730
  if (self.bounds.size.width > 0) {
604
731
  [self setNeedsLayout];
605
732
 
@@ -647,6 +774,9 @@ static char kENRMSegmentFadeAnimatorKey;
647
774
  if (!strongSelf) {
648
775
  return baseMenu;
649
776
  }
777
+ if (strongSelf->_contextMenuHidden) {
778
+ return nil;
779
+ }
650
780
  NSString *segmentMarkdown = extractMarkdownFromAttributedString(textView.textStorage, textView.selectedRange);
651
781
  NSArray<NSMenuItem *> *customItems = ENRMBuildContextMenuItems(
652
782
  strongSelf->_contextMenuItemTexts, strongSelf->_contextMenuItemIcons, textView,
@@ -676,6 +806,7 @@ static char kENRMSegmentFadeAnimatorKey;
676
806
  tableView.accessibilityLabels = _accessibilityLabels;
677
807
  tableView.copyLabel = _selectionMenuLabels.copyLabel;
678
808
  tableView.copyAsMarkdownLabel = _selectionMenuLabels.copyAsMarkdownLabel;
809
+ tableView.contextMenuHidden = _contextMenuHidden;
679
810
 
680
811
  __weak EnrichedMarkdown *weakSelf = self;
681
812
 
@@ -715,11 +846,31 @@ static char kENRMSegmentFadeAnimatorKey;
715
846
  mathView.accessibilityLabels = _accessibilityLabels;
716
847
  mathView.copyLabel = _selectionMenuLabels.copyLabel;
717
848
  mathView.copyAsMarkdownLabel = _selectionMenuLabels.copyAsMarkdownLabel;
849
+ mathView.contextMenuHidden = _contextMenuHidden;
718
850
  [mathView applyLatex:mathSegment.latex];
719
851
  return mathView;
720
852
  }
721
853
  #endif
722
854
 
855
+ - (ENRMCodeBlockContainerView *)createCodeBlockViewForSegment:(ENRMCodeBlockSegment *)codeBlockSegment
856
+ {
857
+ ENRMCodeBlockContainerView *codeBlockView = [[ENRMCodeBlockContainerView alloc] initWithConfig:_config];
858
+ codeBlockView.copyLabel = _selectionMenuLabels.copyLabel;
859
+ codeBlockView.copyAsMarkdownLabel = _selectionMenuLabels.copyAsMarkdownLabel;
860
+ codeBlockView.contextMenuHidden = _contextMenuHidden;
861
+
862
+ __weak EnrichedMarkdown *weakSelf = self;
863
+ codeBlockView.onCopyPress = ^(NSString *code, NSString *language) {
864
+ EnrichedMarkdown *strongSelf = weakSelf;
865
+ if (strongSelf)
866
+ [strongSelf emitCopyPress:code language:language];
867
+ };
868
+
869
+ codeBlockView.pending = codeBlockSegment == _pendingCodeBlockSegment;
870
+ [codeBlockView applyCodeBlockNode:codeBlockSegment.codeBlockNode];
871
+ return codeBlockView;
872
+ }
873
+
723
874
  - (void)animateBlockViewIfNeeded:(RCTUIView *)view
724
875
  {
725
876
  if (!_streamingAnimation)
@@ -784,6 +935,14 @@ static char kENRMSegmentFadeAnimatorKey;
784
935
  }
785
936
  }
786
937
 
938
+ if (ENRMImageRequestHeadersChanged(oldViewProps.imageRequestHeaders, newViewProps.imageRequestHeaders)) {
939
+ [_config setImageRequestHeaders:ENRMImageRequestHeadersFromProps(newViewProps.imageRequestHeaders)];
940
+ _dirtyFlags |= ENRMDirtyRender;
941
+ if (!markdownChanged) {
942
+ _dirtyFlags |= ENRMDirtyRecreateSegments;
943
+ }
944
+ }
945
+
787
946
  _selectable = newViewProps.selectable;
788
947
 
789
948
  for (RCTUIView *segment in _segmentViews) {
@@ -816,28 +975,19 @@ static char kENRMSegmentFadeAnimatorKey;
816
975
  _dirtyFlags |= ENRMDirtyRecreateSegments | ENRMDirtyForceHeight | ENRMDirtyRender;
817
976
  }
818
977
 
819
- if (newViewProps.md4cFlags.underline != oldViewProps.md4cFlags.underline) {
820
- _md4cFlags.underline = newViewProps.md4cFlags.underline;
821
- _dirtyFlags |= ENRMDirtyForceHeight | ENRMDirtyRender;
822
- }
823
- if (newViewProps.md4cFlags.superscript != oldViewProps.md4cFlags.superscript) {
824
- _md4cFlags.superscript = newViewProps.md4cFlags.superscript;
825
- _dirtyFlags |= ENRMDirtyForceHeight | ENRMDirtyRender;
826
- }
827
- if (newViewProps.md4cFlags.subscript != oldViewProps.md4cFlags.subscript) {
828
- _md4cFlags.subscript = newViewProps.md4cFlags.subscript;
829
- _dirtyFlags |= ENRMDirtyForceHeight | ENRMDirtyRender;
830
- }
831
- if (newViewProps.md4cFlags.latexMath != oldViewProps.md4cFlags.latexMath) {
832
- _md4cFlags.latexMath = newViewProps.md4cFlags.latexMath;
833
- _dirtyFlags |= ENRMDirtyForceHeight | ENRMDirtyRender;
834
- }
835
- if (newViewProps.md4cFlags.highlight != oldViewProps.md4cFlags.highlight) {
836
- _md4cFlags.highlight = newViewProps.md4cFlags.highlight;
978
+ if (newViewProps.md4cFlags.underline != oldViewProps.md4cFlags.underline ||
979
+ newViewProps.md4cFlags.superscript != oldViewProps.md4cFlags.superscript ||
980
+ newViewProps.md4cFlags.subscript != oldViewProps.md4cFlags.subscript ||
981
+ newViewProps.md4cFlags.latexMath != oldViewProps.md4cFlags.latexMath ||
982
+ newViewProps.md4cFlags.highlight != oldViewProps.md4cFlags.highlight ||
983
+ newViewProps.md4cFlags.hardSoftBreaks != oldViewProps.md4cFlags.hardSoftBreaks) {
984
+ _md4cFlags = [EnrichedMarkdown flagsFromProps:newViewProps.md4cFlags];
837
985
  _dirtyFlags |= ENRMDirtyForceHeight | ENRMDirtyRender;
838
986
  }
839
987
 
840
988
  _enableLinkPreview = newViewProps.enableLinkPreview;
989
+ _enableTaskListItemToggle = newViewProps.enableTaskListItemToggle;
990
+ _contextMenuHidden = newViewProps.contextMenuHidden;
841
991
 
842
992
  if (newViewProps.streamingAnimation != oldViewProps.streamingAnimation) {
843
993
  _streamingAnimation = newViewProps.streamingAnimation;
@@ -862,6 +1012,14 @@ static char kENRMSegmentFadeAnimatorKey;
862
1012
  _dirtyFlags |= ENRMDirtyForceHeight | ENRMDirtyRender;
863
1013
  }
864
1014
 
1015
+ if (newViewProps.streamingConfig.codeBlockMode != oldViewProps.streamingConfig.codeBlockMode) {
1016
+ NSString *codeBlockModeStr =
1017
+ [[NSString alloc] initWithUTF8String:newViewProps.streamingConfig.codeBlockMode.c_str()];
1018
+ _codeBlockStreamingMode = [codeBlockModeStr isEqualToString:@"hidden"] ? ENRMCodeBlockStreamingModeHidden
1019
+ : ENRMCodeBlockStreamingModeProgressive;
1020
+ _dirtyFlags |= ENRMDirtyForceHeight | ENRMDirtyRender;
1021
+ }
1022
+
865
1023
  if (ENRMContextMenuItemsChanged(oldViewProps.contextMenuItems, newViewProps.contextMenuItems)) {
866
1024
  _contextMenuItemTexts = ENRMContextMenuTextsFromItems(newViewProps.contextMenuItems);
867
1025
  _contextMenuItemIcons = ENRMContextMenuIconsFromItems(newViewProps.contextMenuItems);
@@ -964,7 +1122,8 @@ static char kENRMSegmentFadeAnimatorKey;
964
1122
 
965
1123
  - (void)prepareForRecycle
966
1124
  {
967
- _props = std::make_shared<const EnrichedMarkdownProps>();
1125
+ const auto resetProps = std::make_shared<const EnrichedMarkdownProps>();
1126
+ _props = resetProps;
968
1127
  [_renderCoordinator invalidate];
969
1128
 
970
1129
  for (RCTUIView *segment in _segmentViews) {
@@ -982,8 +1141,31 @@ static char kENRMSegmentFadeAnimatorKey;
982
1141
 
983
1142
  _cachedMarkdown = nil;
984
1143
  _renderedMarkdown = nil;
1144
+ _config = nil;
1145
+ _md4cFlags = [EnrichedMarkdown flagsFromProps:resetProps->md4cFlags];
1146
+ _maxFontSizeMultiplier = 0;
1147
+ _allowTrailingMargin = NO;
1148
+ _streamingAnimation = NO;
1149
+ _tableStreamingMode = ENRMTableStreamingModeProgressive;
1150
+ _codeBlockStreamingMode = ENRMCodeBlockStreamingModeProgressive;
1151
+ _pendingCodeBlockSegment = nil;
1152
+ _lineBreakStrategy = NSLineBreakStrategyNone;
1153
+ _writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
1154
+ _renderedStyleFingerprint = 0;
1155
+ _pendingStyleFingerprint = 0;
1156
+ _contextMenuItemTexts = nil;
1157
+ _contextMenuItemIcons = nil;
1158
+ _fontScaleObserver.allowFontScaling = resetProps->allowFontScaling;
1159
+ _accessibilityLabels = nil;
1160
+ _spoilerOverlay =
1161
+ ENRMSpoilerOverlayFromString([[NSString alloc] initWithUTF8String:resetProps->spoilerOverlay.c_str()]);
1162
+ _dirtyFlags = ENRMDirtyNone;
985
1163
 
986
- [self resetPropDerivedState];
1164
+ // Ported from the fork's resetPropDerivedState: upstream's prepareForRecycle covers every
1165
+ // other prop-derived ivar but leaves these two, so a recycled view keeps the previous
1166
+ // consumer's height-update counter and a dangling shadow-node state handle.
1167
+ _heightUpdateCounter = 0;
1168
+ _state = nullptr;
987
1169
 
988
1170
  [super prepareForRecycle];
989
1171
  }
@@ -1084,6 +1266,14 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownCls(void)
1084
1266
  emitter->onTaskListItemPress({.index = (int)index, .checked = checked, .text = std::string(text.UTF8String ?: "")});
1085
1267
  }
1086
1268
 
1269
+ - (void)emitCopyPress:(NSString *)code language:(NSString *)language
1270
+ {
1271
+ auto emitter = std::static_pointer_cast<EnrichedMarkdownEventEmitter const>(_eventEmitter);
1272
+ if (emitter)
1273
+ emitter->onCopyPress(
1274
+ {.code = std::string(code.UTF8String ?: ""), .language = std::string(language.UTF8String ?: "")});
1275
+ }
1276
+
1087
1277
  - (void)emitContextMenuItemPress:(NSString *)itemText
1088
1278
  selectedText:(NSString *)selectedText
1089
1279
  selectionStart:(NSUInteger)selectionStart
@@ -1103,7 +1293,8 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownCls(void)
1103
1293
  {
1104
1294
  ENRMPlatformTextView *textView = (ENRMPlatformTextView *)recognizer.view;
1105
1295
 
1106
- if (handleTaskListTapWithSharedLogic(
1296
+ if (_enableTaskListItemToggle &&
1297
+ handleTaskListTapWithSharedLogic(
1107
1298
  textView, recognizer, &self->_cachedMarkdown, self->_config,
1108
1299
  ^(NSInteger index, BOOL checked, NSString *itemText) {
1109
1300
  [self emitTaskListItemPress:index checked:checked text:itemText];
@@ -1132,6 +1323,10 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownCls(void)
1132
1323
  editMenuForTextInRange:(NSRange)range
1133
1324
  suggestedActions:(NSArray<UIMenuElement *> *)suggestedActions API_AVAILABLE(ios(16.0))
1134
1325
  {
1326
+ if (_contextMenuHidden) {
1327
+ return nil;
1328
+ }
1329
+
1135
1330
  __weak EnrichedMarkdown *weakSelf = self;
1136
1331
  ENRMContextMenuPressHandler handler =
1137
1332
  ^(NSString *itemText, NSString *selectedText, NSUInteger selectionStart, NSUInteger selectionEnd) {
@@ -13,6 +13,13 @@ NS_ASSUME_NONNULL_BEGIN
13
13
  - (void)renderMarkdownSynchronously:(NSString *)markdownString;
14
14
  - (BOOL)hasRenderedMarkdown:(NSString *)markdown;
15
15
  - (BOOL)hasRenderedWithStyleFingerprint:(size_t)fingerprint;
16
+
17
+ /// Size last committed by Fabric via `updateLayoutMetrics:`, readable from
18
+ /// any thread without blocking (issue #550: the shadow-node measure path must
19
+ /// never wait on the main thread, and reading `bounds` off-main is unsafe).
20
+ /// Backed by a single lock-free atomic, so the pair can't tear. Returns
21
+ /// CGSizeZero until the first layout is committed.
22
+ - (CGSize)lastCommittedLayoutSize;
16
23
  @end
17
24
 
18
25
  NS_ASSUME_NONNULL_END