react-native-enriched-markdown-scaffold 0.7.4-scaffold.9 → 1.0.2-scaffold.2

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 +186 -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 +24 -0
  8. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +8 -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 +35 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +886 -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 +189 -13
  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 +54 -4
  26. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +901 -462
  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/FormattingStore.kt +80 -87
  43. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
  44. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +116 -22
  45. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
  46. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
  47. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
  48. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +4 -2
  49. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
  50. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
  51. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
  52. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
  53. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
  54. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
  55. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
  56. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
  58. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
  65. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
  66. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
  68. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
  69. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
  70. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
  71. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
  72. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
  73. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
  74. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
  75. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
  76. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +30 -27
  77. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
  78. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
  79. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +27 -3
  80. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
  81. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
  82. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
  83. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
  84. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
  85. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
  86. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
  87. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
  88. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
  89. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
  90. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
  91. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
  93. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
  94. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
  95. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
  96. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
  97. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
  98. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
  99. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
  100. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +37 -7
  101. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
  102. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
  103. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
  104. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
  105. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
  106. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
  107. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +20 -0
  108. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
  109. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
  110. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
  111. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
  112. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
  113. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
  114. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
  115. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
  116. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +49 -15
  117. package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +45 -0
  118. package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +396 -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 +36 -9
  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 +6 -4
  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 +234 -12
  152. package/docs/BREAKING_CHANGES.md +129 -0
  153. package/docs/CODE_HIGHLIGHT.md +133 -0
  154. package/docs/COPY_OPTIONS.md +47 -3
  155. package/docs/ELEMENTS_STRUCTURE.md +52 -4
  156. package/docs/IMAGE_CACHING.md +30 -0
  157. package/docs/INPUT.md +108 -11
  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 +284 -75
  169. package/ios/EnrichedMarkdownText.h +7 -0
  170. package/ios/EnrichedMarkdownText.mm +101 -73
  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 +35 -0
  179. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +886 -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/ENRMClipboardCoordinator.h +45 -0
  190. package/ios/input/ENRMClipboardCoordinator.mm +120 -0
  191. package/ios/input/ENRMDetectorPipeline.h +2 -1
  192. package/ios/input/ENRMEditPipeline.h +76 -0
  193. package/ios/input/ENRMEditPipeline.mm +228 -0
  194. package/ios/input/ENRMEditSession.h +36 -0
  195. package/ios/input/ENRMEditSession.mm +63 -0
  196. package/ios/input/ENRMFormattingStore.h +17 -0
  197. package/ios/input/ENRMFormattingStore.mm +95 -105
  198. package/ios/input/ENRMInputBlockType.h +91 -0
  199. package/ios/input/ENRMInputBlockType.mm +5 -0
  200. package/ios/input/ENRMInputDecorationDrawer.h +18 -0
  201. package/ios/input/ENRMInputEventEmitter.h +56 -0
  202. package/ios/input/ENRMInputEventEmitter.mm +308 -0
  203. package/ios/input/ENRMInputFormatter.h +29 -69
  204. package/ios/input/ENRMInputFormatter.mm +216 -124
  205. package/ios/input/ENRMInputFormatterStyle.h +99 -0
  206. package/ios/input/ENRMInputFormatterStyle.mm +188 -0
  207. package/ios/input/ENRMInputLayoutManager.h +9 -0
  208. package/ios/input/ENRMInputLayoutManager.mm +30 -0
  209. package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
  210. package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
  211. package/ios/input/ENRMInputParser.h +5 -6
  212. package/ios/input/ENRMInputParser.mm +461 -178
  213. package/ios/input/ENRMInputRemend.mm +2 -2
  214. package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
  215. package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
  216. package/ios/input/ENRMInputTextView.mm +103 -8
  217. package/ios/input/ENRMInputTypingAttributesController.h +42 -0
  218. package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
  219. package/ios/input/ENRMLinkCoordinator.h +41 -0
  220. package/ios/input/ENRMLinkCoordinator.mm +89 -0
  221. package/ios/input/ENRMMarkdownSerializer.h +29 -5
  222. package/ios/input/ENRMMarkdownSerializer.mm +170 -48
  223. package/ios/input/ENRMMathAtom.h +26 -0
  224. package/ios/input/ENRMMathAtom.mm +12 -0
  225. package/ios/input/ENRMMentionCoordinator.h +45 -0
  226. package/ios/input/ENRMMentionCoordinator.mm +167 -0
  227. package/ios/input/ENRMRangeEditAdjustment.h +38 -0
  228. package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
  229. package/ios/input/ENRMRangeStoreUtils.h +39 -0
  230. package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
  231. package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
  232. package/ios/input/EnrichedMarkdownTextInput.h +7 -1
  233. package/ios/input/EnrichedMarkdownTextInput.mm +1089 -1023
  234. package/ios/input/InputStylePropsUtils.h +109 -68
  235. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
  236. package/ios/input/styles/ENRMBlockHandler.h +46 -0
  237. package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
  238. package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
  239. package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
  240. package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
  241. package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
  242. package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
  243. package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
  244. package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
  245. package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
  246. package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
  247. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
  248. package/ios/internals/MeasurementCache.h +33 -7
  249. package/ios/internals/ShadowMeasurementUtils.h +63 -58
  250. package/ios/math/ENRMMathChipController.h +74 -0
  251. package/ios/math/ENRMMathChipController.mm +476 -0
  252. package/ios/math/ENRMRaTeXBridge.swift +4 -1
  253. package/ios/parser/ENRMMarkdownParser.h +1 -8
  254. package/ios/parser/ENRMMarkdownParser.mm +2 -11
  255. package/ios/parser/MarkdownASTNode.h +2 -1
  256. package/ios/parser/MarkdownParserBridge.mm +4 -0
  257. package/ios/renderer/AttributedRenderer.m +20 -2
  258. package/ios/renderer/BaseRenderer.h +17 -2
  259. package/ios/renderer/BaseRenderer.m +30 -0
  260. package/ios/renderer/BlockquoteRenderer.h +1 -1
  261. package/ios/renderer/BlockquoteRenderer.m +144 -35
  262. package/ios/renderer/CodeBlockRenderer.h +1 -1
  263. package/ios/renderer/CodeBlockRenderer.m +27 -23
  264. package/ios/renderer/CodeRenderer.h +1 -1
  265. package/ios/renderer/CodeRenderer.m +3 -1
  266. package/ios/renderer/ENRMImageRenderer.h +1 -1
  267. package/ios/renderer/ENRMImageRenderer.m +5 -1
  268. package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
  269. package/ios/renderer/ENRMMathInlineRenderer.m +5 -1
  270. package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
  271. package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
  272. package/ios/renderer/EmphasisRenderer.h +1 -1
  273. package/ios/renderer/EmphasisRenderer.m +3 -1
  274. package/ios/renderer/HeadingRenderer.h +1 -1
  275. package/ios/renderer/HeadingRenderer.m +13 -6
  276. package/ios/renderer/HighlightRenderer.h +1 -1
  277. package/ios/renderer/HighlightRenderer.m +3 -1
  278. package/ios/renderer/LinkRenderer.h +1 -1
  279. package/ios/renderer/LinkRenderer.m +3 -1
  280. package/ios/renderer/ListItemRenderer.h +13 -1
  281. package/ios/renderer/ListItemRenderer.m +102 -44
  282. package/ios/renderer/ListRenderer.h +2 -2
  283. package/ios/renderer/ListRenderer.m +63 -25
  284. package/ios/renderer/ParagraphRenderer.h +1 -1
  285. package/ios/renderer/ParagraphRenderer.m +16 -8
  286. package/ios/renderer/RenderContext.h +10 -0
  287. package/ios/renderer/RenderContext.m +44 -0
  288. package/ios/renderer/RendererFactory.m +14 -0
  289. package/ios/renderer/StrikethroughRenderer.h +1 -1
  290. package/ios/renderer/StrikethroughRenderer.m +3 -1
  291. package/ios/renderer/StrongRenderer.h +1 -1
  292. package/ios/renderer/StrongRenderer.m +3 -1
  293. package/ios/renderer/SubscriptRenderer.h +1 -1
  294. package/ios/renderer/SubscriptRenderer.m +3 -1
  295. package/ios/renderer/SuperscriptRenderer.h +1 -1
  296. package/ios/renderer/SuperscriptRenderer.m +3 -1
  297. package/ios/renderer/TextRenderer.h +2 -2
  298. package/ios/renderer/TextRenderer.m +3 -1
  299. package/ios/renderer/ThematicBreakRenderer.h +1 -1
  300. package/ios/renderer/ThematicBreakRenderer.m +3 -1
  301. package/ios/renderer/UnderlineRenderer.h +1 -1
  302. package/ios/renderer/UnderlineRenderer.m +3 -1
  303. package/ios/styles/StyleConfig.h +22 -0
  304. package/ios/styles/StyleConfig.mm +132 -0
  305. package/ios/utils/BlockquoteBorder.h +6 -0
  306. package/ios/utils/BlockquoteBorder.m +249 -52
  307. package/ios/utils/CodeBlockBackground.m +16 -2
  308. package/ios/utils/ENRMAtomicSize.h +65 -0
  309. package/ios/utils/ENRMBlockMenu.h +57 -0
  310. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  311. package/ios/utils/ENRMCodeBlockContent.mm +79 -0
  312. package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
  313. package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
  314. package/ios/utils/ENRMFeatureFlags.h +7 -0
  315. package/ios/utils/ENRMImageDownloader.h +11 -1
  316. package/ios/utils/ENRMImageDownloader.m +60 -16
  317. package/ios/utils/ENRMLocalImageLoader.h +31 -0
  318. package/ios/utils/ENRMLocalImageLoader.m +68 -0
  319. package/ios/utils/ENRMMathFallback.h +26 -0
  320. package/ios/utils/ENRMMathFallback.m +18 -0
  321. package/ios/utils/ENRMTextViewSetup.h +35 -17
  322. package/ios/utils/EditMenuUtils.h +22 -5
  323. package/ios/utils/EditMenuUtils.m +53 -9
  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 +53 -0
  338. package/ios/views/ENRMCodeBlockContainerView.m +559 -0
  339. package/ios/views/ENRMMathContainerView.h +16 -0
  340. package/ios/views/ENRMMathContainerView.m +74 -19
  341. package/ios/views/TableContainerView.h +22 -0
  342. package/ios/views/TableContainerView.m +261 -175
  343. package/jest.d.ts +1 -0
  344. package/jest.js +5 -0
  345. package/lib/module/EnrichedMarkdownNativeComponent.ts +73 -0
  346. package/lib/module/EnrichedMarkdownTextInput.js +84 -5
  347. package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
  348. package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  349. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +74 -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 +37 -5
  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 +66 -0
  383. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
  384. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +94 -9
  385. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
  386. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +69 -5
  387. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
  388. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +66 -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 +104 -9
  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 +73 -0
  433. package/src/EnrichedMarkdownTextInput.tsx +159 -8
  434. package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  435. package/src/EnrichedMarkdownTextNativeComponent.ts +74 -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 +53 -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 +101 -9
  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
@@ -0,0 +1,331 @@
1
+ #pragma once
2
+
3
+ #import "ENRMCodeBlockContainerView.h"
4
+ #import "ENRMFeatureFlags.h"
5
+ #import "ENRMMarkdownParser.h"
6
+ #import "ENRMTextRenderer.h"
7
+ #import "ENRMTextViewSetup.h"
8
+ #import "ImageRequestHeaderUtils.h"
9
+ #import "MarkdownASTNode.h"
10
+ #import "ParagraphStyleUtils.h"
11
+ #import "RenderedMarkdownSegment.h"
12
+ #import "SegmentRenderer.h"
13
+ #import "StreamingMarkdownFilter.h"
14
+ #import "StylePropsUtils.h"
15
+ #import "TableContainerView.h"
16
+ #include <type_traits>
17
+ #if ENRICHED_MARKDOWN_MATH
18
+ #import "ENRMMathContainerView.h"
19
+ #endif
20
+
21
+ /**
22
+ * View-free markdown measurement (issue #550).
23
+ *
24
+ * The previous measurement path built throwaway component views on the main
25
+ * thread via `dispatch_sync` — a deadlock when `measureContent` runs under
26
+ * RN's locked commit fallback while a main-thread committer (Reanimated) is
27
+ * blocked on the same mutex, and a serialization bottleneck (streaming jank)
28
+ * even when it doesn't deadlock.
29
+ *
30
+ * These pipelines measure on the calling thread with no view and no
31
+ * main-thread dependency, mirroring RN core's `RCTTextLayoutManager` (which
32
+ * measures every `<Text>` this way in production) and this library's own
33
+ * Android `MeasurementStore`:
34
+ *
35
+ * - `ENRMMeasureMarkdownViewFree` (EnrichedMarkdownText): parse (md4c) →
36
+ * `ENRMRenderASTNodes` (the SAME renderer the visible view uses, so
37
+ * measured layout ≡ rendered layout) → a fresh per-call
38
+ * NSTextStorage/NSLayoutManager/NSTextContainer stack → shared finalize.
39
+ * - `ENRMMeasureSegmentedMarkdownViewFree` (EnrichedMarkdown): the iOS
40
+ * counterpart of Android's `MeasurementStore.measureAndCacheSplit` — split
41
+ * the AST into segments via the same `ENRMRenderSegmentsFromAST` the view
42
+ * uses, then walk them exactly like the view's
43
+ * `computeSegmentLayoutForWidth:`: text via the TextKit stack, tables via
44
+ * `+[TableContainerView measureHeightForTableNode:…]`, math via
45
+ * `+[ENRMMathContainerView measureHeightForLatex:…]`, with the same
46
+ * margin arithmetic.
47
+ *
48
+ * TextKit objects are thread-CONFINED, not main-thread-only: safe off main as
49
+ * long as one thread owns a given stack (Apple-sanctioned; the
50
+ * Texture/AsyncDisplayKit pattern). Allocating the stack per call — exactly
51
+ * what `RCTTextLayoutManager` does — makes confinement trivially true.
52
+ * `boundingRectWithSize:` (tables, math fallback) is documented thread-safe.
53
+ *
54
+ * Ambient-state rules for this path:
55
+ * - Font scale comes in as a parameter (from `LayoutContext::fontSizeMultiplier`),
56
+ * never from `RCTFontSizeMultiplier()` (UIKit read).
57
+ * - Pixel rounding uses `LayoutContext::pointScaleFactor`, never
58
+ * `RCTScreenScale()` (dispatch_syncs to main on first use).
59
+ * - The resolved layout direction comes from `LayoutConstraints::layoutDirection`,
60
+ * never from `RCTI18nUtil`.
61
+ * - The geometry config must match the visible view's
62
+ * (`ENRMConfigureMarkdownTextView`): zero insets, `lineFragmentPadding = 0`,
63
+ * `allowsNonContiguousLayout = NO`. The view's custom `TextViewLayoutManager`
64
+ * subclass only draws backgrounds and does not affect geometry.
65
+ * - Each entry point drains its own `@autoreleasepool`. The calling JS/layout
66
+ * thread has no runloop draining pools, and a full measure autoreleases
67
+ * thousands of objects (AST, attributed string, TextKit stack, fonts) — the
68
+ * old main-thread path silently leaned on the main runloop's per-cycle
69
+ * drain, and without a local pool sustained re-measurement accumulates
70
+ * until jetsam kills the app.
71
+ *
72
+ * RaTeX concurrency (math segments and lazily-measured inline math
73
+ * attachments now parse on the calling thread, possibly concurrently with the
74
+ * render thread): verified safe against RaTeX sources. The Swift engine is
75
+ * stateless per call, font registration is NSLock-guarded and idempotent
76
+ * (RaTeXFontLoader), the FFI's last-error slot is thread_local, the Rust
77
+ * core's only statics are immutable OnceLock/LazyLock tables, and renderer
78
+ * font caches are per-call locals.
79
+ */
80
+
81
+ template <typename Md4cFlagsT> static inline ENRMMd4cFlags *ENRMMd4cFlagsFromProps(const Md4cFlagsT &props)
82
+ {
83
+ ENRMMd4cFlags *flags = [ENRMMd4cFlags defaultFlags];
84
+ flags.underline = props.underline;
85
+ flags.superscript = props.superscript;
86
+ flags.subscript = props.subscript;
87
+ flags.latexMath = props.latexMath;
88
+ flags.highlight = props.highlight;
89
+ flags.hardSoftBreaks = props.hardSoftBreaks;
90
+ return flags;
91
+ }
92
+
93
+ /**
94
+ * Builds a StyleConfig from props alone, replicating the mock-view recipe
95
+ * field for field: a fresh config receives the props' style diffed against a
96
+ * default-constructed style struct (the mock view's `updateProps
97
+ * oldProps:nullptr` applied the same diff against default props), then the
98
+ * font scale, max multiplier, and image request headers.
99
+ */
100
+ template <typename PropsT>
101
+ static inline StyleConfig *ENRMStyleConfigFromProps(const PropsT &typedProps, CGFloat fontScale)
102
+ {
103
+ StyleConfig *config = [[StyleConfig alloc] init];
104
+ using StyleT = std::remove_cv_t<std::remove_reference_t<decltype(typedProps.markdownStyle)>>;
105
+ static const StyleT kDefaultStyle{};
106
+ applyMarkdownStyleToConfig(config, typedProps.markdownStyle, kDefaultStyle);
107
+ [config setFontScaleMultiplier:fontScale];
108
+ [config setMaxFontSizeMultiplier:typedProps.maxFontSizeMultiplier];
109
+ [config setImageRequestHeaders:ENRMImageRequestHeadersFromProps(typedProps.imageRequestHeaders)];
110
+ return config;
111
+ }
112
+
113
+ /**
114
+ * Lays out an already-rendered attributed string in a fresh, call-confined
115
+ * TextKit stack and finalizes with the shared algorithm
116
+ * (`ENRMFinalizeMeasuredTextSize`). Returns CGSizeZero for empty text — the
117
+ * same result the view path produces, and a guard against TextKit's
118
+ * empty-string layout freeze (see RCTTextLayoutManager).
119
+ *
120
+ * `usesFontLeading` must be NO: a raw NSLayoutManager defaults to YES and
121
+ * adds the used fonts' leading on top of the paragraph style's line-height
122
+ * clamp, while the UITextView the visible view renders with does not. Fonts
123
+ * pulled in by glyph fallback make this observable — Geeza Pro (Arabic)
124
+ * carries nonzero leading, so with YES every Arabic-script line measures
125
+ * taller than it renders and the surplus pools as phantom bottom space.
126
+ * RCTTextLayoutManager disables it for the same view-parity reason.
127
+ */
128
+ static inline CGSize ENRMMeasureAttributedTextViewFree(NSAttributedString *text, CGFloat maxWidth, StyleConfig *config,
129
+ BOOL allowTrailingMargin, CGFloat lastElementMarginBottom,
130
+ CGFloat pointScaleFactor)
131
+ {
132
+ if (text.length == 0) {
133
+ return CGSizeZero;
134
+ }
135
+
136
+ NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(maxWidth, CGFLOAT_MAX)];
137
+ textContainer.lineFragmentPadding = 0;
138
+ NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
139
+ layoutManager.allowsNonContiguousLayout = NO;
140
+ layoutManager.usesFontLeading = NO;
141
+ [layoutManager addTextContainer:textContainer];
142
+ NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:text];
143
+ [textStorage addLayoutManager:layoutManager];
144
+
145
+ [layoutManager ensureLayoutForTextContainer:textContainer];
146
+ ENRMTextLayoutResult layout;
147
+ layout.usedRect = [layoutManager usedRectForTextContainer:textContainer];
148
+ layout.extraLineFragmentRect = layoutManager.extraLineFragmentRect;
149
+
150
+ return ENRMFinalizeMeasuredTextSize(layout, layoutManager, text, maxWidth, config, allowTrailingMargin,
151
+ lastElementMarginBottom, pointScaleFactor);
152
+ }
153
+
154
+ /**
155
+ * Measures EnrichedMarkdownText content from props alone, on the calling
156
+ * thread. The line-break strategy and writing-direction mode are resolved
157
+ * from the props exactly as `updateProps:` resolves them. Falls back to
158
+ * (maxWidth × system-16 line height) for empty markdown, parse failures, and
159
+ * empty render output — the same fallback `measureSize:` produced.
160
+ */
161
+ template <typename PropsT>
162
+ static inline CGSize ENRMMeasureMarkdownViewFree(const PropsT &typedProps, CGFloat maxWidth, CGFloat fontScale,
163
+ CGFloat pointScaleFactor, NSWritingDirection resolvedLayoutDirection)
164
+ {
165
+ @autoreleasepool {
166
+ CGSize fallback = CGSizeMake(maxWidth, UIFontLineHeight([UIFont systemFontOfSize:16.0]));
167
+ if (typedProps.markdown.empty()) {
168
+ return fallback;
169
+ }
170
+
171
+ NSString *markdown = [[NSString alloc] initWithUTF8String:typedProps.markdown.c_str()];
172
+ StyleConfig *config = ENRMStyleConfigFromProps(typedProps, fontScale);
173
+
174
+ ENRMMd4cFlags *flags = ENRMMd4cFlagsFromProps(typedProps.md4cFlags);
175
+ ENRMMarkdownParser *parser = [[ENRMMarkdownParser alloc] init];
176
+ MarkdownASTNode *ast = [parser parseMarkdown:markdown flags:flags];
177
+ if (!ast) {
178
+ return fallback;
179
+ }
180
+
181
+ NSLineBreakStrategy lineBreakStrategy =
182
+ ENRMResolveLineBreakStrategy([[NSString alloc] initWithUTF8String:typedProps.lineBreakStrategyIOS.c_str()]);
183
+ ENRMRenderResult *result =
184
+ ENRMRenderASTNodes(ast.children, config, typedProps.allowTrailingMargin, typedProps.allowFontScaling,
185
+ typedProps.maxFontSizeMultiplier, lineBreakStrategy);
186
+ NSMutableAttributedString *text = result.attributedText;
187
+ if (text.length == 0) {
188
+ return fallback;
189
+ }
190
+
191
+ ENRMWritingDirectionMode writingDirectionMode =
192
+ ENRMResolveWritingDirectionMode([[NSString alloc] initWithUTF8String:typedProps.writingDirection.c_str()]);
193
+ ENRMApplyWritingDirectionMode(text, writingDirectionMode, resolvedLayoutDirection);
194
+
195
+ CGSize size = ENRMMeasureAttributedTextViewFree(text, maxWidth, config, typedProps.allowTrailingMargin,
196
+ result.lastElementMarginBottom, pointScaleFactor);
197
+ if (size.height == 0) {
198
+ return fallback;
199
+ }
200
+ return size;
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Measures segmented EnrichedMarkdown content from props alone, on the
206
+ * calling thread, replicating the view path end to end: the streaming table
207
+ * filter (`ENRMRenderableMarkdownForStreaming` with the props'
208
+ * streamingConfig.tableMode), the segment split and per-segment rendering
209
+ * (`ENRMRenderSegmentsFromAST` + per-text-segment writing direction — the
210
+ * same calls `renderMarkdownContent:` makes), then the walk from
211
+ * `computeSegmentLayoutForWidth:`: text segments include their trailing
212
+ * margin unless last (`!isLast || allowTrailingMargin`), table and math
213
+ * segments add their config marginTop before and marginBottom after under the
214
+ * same condition, tables report full width. Finishes with `measureSize:`'s
215
+ * pixel rounding (width capped at maxWidth) and its
216
+ * (maxWidth × system-16 line height) fallback for empty/failed content.
217
+ */
218
+ template <typename PropsT>
219
+ static inline CGSize ENRMMeasureSegmentedMarkdownViewFree(const PropsT &typedProps, CGFloat maxWidth, CGFloat fontScale,
220
+ CGFloat pointScaleFactor,
221
+ NSWritingDirection resolvedLayoutDirection)
222
+ {
223
+ @autoreleasepool {
224
+ CGSize fallback = CGSizeMake(maxWidth, UIFontLineHeight([UIFont systemFontOfSize:16.0]));
225
+ if (typedProps.markdown.empty()) {
226
+ return fallback;
227
+ }
228
+
229
+ NSString *markdown = [[NSString alloc] initWithUTF8String:typedProps.markdown.c_str()];
230
+
231
+ if (typedProps.streamingAnimation) {
232
+ NSString *tableModeStr = [[NSString alloc] initWithUTF8String:typedProps.streamingConfig.tableMode.c_str()];
233
+ ENRMTableStreamingMode tableStreamingMode =
234
+ [tableModeStr isEqualToString:@"hidden"] ? ENRMTableStreamingModeHidden : ENRMTableStreamingModeProgressive;
235
+ NSString *codeBlockModeStr =
236
+ [[NSString alloc] initWithUTF8String:typedProps.streamingConfig.codeBlockMode.c_str()];
237
+ ENRMCodeBlockStreamingMode codeBlockStreamingMode = [codeBlockModeStr isEqualToString:@"hidden"]
238
+ ? ENRMCodeBlockStreamingModeHidden
239
+ : ENRMCodeBlockStreamingModeProgressive;
240
+ markdown = ENRMRenderableMarkdownForStreaming(markdown, tableStreamingMode, codeBlockStreamingMode, NULL);
241
+ if (markdown.length == 0) {
242
+ return fallback;
243
+ }
244
+ }
245
+
246
+ StyleConfig *config = ENRMStyleConfigFromProps(typedProps, fontScale);
247
+
248
+ ENRMMd4cFlags *flags = ENRMMd4cFlagsFromProps(typedProps.md4cFlags);
249
+ ENRMMarkdownParser *parser = [[ENRMMarkdownParser alloc] init];
250
+ MarkdownASTNode *ast = [parser parseMarkdown:markdown flags:flags];
251
+ if (!ast) {
252
+ return fallback;
253
+ }
254
+
255
+ NSLineBreakStrategy lineBreakStrategy =
256
+ ENRMResolveLineBreakStrategy([[NSString alloc] initWithUTF8String:typedProps.lineBreakStrategyIOS.c_str()]);
257
+ ENRMWritingDirectionMode writingDirectionMode =
258
+ ENRMResolveWritingDirectionMode([[NSString alloc] initWithUTF8String:typedProps.writingDirection.c_str()]);
259
+
260
+ NSArray<ENRMRenderedSegment *> *segments =
261
+ ENRMRenderSegmentsFromAST(ast, config, typedProps.allowTrailingMargin, typedProps.allowFontScaling,
262
+ typedProps.maxFontSizeMultiplier, lineBreakStrategy);
263
+ for (ENRMRenderedSegment *segment in segments) {
264
+ if (segment.kind == ENRMSegmentKindText && segment.textResult) {
265
+ ENRMApplyWritingDirectionMode(segment.textResult.attributedText, writingDirectionMode, resolvedLayoutDirection);
266
+ }
267
+ }
268
+
269
+ if (segments.count == 0) {
270
+ return fallback;
271
+ }
272
+
273
+ CGFloat yOffset = 0.0;
274
+ CGFloat maxContentWidth = 0.0;
275
+ const NSUInteger lastIndex = segments.count - 1;
276
+
277
+ for (NSUInteger i = 0; i < segments.count; i++) {
278
+ ENRMRenderedSegment *segment = segments[i];
279
+ const BOOL isLast = (i == lastIndex);
280
+ const BOOL shouldAddBottomMargin = (!isLast || typedProps.allowTrailingMargin);
281
+
282
+ if (segment.kind == ENRMSegmentKindText && segment.textResult) {
283
+ CGSize textSize = ENRMMeasureAttributedTextViewFree(
284
+ segment.textResult.attributedText, maxWidth, config, shouldAddBottomMargin,
285
+ segment.textResult.lastElementMarginBottom, pointScaleFactor);
286
+ yOffset += textSize.height;
287
+ maxContentWidth = MAX(maxContentWidth, textSize.width);
288
+ } else if (segment.kind == ENRMSegmentKindTable && segment.tableSegment) {
289
+ yOffset += config.tableMarginTop;
290
+ yOffset += [TableContainerView measureHeightForTableNode:segment.tableSegment.tableNode
291
+ config:config
292
+ allowFontScaling:typedProps.allowFontScaling
293
+ maxFontSizeMultiplier:typedProps.maxFontSizeMultiplier
294
+ writingDirectionMode:writingDirectionMode
295
+ resolvedLayoutDirection:resolvedLayoutDirection];
296
+ maxContentWidth = maxWidth;
297
+ if (shouldAddBottomMargin) {
298
+ yOffset += config.tableMarginBottom;
299
+ }
300
+ } else if (segment.kind == ENRMSegmentKindCodeBlock && segment.codeBlockSegment) {
301
+ yOffset += config.codeBlockMarginTop;
302
+ yOffset += [ENRMCodeBlockContainerView measureHeightForCodeBlockNode:segment.codeBlockSegment.codeBlockNode
303
+ config:config];
304
+ maxContentWidth = maxWidth;
305
+ if (shouldAddBottomMargin) {
306
+ yOffset += config.codeBlockMarginBottom;
307
+ }
308
+ }
309
+ #if ENRICHED_MARKDOWN_MATH
310
+ else if (segment.kind == ENRMSegmentKindMath && segment.mathSegment) {
311
+ yOffset += config.mathMarginTop;
312
+ yOffset += [ENRMMathContainerView measureHeightForLatex:segment.mathSegment.latex
313
+ config:config
314
+ maxWidth:maxWidth];
315
+ maxContentWidth = maxWidth;
316
+ if (shouldAddBottomMargin) {
317
+ yOffset += config.mathMarginBottom;
318
+ }
319
+ }
320
+ #endif
321
+ }
322
+
323
+ if (yOffset == 0) {
324
+ return fallback;
325
+ }
326
+
327
+ CGFloat measuredWidth = MIN(ceil(maxContentWidth * pointScaleFactor) / pointScaleFactor, maxWidth);
328
+ CGFloat measuredHeight = ceil(yOffset * pointScaleFactor) / pointScaleFactor;
329
+ return CGSizeMake(measuredWidth, measuredHeight);
330
+ }
331
+ }
@@ -35,9 +35,7 @@ public:
35
35
  private:
36
36
  int localHeightRecalculationCounter_{0};
37
37
  mutable int lastExactMeasurementCounter_{0};
38
-
39
- // Creates mock view off-screen for initial measurement when real view doesn't exist
40
- id setupMockEnrichedMarkdown_(CGFloat width) const;
38
+ mutable CGSize lastExactMeasurementSize_{0, 0};
41
39
  };
42
40
 
43
41
  } // namespace facebook::react
@@ -1,4 +1,5 @@
1
1
  #import "EnrichedMarkdownShadowNode.h"
2
+ #import "ENRMViewFreeMeasurement.h"
2
3
  #import "EnrichedMarkdown.h"
3
4
  #import "ShadowMeasurementUtils.h"
4
5
  #import <yoga/Yoga.h>
@@ -19,7 +20,9 @@ EnrichedMarkdownShadowNode::EnrichedMarkdownShadowNode(const ShadowNode &sourceS
19
20
  localHeightRecalculationCounter_(
20
21
  static_cast<const EnrichedMarkdownShadowNode &>(sourceShadowNode).localHeightRecalculationCounter_),
21
22
  lastExactMeasurementCounter_(
22
- static_cast<const EnrichedMarkdownShadowNode &>(sourceShadowNode).lastExactMeasurementCounter_)
23
+ static_cast<const EnrichedMarkdownShadowNode &>(sourceShadowNode).lastExactMeasurementCounter_),
24
+ lastExactMeasurementSize_(
25
+ static_cast<const EnrichedMarkdownShadowNode &>(sourceShadowNode).lastExactMeasurementSize_)
23
26
  {
24
27
  const auto &oldProps = *std::static_pointer_cast<const EnrichedMarkdownProps>(sourceShadowNode.getProps());
25
28
  const auto &newProps = *std::static_pointer_cast<const EnrichedMarkdownProps>(this->getProps());
@@ -42,32 +45,25 @@ void EnrichedMarkdownShadowNode::dirtyLayoutIfNeeded()
42
45
  }
43
46
  }
44
47
 
45
- id EnrichedMarkdownShadowNode::setupMockEnrichedMarkdown_(CGFloat width) const
46
- {
47
- EnrichedMarkdown *mockView = [[EnrichedMarkdown alloc] initWithFrame:CGRectMake(20000, 20000, width, 1000)];
48
-
49
- const auto props = this->getProps();
50
- [mockView updateProps:props oldProps:nullptr];
51
-
52
- const auto &typedProps = *std::static_pointer_cast<const EnrichedMarkdownProps>(props);
53
- if (!typedProps.markdown.empty()) {
54
- NSString *markdown = [NSString stringWithUTF8String:typedProps.markdown.c_str()];
55
- [mockView renderMarkdownSynchronously:markdown];
56
- }
57
-
58
- return mockView;
59
- }
60
-
61
48
  Size EnrichedMarkdownShadowNode::measureContent(const LayoutContext &layoutContext,
62
49
  const LayoutConstraints &layoutConstraints) const
63
50
  {
64
- const auto &typedProps = *std::static_pointer_cast<const EnrichedMarkdownProps>(this->getProps());
51
+ const auto propsHandle = std::static_pointer_cast<const EnrichedMarkdownProps>(this->getProps());
52
+ const auto &typedProps = *propsHandle;
65
53
  const int receivedCounter = getStateData().getHeightRecalculationCounter();
54
+ const EnrichedMarkdownProps *props = propsHandle.get();
55
+ CGFloat pointScaleFactor = layoutContext.pointScaleFactor;
56
+ NSWritingDirection resolvedLayoutDirection = layoutConstraints.layoutDirection == LayoutDirection::RightToLeft
57
+ ? NSWritingDirectionRightToLeft
58
+ : NSWritingDirectionLeftToRight;
66
59
 
67
60
  return ENRMMeasureMarkdownContent<EnrichedMarkdownProps, EnrichedMarkdown>(
68
61
  typedProps, getStateData().getComponentViewRef(), receivedCounter, lastExactMeasurementCounter_,
69
- MarkdownFlavor::GitHub, layoutConstraints,
70
- ^(CGFloat width) { return (EnrichedMarkdown *)setupMockEnrichedMarkdown_(width); });
62
+ lastExactMeasurementSize_, MarkdownFlavor::GitHub, layoutContext, layoutConstraints,
63
+ ^(EnrichedMarkdown *view, CGFloat maxWidth, CGFloat fontScale) {
64
+ return ENRMMeasureSegmentedMarkdownViewFree(*props, maxWidth, fontScale, pointScaleFactor,
65
+ resolvedLayoutDirection);
66
+ });
71
67
  }
72
68
 
73
69
  } // namespace facebook::react
@@ -37,9 +37,7 @@ public:
37
37
  private:
38
38
  int localHeightRecalculationCounter_{0};
39
39
  mutable int lastExactMeasurementCounter_{0};
40
-
41
- // Creates mock view off-screen for initial measurement when real view doesn't exist
42
- id setupMockEnrichedMarkdownText_(CGFloat width) const;
40
+ mutable CGSize lastExactMeasurementSize_{0, 0};
43
41
  };
44
42
 
45
43
  } // namespace facebook::react
@@ -1,4 +1,5 @@
1
1
  #import "EnrichedMarkdownTextShadowNode.h"
2
+ #import "ENRMViewFreeMeasurement.h"
2
3
  #import "EnrichedMarkdownText.h"
3
4
  #import "ShadowMeasurementUtils.h"
4
5
  #import <yoga/Yoga.h>
@@ -20,7 +21,9 @@ EnrichedMarkdownTextShadowNode::EnrichedMarkdownTextShadowNode(const ShadowNode
20
21
  localHeightRecalculationCounter_(
21
22
  static_cast<const EnrichedMarkdownTextShadowNode &>(sourceShadowNode).localHeightRecalculationCounter_),
22
23
  lastExactMeasurementCounter_(
23
- static_cast<const EnrichedMarkdownTextShadowNode &>(sourceShadowNode).lastExactMeasurementCounter_)
24
+ static_cast<const EnrichedMarkdownTextShadowNode &>(sourceShadowNode).lastExactMeasurementCounter_),
25
+ lastExactMeasurementSize_(
26
+ static_cast<const EnrichedMarkdownTextShadowNode &>(sourceShadowNode).lastExactMeasurementSize_)
24
27
  {
25
28
  const auto &oldProps = *std::static_pointer_cast<const EnrichedMarkdownTextProps>(sourceShadowNode.getProps());
26
29
  const auto &newProps = *std::static_pointer_cast<const EnrichedMarkdownTextProps>(this->getProps());
@@ -43,32 +46,24 @@ void EnrichedMarkdownTextShadowNode::dirtyLayoutIfNeeded()
43
46
  }
44
47
  }
45
48
 
46
- id EnrichedMarkdownTextShadowNode::setupMockEnrichedMarkdownText_(CGFloat width) const
47
- {
48
- EnrichedMarkdownText *mockView = [[EnrichedMarkdownText alloc] initWithFrame:CGRectMake(20000, 20000, width, 1000)];
49
-
50
- const auto props = this->getProps();
51
- [mockView updateProps:props oldProps:nullptr];
52
-
53
- const auto &typedProps = *std::static_pointer_cast<const EnrichedMarkdownTextProps>(props);
54
- if (!typedProps.markdown.empty()) {
55
- NSString *markdown = [NSString stringWithUTF8String:typedProps.markdown.c_str()];
56
- [mockView renderMarkdownSynchronously:markdown];
57
- }
58
-
59
- return mockView;
60
- }
61
-
62
49
  Size EnrichedMarkdownTextShadowNode::measureContent(const LayoutContext &layoutContext,
63
50
  const LayoutConstraints &layoutConstraints) const
64
51
  {
65
- const auto &typedProps = *std::static_pointer_cast<const EnrichedMarkdownTextProps>(this->getProps());
52
+ const auto propsHandle = std::static_pointer_cast<const EnrichedMarkdownTextProps>(this->getProps());
53
+ const auto &typedProps = *propsHandle;
66
54
  const int receivedCounter = getStateData().getHeightRecalculationCounter();
55
+ const EnrichedMarkdownTextProps *props = propsHandle.get();
56
+ CGFloat pointScaleFactor = layoutContext.pointScaleFactor;
57
+ NSWritingDirection resolvedLayoutDirection = layoutConstraints.layoutDirection == LayoutDirection::RightToLeft
58
+ ? NSWritingDirectionRightToLeft
59
+ : NSWritingDirectionLeftToRight;
67
60
 
68
61
  return ENRMMeasureMarkdownContent<EnrichedMarkdownTextProps, EnrichedMarkdownText>(
69
62
  typedProps, getStateData().getComponentViewRef(), receivedCounter, lastExactMeasurementCounter_,
70
- MarkdownFlavor::CommonMark, layoutConstraints,
71
- ^(CGFloat width) { return (EnrichedMarkdownText *)setupMockEnrichedMarkdownText_(width); });
63
+ lastExactMeasurementSize_, MarkdownFlavor::CommonMark, layoutContext, layoutConstraints,
64
+ ^(EnrichedMarkdownText *view, CGFloat maxWidth, CGFloat fontScale) {
65
+ return ENRMMeasureMarkdownViewFree(*props, maxWidth, fontScale, pointScaleFactor, resolvedLayoutDirection);
66
+ });
72
67
  }
73
68
 
74
69
  } // namespace facebook::react
@@ -40,19 +40,24 @@ struct MeasurementCacheKey {
40
40
  bool md4cFlagsSubscript;
41
41
  bool md4cFlagsHighlight;
42
42
  bool md4cFlagsLatexMath;
43
+ bool md4cFlagsHardSoftBreaks;
43
44
  size_t styleFingerprint;
44
45
  CGFloat fontScale;
45
46
  MarkdownFlavor flavor;
47
+ std::string lineBreakStrategyIOS;
48
+ std::string writingDirection;
46
49
 
47
50
  bool operator==(const MeasurementCacheKey &other) const
48
51
  {
49
52
  return std::tie(markdown, maxWidth, allowTrailingMargin, allowFontScaling, maxFontSizeMultiplier,
50
53
  md4cFlagsUnderline, md4cFlagsSuperscript, md4cFlagsSubscript, md4cFlagsHighlight,
51
- md4cFlagsLatexMath, styleFingerprint, fontScale, flavor) ==
54
+ md4cFlagsLatexMath, md4cFlagsHardSoftBreaks, styleFingerprint, fontScale, flavor,
55
+ lineBreakStrategyIOS, writingDirection) ==
52
56
  std::tie(other.markdown, other.maxWidth, other.allowTrailingMargin, other.allowFontScaling,
53
57
  other.maxFontSizeMultiplier, other.md4cFlagsUnderline, other.md4cFlagsSuperscript,
54
58
  other.md4cFlagsSubscript, other.md4cFlagsHighlight, other.md4cFlagsLatexMath,
55
- other.styleFingerprint, other.fontScale, other.flavor);
59
+ other.md4cFlagsHardSoftBreaks, other.styleFingerprint, other.fontScale, other.flavor,
60
+ other.lineBreakStrategyIOS, other.writingDirection);
56
61
  }
57
62
  };
58
63
 
@@ -70,9 +75,12 @@ struct MeasurementCacheKeyHash {
70
75
  HashUtils::hash_one(h, key.md4cFlagsSubscript);
71
76
  HashUtils::hash_one(h, key.md4cFlagsHighlight);
72
77
  HashUtils::hash_one(h, key.md4cFlagsLatexMath);
78
+ HashUtils::hash_one(h, key.md4cFlagsHardSoftBreaks);
73
79
  HashUtils::hash_one(h, key.styleFingerprint);
74
80
  HashUtils::hash_one(h, key.fontScale);
75
81
  HashUtils::hash_one(h, static_cast<uint8_t>(key.flavor));
82
+ HashUtils::hash_one(h, key.lineBreakStrategyIOS);
83
+ HashUtils::hash_one(h, key.writingDirection);
76
84
  return h;
77
85
  }
78
86
  };
@@ -108,10 +116,11 @@ template <typename StyleStruct> inline size_t computeStyleFingerprint(const Styl
108
116
  hashFields(s.h6.textAlign);
109
117
 
110
118
  hashTextLayout(s.blockquote);
111
- hashFields(s.blockquote.borderWidth, s.blockquote.gapWidth);
119
+ hashFields(s.blockquote.borderWidth, s.blockquote.gapWidth, s.blockquote.padding, s.blockquote.borderRadius);
112
120
 
113
121
  hashTextLayout(s.list);
114
- hashFields(s.list.bulletSize, s.list.markerMinWidth, s.list.markerFontWeight, s.list.gapWidth, s.list.marginLeft);
122
+ hashFields(s.list.bulletSize, s.list.markerMinWidth, s.list.markerFontWeight, s.list.gapWidth, s.list.marginLeft,
123
+ s.list.itemSpacing);
115
124
 
116
125
  // Code & Inlines
117
126
  hashFields(s.codeBlock.fontFamily, s.codeBlock.fontSize, s.codeBlock.fontWeight, s.codeBlock.marginTop,
@@ -122,14 +131,14 @@ template <typename StyleStruct> inline size_t computeStyleFingerprint(const Styl
122
131
  hashFields(s.highlight.backgroundColor, s.highlight.color);
123
132
 
124
133
  // Visual/Spacing Elements
125
- hashFields(s.image.height, s.image.marginTop, s.image.marginBottom);
134
+ hashFields(s.image.height, s.image.maxHeight, s.image.aspectRatio, s.image.marginTop, s.image.marginBottom);
126
135
  hashFields(s.inlineImage.size);
127
136
  hashFields(s.thematicBreak.height, s.thematicBreak.marginTop, s.thematicBreak.marginBottom);
128
137
 
129
138
  // Complex Components
130
139
  hashTextLayout(s.table);
131
140
  hashFields(s.table.headerFontFamily, s.table.cellPaddingHorizontal, s.table.cellPaddingVertical, s.table.borderWidth,
132
- s.table.borderRadius);
141
+ s.table.borderRadius, s.table.horizontalOverflow);
133
142
  hashFields(s.math.fontSize, s.math.padding, s.math.marginTop, s.math.marginBottom, s.math.textAlign);
134
143
  hashFields(s.inlineMath.paddingVertical);
135
144
  hashFields(s.taskList.checkboxSize, s.taskList.checkboxBorderRadius);
@@ -152,9 +161,12 @@ inline MeasurementCacheKey buildMeasurementCacheKey(const PropsType &props, CGFl
152
161
  .md4cFlagsSubscript = props.md4cFlags.subscript,
153
162
  .md4cFlagsHighlight = props.md4cFlags.highlight,
154
163
  .md4cFlagsLatexMath = props.md4cFlags.latexMath,
164
+ .md4cFlagsHardSoftBreaks = props.md4cFlags.hardSoftBreaks,
155
165
  .styleFingerprint = computeStyleFingerprint(props.markdownStyle),
156
166
  .fontScale = fontScale,
157
167
  .flavor = flavor,
168
+ .lineBreakStrategyIOS = props.lineBreakStrategyIOS,
169
+ .writingDirection = props.writingDirection,
158
170
  };
159
171
  }
160
172
 
@@ -211,6 +223,20 @@ public:
211
223
  }
212
224
  }
213
225
 
226
+ void removeMatchingMarkdown(const std::string &markdown)
227
+ {
228
+ std::lock_guard<std::mutex> lock(mutex_);
229
+
230
+ for (auto it = list_.begin(); it != list_.end();) {
231
+ if (it->key.markdown == markdown) {
232
+ map_.erase(it->key);
233
+ it = list_.erase(it);
234
+ } else {
235
+ ++it;
236
+ }
237
+ }
238
+ }
239
+
214
240
  private:
215
241
  MeasurementCache() = default;
216
242
 
@@ -221,4 +247,4 @@ private:
221
247
  std::unordered_map<MeasurementCacheKey, std::list<CacheEntry>::iterator, MeasurementCacheKeyHash> map_;
222
248
  };
223
249
 
224
- } // namespace facebook::react
250
+ } // namespace facebook::react