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

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 (505) hide show
  1. package/README.md +54 -8
  2. package/ReactNativeEnrichedMarkdown.podspec +82 -73
  3. package/android/build.gradle +188 -1
  4. package/android/consumer-rules.pro +1 -1
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +27 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +7 -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 +27 -0
  10. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +7 -0
  11. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +223 -0
  12. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +183 -0
  13. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +65 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +1086 -61
  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 +351 -13
  18. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +62 -0
  19. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +85 -0
  20. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +160 -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 +76 -0
  23. package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +126 -10
  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/events/CopyRequestEvent.kt +28 -0
  26. package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkLayoutEvent.kt +36 -0
  27. package/android/src/main/java/com/swmansion/enriched/markdown/events/SelectionChangeEvent.kt +43 -0
  28. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +54 -4
  29. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +923 -462
  30. package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
  31. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
  32. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
  33. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
  34. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
  35. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
  36. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +108 -7
  37. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
  38. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
  39. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
  40. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
  41. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
  42. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
  43. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
  44. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
  45. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
  46. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
  47. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +116 -22
  48. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
  49. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
  50. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
  51. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +4 -2
  52. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
  53. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
  54. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
  55. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
  56. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
  58. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
  65. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
  66. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
  68. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
  69. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
  70. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
  71. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
  72. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
  73. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
  74. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt +37 -7
  75. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
  76. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
  77. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
  78. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
  79. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
  80. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +35 -28
  81. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
  82. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
  83. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +20 -82
  84. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
  85. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
  86. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
  87. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
  88. package/android/src/main/java/com/swmansion/enriched/markdown/spans/InlineChipPainter.kt +140 -0
  89. package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkChipSpans.kt +177 -0
  90. package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +1 -6
  91. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
  93. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
  94. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
  95. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
  96. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
  97. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
  98. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
  99. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
  100. package/android/src/main/java/com/swmansion/enriched/markdown/styles/InlineMathStyle.kt +16 -1
  101. package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkStyle.kt +36 -1
  102. package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt +7 -3
  103. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
  104. package/android/src/main/java/com/swmansion/enriched/markdown/styles/MathStyle.kt +3 -0
  105. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
  106. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
  107. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
  108. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
  109. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
  110. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
  111. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +84 -7
  112. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
  113. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
  114. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
  115. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
  116. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
  117. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
  118. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +52 -0
  119. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
  120. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
  121. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
  122. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/HTMLGenerator.kt +2 -1
  123. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt +6 -0
  124. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
  125. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
  126. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
  127. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
  128. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/HeadlessActionMode.kt +88 -0
  129. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLayoutCollector.kt +100 -0
  130. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
  131. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +72 -16
  132. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionChangeReporter.kt +232 -0
  133. package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +64 -0
  134. package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +414 -0
  135. package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
  136. package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
  137. package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +61 -11
  138. package/android/src/main/jni/CMakeLists.txt +53 -0
  139. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
  140. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
  141. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
  142. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
  143. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
  144. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
  145. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
  146. package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
  147. package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +8 -2
  148. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
  149. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathInlineSpan.kt +13 -6
  150. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathMeasureHelper.kt +2 -1
  151. package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +26 -8
  152. package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
  153. package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
  154. package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
  155. package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
  156. package/cpp/highlight/HighlightGrammars.hpp +28 -0
  157. package/cpp/highlight/code_highlight_podspec.rb +211 -0
  158. package/cpp/highlight/gen-registry.mjs +155 -0
  159. package/cpp/highlight/grammar-versions.json +159 -0
  160. package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
  161. package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
  162. package/cpp/parser/MD4CParser.cpp +173 -61
  163. package/cpp/parser/MD4CParser.hpp +1 -0
  164. package/cpp/parser/MarkdownASTNode.hpp +2 -1
  165. package/cpp/wasm/ASTSerializer.cpp +2 -0
  166. package/cpp/wasm/build.sh +1 -0
  167. package/cpp/wasm/md4c_wasm.cpp +3 -1
  168. package/docs/ACCESSIBILITY.md +14 -2
  169. package/docs/API_REFERENCE.md +405 -12
  170. package/docs/BREAKING_CHANGES.md +129 -0
  171. package/docs/CODE_HIGHLIGHT.md +133 -0
  172. package/docs/COPY_OPTIONS.md +61 -3
  173. package/docs/ELEMENTS_STRUCTURE.md +52 -4
  174. package/docs/IMAGE_CACHING.md +30 -0
  175. package/docs/INPUT.md +110 -11
  176. package/docs/LATEX_MATH.md +87 -45
  177. package/docs/MACOS.md +1 -1
  178. package/docs/MARKDOWN_STREAMING.md +27 -1
  179. package/docs/MENTIONS.md +8 -1
  180. package/docs/NATIVE_ASSETS.md +127 -0
  181. package/docs/RTL.md +1 -1
  182. package/docs/STYLES.md +73 -6
  183. package/docs/TESTING.md +112 -0
  184. package/docs/TEXT.md +18 -6
  185. package/docs/WEB.md +4 -1
  186. package/ios/EnrichedMarkdown.h +7 -0
  187. package/ios/EnrichedMarkdown.mm +583 -76
  188. package/ios/EnrichedMarkdownText.h +7 -0
  189. package/ios/EnrichedMarkdownText.mm +299 -73
  190. package/ios/attachments/ENRMImageAttachment.h +9 -0
  191. package/ios/attachments/ENRMImageAttachment.m +143 -40
  192. package/ios/attachments/ENRMMathInlineAttachment+macOS.m +2 -1
  193. package/ios/attachments/ENRMMathInlineAttachment.h +5 -0
  194. package/ios/attachments/ENRMMathInlineAttachment.m +50 -82
  195. package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
  196. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +223 -0
  197. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +183 -0
  198. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +65 -0
  199. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +1086 -61
  200. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +181 -2
  201. package/ios/input/ENRMAutoLinkDetector.h +2 -1
  202. package/ios/input/ENRMAutoLinkDetector.mm +79 -41
  203. package/ios/input/ENRMBlockEditCoordinator.h +71 -0
  204. package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
  205. package/ios/input/ENRMBlockRange.h +28 -0
  206. package/ios/input/ENRMBlockRange.mm +30 -0
  207. package/ios/input/ENRMBlockStore.h +56 -0
  208. package/ios/input/ENRMBlockStore.mm +275 -0
  209. package/ios/input/ENRMClipboardCoordinator.h +45 -0
  210. package/ios/input/ENRMClipboardCoordinator.mm +120 -0
  211. package/ios/input/ENRMDetectorPipeline.h +2 -1
  212. package/ios/input/ENRMEditPipeline.h +76 -0
  213. package/ios/input/ENRMEditPipeline.mm +228 -0
  214. package/ios/input/ENRMEditSession.h +36 -0
  215. package/ios/input/ENRMEditSession.mm +63 -0
  216. package/ios/input/ENRMFormattingStore.h +17 -0
  217. package/ios/input/ENRMFormattingStore.mm +95 -105
  218. package/ios/input/ENRMInputBlockType.h +91 -0
  219. package/ios/input/ENRMInputBlockType.mm +5 -0
  220. package/ios/input/ENRMInputDecorationDrawer.h +18 -0
  221. package/ios/input/ENRMInputEventEmitter.h +56 -0
  222. package/ios/input/ENRMInputEventEmitter.mm +308 -0
  223. package/ios/input/ENRMInputFormatter.h +29 -69
  224. package/ios/input/ENRMInputFormatter.mm +216 -124
  225. package/ios/input/ENRMInputFormatterStyle.h +99 -0
  226. package/ios/input/ENRMInputFormatterStyle.mm +188 -0
  227. package/ios/input/ENRMInputLayoutManager.h +9 -0
  228. package/ios/input/ENRMInputLayoutManager.mm +30 -0
  229. package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
  230. package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
  231. package/ios/input/ENRMInputParser.h +5 -6
  232. package/ios/input/ENRMInputParser.mm +461 -178
  233. package/ios/input/ENRMInputRemend.mm +2 -2
  234. package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
  235. package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
  236. package/ios/input/ENRMInputTextView.mm +103 -8
  237. package/ios/input/ENRMInputTypingAttributesController.h +42 -0
  238. package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
  239. package/ios/input/ENRMLinkCoordinator.h +41 -0
  240. package/ios/input/ENRMLinkCoordinator.mm +89 -0
  241. package/ios/input/ENRMMarkdownSerializer.h +29 -5
  242. package/ios/input/ENRMMarkdownSerializer.mm +170 -48
  243. package/ios/input/ENRMMathAtom.h +26 -0
  244. package/ios/input/ENRMMathAtom.mm +12 -0
  245. package/ios/input/ENRMMentionCoordinator.h +45 -0
  246. package/ios/input/ENRMMentionCoordinator.mm +167 -0
  247. package/ios/input/ENRMRangeEditAdjustment.h +38 -0
  248. package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
  249. package/ios/input/ENRMRangeStoreUtils.h +39 -0
  250. package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
  251. package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
  252. package/ios/input/EnrichedMarkdownTextInput.h +7 -1
  253. package/ios/input/EnrichedMarkdownTextInput.mm +1089 -1023
  254. package/ios/input/InputStylePropsUtils.h +109 -68
  255. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
  256. package/ios/input/styles/ENRMBlockHandler.h +46 -0
  257. package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
  258. package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
  259. package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
  260. package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
  261. package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
  262. package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
  263. package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
  264. package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
  265. package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
  266. package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
  267. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
  268. package/ios/internals/MeasurementCache.h +41 -9
  269. package/ios/internals/ShadowMeasurementUtils.h +63 -58
  270. package/ios/math/ENRMMathChipController.h +74 -0
  271. package/ios/math/ENRMMathChipController.mm +476 -0
  272. package/ios/math/ENRMRaTeXBridge.swift +27 -6
  273. package/ios/parser/ENRMMarkdownParser.h +1 -8
  274. package/ios/parser/ENRMMarkdownParser.mm +2 -11
  275. package/ios/parser/MarkdownASTNode.h +2 -1
  276. package/ios/parser/MarkdownParserBridge.mm +4 -0
  277. package/ios/renderer/AttributedRenderer.m +20 -2
  278. package/ios/renderer/BaseRenderer.h +17 -2
  279. package/ios/renderer/BaseRenderer.m +30 -0
  280. package/ios/renderer/BlockquoteRenderer.h +1 -1
  281. package/ios/renderer/BlockquoteRenderer.m +144 -35
  282. package/ios/renderer/CodeBlockRenderer.h +1 -1
  283. package/ios/renderer/CodeBlockRenderer.m +27 -23
  284. package/ios/renderer/CodeRenderer.h +1 -1
  285. package/ios/renderer/CodeRenderer.m +3 -1
  286. package/ios/renderer/ENRMImageRenderer.h +1 -1
  287. package/ios/renderer/ENRMImageRenderer.m +5 -1
  288. package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
  289. package/ios/renderer/ENRMMathInlineRenderer.m +6 -1
  290. package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
  291. package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
  292. package/ios/renderer/EmphasisRenderer.h +1 -1
  293. package/ios/renderer/EmphasisRenderer.m +3 -1
  294. package/ios/renderer/HeadingRenderer.h +1 -1
  295. package/ios/renderer/HeadingRenderer.m +13 -6
  296. package/ios/renderer/HighlightRenderer.h +1 -1
  297. package/ios/renderer/HighlightRenderer.m +3 -1
  298. package/ios/renderer/LinkRenderer.h +1 -1
  299. package/ios/renderer/LinkRenderer.m +50 -16
  300. package/ios/renderer/ListItemRenderer.h +13 -1
  301. package/ios/renderer/ListItemRenderer.m +102 -44
  302. package/ios/renderer/ListRenderer.h +2 -2
  303. package/ios/renderer/ListRenderer.m +63 -25
  304. package/ios/renderer/ParagraphRenderer.h +1 -1
  305. package/ios/renderer/ParagraphRenderer.m +16 -8
  306. package/ios/renderer/RenderContext.h +10 -0
  307. package/ios/renderer/RenderContext.m +44 -0
  308. package/ios/renderer/RendererFactory.m +14 -0
  309. package/ios/renderer/StrikethroughRenderer.h +1 -1
  310. package/ios/renderer/StrikethroughRenderer.m +3 -1
  311. package/ios/renderer/StrongRenderer.h +1 -1
  312. package/ios/renderer/StrongRenderer.m +3 -1
  313. package/ios/renderer/SubscriptRenderer.h +1 -1
  314. package/ios/renderer/SubscriptRenderer.m +3 -1
  315. package/ios/renderer/SuperscriptRenderer.h +1 -1
  316. package/ios/renderer/SuperscriptRenderer.m +3 -1
  317. package/ios/renderer/TextRenderer.h +2 -2
  318. package/ios/renderer/TextRenderer.m +3 -1
  319. package/ios/renderer/ThematicBreakRenderer.h +1 -1
  320. package/ios/renderer/ThematicBreakRenderer.m +3 -1
  321. package/ios/renderer/UnderlineRenderer.h +1 -1
  322. package/ios/renderer/UnderlineRenderer.m +3 -1
  323. package/ios/styles/StyleConfig.h +42 -0
  324. package/ios/styles/StyleConfig.mm +216 -0
  325. package/ios/utils/BlockquoteBorder.h +6 -0
  326. package/ios/utils/BlockquoteBorder.m +249 -52
  327. package/ios/utils/CodeBackground.m +3 -65
  328. package/ios/utils/CodeBlockBackground.m +16 -2
  329. package/ios/utils/ENRMAtomicSize.h +65 -0
  330. package/ios/utils/ENRMBlockMenu.h +66 -0
  331. package/ios/utils/ENRMChipDrawing.h +24 -0
  332. package/ios/utils/ENRMChipDrawing.m +83 -0
  333. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  334. package/ios/utils/ENRMCodeBlockContent.mm +79 -0
  335. package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
  336. package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
  337. package/ios/utils/ENRMFeatureFlags.h +7 -0
  338. package/ios/utils/ENRMImageDownloader.h +11 -1
  339. package/ios/utils/ENRMImageDownloader.m +60 -16
  340. package/ios/utils/ENRMLinkChip.h +70 -0
  341. package/ios/utils/ENRMLinkChip.m +213 -0
  342. package/ios/utils/ENRMLinkLayout.h +50 -0
  343. package/ios/utils/ENRMLinkLayout.m +45 -0
  344. package/ios/utils/ENRMLocalImageLoader.h +31 -0
  345. package/ios/utils/ENRMLocalImageLoader.m +68 -0
  346. package/ios/utils/ENRMMathFallback.h +26 -0
  347. package/ios/utils/ENRMMathFallback.m +18 -0
  348. package/ios/utils/ENRMSelectionChange.h +120 -0
  349. package/ios/utils/ENRMSelectionChange.m +282 -0
  350. package/ios/utils/ENRMTextViewSetup.h +35 -17
  351. package/ios/utils/EditMenuUtils+macOS.m +4 -1
  352. package/ios/utils/EditMenuUtils.h +35 -6
  353. package/ios/utils/EditMenuUtils.m +188 -11
  354. package/ios/utils/HTMLGenerator.m +2 -1
  355. package/ios/utils/ImageRequestHeaderUtils.h +35 -0
  356. package/ios/utils/LastElementUtils.h +1 -0
  357. package/ios/utils/ListMarkerDrawer.m +29 -42
  358. package/ios/utils/MarkdownASTSerializer.m +4 -0
  359. package/ios/utils/MarkdownAccessibilityElementBuilder.m +3 -1
  360. package/ios/utils/MarkdownExtractor.m +2 -1
  361. package/ios/utils/ParagraphStyleUtils.h +5 -0
  362. package/ios/utils/ParagraphStyleUtils.m +77 -17
  363. package/ios/utils/RTFExportUtils.m +2 -0
  364. package/ios/utils/RenderedMarkdownSegment.h +13 -1
  365. package/ios/utils/RenderedMarkdownSegment.m +20 -0
  366. package/ios/utils/SegmentRenderer.m +17 -4
  367. package/ios/utils/StreamingMarkdownFilter.h +11 -1
  368. package/ios/utils/StreamingMarkdownFilter.m +98 -2
  369. package/ios/utils/StylePropsUtils.h +110 -1
  370. package/ios/utils/TaskListTapUtils.m +24 -0
  371. package/ios/utils/TextViewLayoutManager.mm +3 -0
  372. package/ios/views/ENRMCodeBlockContainerView.h +60 -0
  373. package/ios/views/ENRMCodeBlockContainerView.m +569 -0
  374. package/ios/views/ENRMMathContainerView.h +23 -0
  375. package/ios/views/ENRMMathContainerView.m +87 -20
  376. package/ios/views/TableContainerView.h +32 -0
  377. package/ios/views/TableContainerView.m +291 -175
  378. package/jest.d.ts +1 -0
  379. package/jest.js +5 -0
  380. package/lib/module/EnrichedMarkdownNativeComponent.ts +203 -1
  381. package/lib/module/EnrichedMarkdownTextInput.js +84 -5
  382. package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
  383. package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  384. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +204 -1
  385. package/lib/module/headingDefaults.js +34 -0
  386. package/lib/module/headingDefaults.js.map +1 -0
  387. package/lib/module/index.js.map +1 -1
  388. package/lib/module/jest/index.js +205 -0
  389. package/lib/module/jest/index.js.map +1 -0
  390. package/lib/module/native/EnrichedMarkdownText.js +199 -15
  391. package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
  392. package/lib/module/normalizeMarkdownStyle.js +98 -23
  393. package/lib/module/normalizeMarkdownStyle.js.map +1 -1
  394. package/lib/module/normalizeMarkdownStyle.web.js +73 -22
  395. package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
  396. package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
  397. package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
  398. package/lib/module/normalizeMenuItem.js +1 -1
  399. package/lib/module/utils/textInputState.js +26 -0
  400. package/lib/module/utils/textInputState.js.map +1 -0
  401. package/lib/module/web/EnrichedMarkdownText.js +15 -8
  402. package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
  403. package/lib/module/web/parseMarkdown.js +4 -3
  404. package/lib/module/web/parseMarkdown.js.map +1 -1
  405. package/lib/module/web/renderers/InlineRenderers.js +102 -3
  406. package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
  407. package/lib/module/web/renderers/ListRenderers.js +7 -2
  408. package/lib/module/web/renderers/ListRenderers.js.map +1 -1
  409. package/lib/module/web/renderers/index.js +7 -4
  410. package/lib/module/web/renderers/index.js.map +1 -1
  411. package/lib/module/web/styles.js +101 -6
  412. package/lib/module/web/styles.js.map +1 -1
  413. package/lib/module/web/utils.js +14 -0
  414. package/lib/module/web/utils.js.map +1 -1
  415. package/lib/module/web/wasm/md4c.js +0 -0
  416. package/lib/module/web/wasm/md4c.js.map +1 -1
  417. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +185 -2
  418. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
  419. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +94 -9
  420. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
  421. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +69 -5
  422. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
  423. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +185 -2
  424. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
  425. package/lib/typescript/src/headingDefaults.d.ts +9 -0
  426. package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
  427. package/lib/typescript/src/index.d.ts +3 -3
  428. package/lib/typescript/src/index.d.ts.map +1 -1
  429. package/lib/typescript/src/index.web.d.ts +2 -2
  430. package/lib/typescript/src/index.web.d.ts.map +1 -1
  431. package/lib/typescript/src/jest/index.d.ts +6 -0
  432. package/lib/typescript/src/jest/index.d.ts.map +1 -0
  433. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +5 -5
  434. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
  435. package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
  436. package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
  437. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
  438. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
  439. package/lib/typescript/src/types/MarkdownStyle.d.ts +122 -5
  440. package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
  441. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +39 -0
  442. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
  443. package/lib/typescript/src/types/MarkdownTextProps.d.ts +207 -10
  444. package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
  445. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +60 -1
  446. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
  447. package/lib/typescript/src/types/events.d.ts +85 -0
  448. package/lib/typescript/src/types/events.d.ts.map +1 -1
  449. package/lib/typescript/src/utils/textInputState.d.ts +24 -0
  450. package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
  451. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
  452. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
  453. package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
  454. package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
  455. package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
  456. package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
  457. package/lib/typescript/src/web/renderers/index.d.ts +2 -1
  458. package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
  459. package/lib/typescript/src/web/styles.d.ts +2 -1
  460. package/lib/typescript/src/web/styles.d.ts.map +1 -1
  461. package/lib/typescript/src/web/types.d.ts +10 -2
  462. package/lib/typescript/src/web/types.d.ts.map +1 -1
  463. package/lib/typescript/src/web/utils.d.ts +4 -0
  464. package/lib/typescript/src/web/utils.d.ts.map +1 -1
  465. package/package.json +36 -9
  466. package/postinstall.mjs +131 -0
  467. package/ratex-version.json +21 -0
  468. package/src/EnrichedMarkdownNativeComponent.ts +203 -1
  469. package/src/EnrichedMarkdownTextInput.tsx +159 -8
  470. package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  471. package/src/EnrichedMarkdownTextNativeComponent.ts +204 -1
  472. package/src/headingDefaults.ts +21 -0
  473. package/src/index.tsx +15 -0
  474. package/src/index.web.tsx +6 -1
  475. package/src/jest/index.tsx +236 -0
  476. package/src/native/EnrichedMarkdownText.tsx +260 -11
  477. package/src/normalizeMarkdownStyle.ts +117 -16
  478. package/src/normalizeMarkdownStyle.web.ts +76 -15
  479. package/src/normalizeMarkdownTextInputStyle.ts +110 -35
  480. package/src/normalizeMenuItem.ts +1 -1
  481. package/src/types/MarkdownStyle.ts +125 -5
  482. package/src/types/MarkdownStyleInternal.ts +51 -0
  483. package/src/types/MarkdownTextProps.ts +215 -10
  484. package/src/types/MarkdownTextProps.web.ts +62 -1
  485. package/src/types/events.ts +90 -0
  486. package/src/utils/textInputState.ts +35 -0
  487. package/src/web/EnrichedMarkdownText.tsx +26 -5
  488. package/src/web/parseMarkdown.ts +6 -2
  489. package/src/web/renderers/InlineRenderers.tsx +116 -3
  490. package/src/web/renderers/ListRenderers.tsx +14 -2
  491. package/src/web/renderers/index.tsx +6 -2
  492. package/src/web/styles.ts +114 -5
  493. package/src/web/types.ts +10 -1
  494. package/src/web/utils.ts +9 -0
  495. package/src/web/wasm/md4c.js +0 -0
  496. package/vendor-grammars.mjs +511 -0
  497. package/vendor-ratex.mjs +173 -0
  498. package/app.plugin.js +0 -2
  499. package/plugin/build/withAndroidMath.js +0 -19
  500. package/plugin/build/withIosMath.js +0 -28
  501. package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
  502. package/plugin/src/withAndroidMath.ts +0 -24
  503. package/plugin/src/withIosMath.ts +0 -35
  504. package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
  505. package/plugin/tsconfig.build.json +0 -16
@@ -1,38 +1,76 @@
1
- import { useMemo, useCallback, useRef, useEffect } from 'react';
2
- import EnrichedMarkdownTextNativeComponent from '../EnrichedMarkdownTextNativeComponent';
3
- import type { MarkdownStyleInternal } from '../EnrichedMarkdownTextNativeComponent';
4
- import EnrichedMarkdownNativeComponent from '../EnrichedMarkdownNativeComponent';
1
+ import {
2
+ useMemo,
3
+ useCallback,
4
+ useRef,
5
+ useEffect,
6
+ useState,
7
+ useImperativeHandle,
8
+ } from 'react';
9
+ import EnrichedMarkdownTextNativeComponent, {
10
+ Commands as TextCommands,
11
+ } from '../EnrichedMarkdownTextNativeComponent';
12
+ import type {
13
+ LinkLayoutEvent,
14
+ MarkdownStyleInternal,
15
+ SelectionChangeEvent as NativeSelectionChangeEvent,
16
+ } from '../EnrichedMarkdownTextNativeComponent';
17
+ import EnrichedMarkdownNativeComponent, {
18
+ Commands as MarkdownCommands,
19
+ } from '../EnrichedMarkdownNativeComponent';
5
20
  import { normalizeMarkdownStyle } from '../normalizeMarkdownStyle';
6
21
  import { resolveAccessibilityLabels } from '../accessibilityLabelDefaults';
7
22
  import {
8
23
  normalizeMenuItem,
9
24
  normalizeLegacyBooleanMenuItem,
10
25
  } from '../normalizeMenuItem';
11
- import type { NativeSyntheticEvent } from 'react-native';
26
+ import { StyleSheet, View } from 'react-native';
27
+ import type {
28
+ HostInstance,
29
+ LayoutChangeEvent,
30
+ NativeSyntheticEvent,
31
+ } from 'react-native';
12
32
  import type { MarkdownStyle, Md4cFlags } from '../types/MarkdownStyle';
13
33
  import type {
14
34
  EnrichedMarkdownTextProps,
35
+ EnrichedMarkdownTextInstance,
15
36
  StreamingConfig,
16
37
  ContextMenuItem,
17
38
  SelectionMenuConfig,
18
39
  SelectionMenuPluralLabels,
40
+ LinkDecorationInfo,
41
+ LinkRect,
19
42
  } from '../types/MarkdownTextProps';
20
43
  import type {
21
44
  LinkPressEvent,
22
45
  LinkLongPressEvent,
23
46
  TaskListItemPressEvent,
47
+ CopyPressEvent,
48
+ CopyEvent,
24
49
  OnContextMenuItemPressEvent,
50
+ SelectionChangeEvent,
51
+ SelectionRect,
25
52
  } from '../types/events';
26
53
 
27
54
  export type { MarkdownStyle, Md4cFlags };
28
55
  export type {
29
56
  EnrichedMarkdownTextProps,
57
+ EnrichedMarkdownTextInstance,
30
58
  StreamingConfig,
31
59
  ContextMenuItem,
32
60
  SelectionMenuConfig,
33
61
  SelectionMenuPluralLabels,
62
+ LinkDecorationInfo,
63
+ LinkRect,
64
+ };
65
+ export type {
66
+ LinkPressEvent,
67
+ LinkLongPressEvent,
68
+ TaskListItemPressEvent,
69
+ CopyPressEvent,
70
+ CopyEvent,
71
+ SelectionChangeEvent,
72
+ SelectionRect,
34
73
  };
35
- export type { LinkPressEvent, LinkLongPressEvent, TaskListItemPressEvent };
36
74
 
37
75
  // Default English labels for the built-in selection menu actions. Defaults are
38
76
  // resolved here (JS-side) so the native code always receives a concrete string.
@@ -95,22 +133,57 @@ const buildPluralTemplates = (
95
133
  return templates;
96
134
  };
97
135
 
136
+ type LinkLayoutFragment = LinkLayoutEvent['fragments'][number];
137
+
138
+ /** Groups the flat per-line fragments native reports into one entry per link. */
139
+ const groupLinkFragments = (
140
+ fragments: ReadonlyArray<LinkLayoutFragment>
141
+ ): LinkDecorationInfo[] => {
142
+ const byIndex = new Map<number, LinkDecorationInfo>();
143
+ for (const { linkIndex, url, text, x, y, width, height } of fragments) {
144
+ const rect: LinkRect = { x, y, width, height };
145
+ const info = byIndex.get(linkIndex);
146
+ if (info) {
147
+ info.rects.push(rect);
148
+ info.rect = rect;
149
+ } else {
150
+ byIndex.set(linkIndex, {
151
+ index: linkIndex,
152
+ url,
153
+ text,
154
+ rect,
155
+ rects: [rect],
156
+ });
157
+ }
158
+ }
159
+ return [...byIndex.values()];
160
+ };
161
+
162
+ const ZERO_OFFSET = { x: 0, y: 0 };
163
+
98
164
  const defaultMd4cFlags: Md4cFlags = {
99
165
  underline: false,
100
166
  superscript: false,
101
167
  subscript: false,
102
168
  latexMath: true,
103
169
  highlight: false,
170
+ hardSoftBreaks: false,
104
171
  };
105
172
 
106
173
  export const EnrichedMarkdownText = ({
174
+ ref,
107
175
  markdown,
108
176
  markdownStyle = {},
109
177
  containerStyle,
110
178
  onLinkPress,
111
179
  onLinkLongPress,
112
180
  onTaskListItemPress,
181
+ enableTaskListItemToggle = true,
182
+ onCopyPress,
183
+ onCopy,
184
+ onSelectionChange,
113
185
  enableLinkPreview,
186
+ linkLongPressSelects = false,
114
187
  selectable = true,
115
188
  md4cFlags = defaultMd4cFlags,
116
189
  allowFontScaling = true,
@@ -121,6 +194,8 @@ export const EnrichedMarkdownText = ({
121
194
  streamingConfig,
122
195
  spoilerOverlay = 'particles',
123
196
  contextMenuItems,
197
+ imageRequestHeaders,
198
+ contextMenuHidden = false,
124
199
  selectionMenuConfig,
125
200
  accessibilityLabels,
126
201
  selectionColor,
@@ -128,6 +203,8 @@ export const EnrichedMarkdownText = ({
128
203
  textBreakStrategy,
129
204
  lineBreakStrategyIOS,
130
205
  writingDirection = 'first-strong',
206
+ renderLinkDecoration,
207
+ onLayout,
131
208
  ...rest
132
209
  }: EnrichedMarkdownTextProps) => {
133
210
  const normalizedStyleRef = useRef<MarkdownStyleInternal | null>(null);
@@ -146,6 +223,7 @@ export const EnrichedMarkdownText = ({
146
223
  subscript: md4cFlags.subscript ?? false,
147
224
  latexMath: md4cFlags.latexMath ?? true,
148
225
  highlight: md4cFlags.highlight ?? false,
226
+ hardSoftBreaks: md4cFlags.hardSoftBreaks ?? false,
149
227
  }),
150
228
  [md4cFlags]
151
229
  );
@@ -172,6 +250,16 @@ export const EnrichedMarkdownText = ({
172
250
  [contextMenuItems]
173
251
  );
174
252
 
253
+ const nativeImageRequestHeaders = useMemo(
254
+ () =>
255
+ imageRequestHeaders
256
+ ? Object.entries(imageRequestHeaders)
257
+ .map(([name, value]) => ({ name, value }))
258
+ .sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))
259
+ : undefined,
260
+ [imageRequestHeaders]
261
+ );
262
+
175
263
  const handleContextMenuItemPress = useCallback(
176
264
  (e: NativeSyntheticEvent<OnContextMenuItemPressEvent>) => {
177
265
  const { itemText, selectedText, selectionStart, selectionEnd } =
@@ -209,8 +297,103 @@ export const EnrichedMarkdownText = ({
209
297
  [onTaskListItemPress]
210
298
  );
211
299
 
300
+ const handleCopyPress = useCallback(
301
+ (e: NativeSyntheticEvent<CopyPressEvent>) => {
302
+ const { code, language } = e.nativeEvent;
303
+ onCopyPress?.({ code, language });
304
+ },
305
+ [onCopyPress]
306
+ );
307
+
308
+ const handleCopyRequest = useCallback(
309
+ // Codegen types `source` as a plain string; native only sends the four
310
+ // values of CopyEvent['source'].
311
+ (
312
+ e: NativeSyntheticEvent<Omit<CopyEvent, 'source'> & { source: string }>
313
+ ) => {
314
+ const { source, markdown: copied, text, whole } = e.nativeEvent;
315
+ onCopy?.({
316
+ source: source as CopyEvent['source'],
317
+ markdown: copied,
318
+ text,
319
+ whole,
320
+ });
321
+ },
322
+ [onCopy]
323
+ );
324
+ const interceptCopy = onCopy != null;
325
+
326
+ const decorated = renderLinkDecoration != null;
327
+ const [linkLayout, setLinkLayout] = useState<LinkDecorationInfo[]>([]);
328
+ // Where the native view sits inside the wrapper (the wrapper's padding).
329
+ const [nativeOffset, setNativeOffset] = useState(ZERO_OFFSET);
330
+
331
+ const handleLinkLayout = useCallback(
332
+ (e: NativeSyntheticEvent<LinkLayoutEvent>) => {
333
+ setLinkLayout(groupLinkFragments(e.nativeEvent.fragments));
334
+ },
335
+ []
336
+ );
337
+
338
+ const handleNativeLayout = useCallback((e: LayoutChangeEvent) => {
339
+ const { x, y } = e.nativeEvent.layout;
340
+ setNativeOffset((prev) => (prev.x === x && prev.y === y ? prev : { x, y }));
341
+ }, []);
342
+
343
+ // Rects stay relative to the native view — the view the ref's
344
+ // `measureInWindow` measures — even when decorations wrap it.
345
+ const handleSelectionChange = useCallback(
346
+ // Codegen types `source` as a plain string; native only sends the four
347
+ // values of SelectionChangeEvent['source'].
348
+ (e: NativeSyntheticEvent<NativeSelectionChangeEvent>) => {
349
+ const { source, ...payload } = e.nativeEvent;
350
+ onSelectionChange?.({
351
+ ...payload,
352
+ source: source as SelectionChangeEvent['source'],
353
+ });
354
+ },
355
+ [onSelectionChange]
356
+ );
357
+
358
+ const nativeRef = useRef<HostInstance | null>(null);
359
+ const isGithubFlavor = flavor === 'github';
360
+ useImperativeHandle(
361
+ ref,
362
+ () => ({
363
+ clearSelection: () => {
364
+ const node = nativeRef.current;
365
+ if (node == null) return;
366
+ // Codegen's ViewRef resolves to `never` with RN 0.84's function-based
367
+ // HostComponent type — the cast is safe at runtime.
368
+ if (isGithubFlavor) {
369
+ MarkdownCommands.clearSelection(
370
+ node as Parameters<(typeof MarkdownCommands)['clearSelection']>[0]
371
+ );
372
+ } else {
373
+ TextCommands.clearSelection(
374
+ node as Parameters<(typeof TextCommands)['clearSelection']>[0]
375
+ );
376
+ }
377
+ },
378
+ measure: (callback) => nativeRef.current?.measure(callback),
379
+ measureInWindow: (callback) =>
380
+ nativeRef.current?.measureInWindow(callback),
381
+ measureLayout: (relativeToNativeNode, onSuccess, onFail) =>
382
+ nativeRef.current?.measureLayout(
383
+ relativeToNativeNode,
384
+ onSuccess,
385
+ onFail
386
+ ),
387
+ }),
388
+ [isGithubFlavor]
389
+ );
390
+
212
391
  const tableMode = streamingConfig?.tableMode ?? 'progressive';
213
- const normalizedStreamingConfig = useMemo(() => ({ tableMode }), [tableMode]);
392
+ const codeBlockMode = streamingConfig?.codeBlockMode ?? 'progressive';
393
+ const normalizedStreamingConfig = useMemo(
394
+ () => ({ tableMode, codeBlockMode }),
395
+ [tableMode, codeBlockMode]
396
+ );
214
397
  const normalizedSelectionMenuConfig = useMemo(() => {
215
398
  // The boolean acceptance is confined to this wrapper boundary via a single
216
399
  // `as unknown` cast; the public type only exposes the object shape.
@@ -219,10 +402,19 @@ export const EnrichedMarkdownText = ({
219
402
  copy?: unknown;
220
403
  copyAsMarkdown?: unknown;
221
404
  copyImageUrl?: unknown;
405
+ systemItems?: unknown;
406
+ codeBlockCopyButton?: unknown;
222
407
  }
223
408
  | undefined;
224
409
 
225
410
  const copy = normalizeMenuItem(config?.copy, true, DEFAULT_COPY_LABEL);
411
+ const copyFormat = (config?.copy as { format?: unknown } | undefined)
412
+ ?.format;
413
+ const codeBlockCopyButton = normalizeMenuItem(
414
+ config?.codeBlockCopyButton,
415
+ true,
416
+ ''
417
+ );
226
418
  const copyAsMarkdown = normalizeLegacyBooleanMenuItem(
227
419
  config?.copyAsMarkdown,
228
420
  'selectionMenuConfig',
@@ -255,8 +447,13 @@ export const EnrichedMarkdownText = ({
255
447
  pluralLabels,
256
448
  copyImageUrl.label
257
449
  ),
450
+ copyEnabled: copy.enabled,
451
+ copyFormatMarkdown: copyFormat === 'markdown',
452
+ systemItemsNone: config?.systemItems === 'none',
453
+ codeBlockCopyButton: codeBlockCopyButton.enabled,
454
+ interceptCopy,
258
455
  };
259
- }, [selectionMenuConfig]);
456
+ }, [selectionMenuConfig, interceptCopy]);
260
457
 
261
458
  const resolvedAccessibilityLabels = useMemo(
262
459
  () => resolveAccessibilityLabels(accessibilityLabels),
@@ -269,7 +466,13 @@ export const EnrichedMarkdownText = ({
269
466
  onLinkPress: handleLinkPress,
270
467
  onLinkLongPress: handleLinkLongPress,
271
468
  onTaskListItemPress: handleTaskListItemPress,
469
+ enableTaskListItemToggle,
470
+ onCopyPress: handleCopyPress,
471
+ onCopyRequest: handleCopyRequest,
472
+ emitSelectionChange: onSelectionChange != null,
473
+ onSelectionChange: handleSelectionChange,
272
474
  enableLinkPreview: onLinkLongPress == null && (enableLinkPreview ?? true),
475
+ linkLongPressSelects,
273
476
  selectable,
274
477
  md4cFlags: normalizedMd4cFlags,
275
478
  allowFontScaling,
@@ -280,6 +483,8 @@ export const EnrichedMarkdownText = ({
280
483
  spoilerOverlay,
281
484
  style: containerStyle,
282
485
  contextMenuItems: nativeContextMenuItems,
486
+ imageRequestHeaders: nativeImageRequestHeaders,
487
+ contextMenuHidden,
283
488
  selectionMenuConfig: normalizedSelectionMenuConfig,
284
489
  accessibilityLabels: resolvedAccessibilityLabels,
285
490
  onContextMenuItemPress: handleContextMenuItemPress,
@@ -291,11 +496,55 @@ export const EnrichedMarkdownText = ({
291
496
  ...rest,
292
497
  };
293
498
 
294
- if (flavor === 'github') {
295
- return <EnrichedMarkdownNativeComponent {...sharedProps} />;
499
+ const NativeComponent = isGithubFlavor
500
+ ? EnrichedMarkdownNativeComponent
501
+ : EnrichedMarkdownTextNativeComponent;
502
+
503
+ // Without decorations the native view is returned as-is (no wrapper, no
504
+ // layout events) so existing layouts are untouched.
505
+ if (!decorated) {
506
+ return (
507
+ <NativeComponent {...sharedProps} ref={nativeRef} onLayout={onLayout} />
508
+ );
296
509
  }
297
510
 
298
- return <EnrichedMarkdownTextNativeComponent {...sharedProps} />;
511
+ return (
512
+ <View style={containerStyle} onLayout={onLayout}>
513
+ <NativeComponent
514
+ {...sharedProps}
515
+ ref={nativeRef}
516
+ style={undefined}
517
+ emitLinkLayout
518
+ onLinkLayout={handleLinkLayout}
519
+ onLayout={handleNativeLayout}
520
+ />
521
+ {linkLayout.map((info) => {
522
+ const decoration = renderLinkDecoration(info);
523
+ if (decoration == null) return null;
524
+ return (
525
+ <View
526
+ key={info.index}
527
+ pointerEvents="box-none"
528
+ style={[
529
+ styles.decoration,
530
+ {
531
+ left: nativeOffset.x + info.rect.x,
532
+ top: nativeOffset.y + info.rect.y,
533
+ width: info.rect.width,
534
+ height: info.rect.height,
535
+ },
536
+ ]}
537
+ >
538
+ {decoration}
539
+ </View>
540
+ );
541
+ })}
542
+ </View>
543
+ );
299
544
  };
300
545
 
546
+ const styles = StyleSheet.create({
547
+ decoration: { position: 'absolute' },
548
+ });
549
+
301
550
  export default EnrichedMarkdownText;
@@ -8,6 +8,10 @@ import type {
8
8
  } from './types/MarkdownStyleInternal';
9
9
  import { isStyleEqual, normalizeColor, mergeSubStyle } from './styleUtils';
10
10
  import { normalizeLinkVariantEntries } from './linkVariantUtils';
11
+ import {
12
+ DEFAULT_HEADING_FONT_WEIGHT,
13
+ HEADING_DEFAULTS,
14
+ } from './headingDefaults';
11
15
 
12
16
  const getSystemFont = (): string =>
13
17
  Platform.select({
@@ -26,7 +30,43 @@ const getMonospaceFont = (): string =>
26
30
  })!;
27
31
 
28
32
  const defaultTextColor = normalizeColor('#1F2937')!;
29
- const defaultHeadingColor = normalizeColor('#111827')!;
33
+
34
+ const codeBlockTextColor = normalizeColor('#F3F4F6')!;
35
+
36
+ // GitHub-dark syntax palette (Primer prettylights), tuned for the dark code
37
+ // block background (#1F2937). It is the single source of truth for per-token
38
+ // code colors: native reads these resolved values and holds no default of its
39
+ // own. The four inheriting tokens resolve to the code block base color.
40
+ const DEFAULT_CODE_BLOCK_SYNTAX_COLORS = {
41
+ keyword: normalizeColor('#FF7B72')!,
42
+ operatorColor: codeBlockTextColor,
43
+ punctuation: codeBlockTextColor,
44
+ string: normalizeColor('#A5D6FF')!,
45
+ number: normalizeColor('#79C0FF')!,
46
+ constant: normalizeColor('#79C0FF')!,
47
+ comment: normalizeColor('#8B949E')!,
48
+ function: normalizeColor('#D2A8FF')!,
49
+ type: normalizeColor('#FFA657')!,
50
+ variable: codeBlockTextColor,
51
+ property: normalizeColor('#79C0FF')!,
52
+ tag: normalizeColor('#7EE787')!,
53
+ attribute: normalizeColor('#79C0FF')!,
54
+ embedded: codeBlockTextColor,
55
+ };
56
+
57
+ const INHERIT_SYNTAX_TOKENS = new Set([
58
+ 'operatorColor',
59
+ 'punctuation',
60
+ 'variable',
61
+ 'embedded',
62
+ ]);
63
+
64
+ // The public API exposes `operator`, but the internal/native token is named
65
+ // `operatorColor` because `operator` is a reserved word in the generated C++
66
+ // struct. Map the public key onto the internal token when reading user input.
67
+ const PUBLIC_SYNTAX_TOKEN_KEYS: Record<string, string> = {
68
+ operatorColor: 'operator',
69
+ };
30
70
 
31
71
  // Explicit type annotation needed: Object.freeze breaks contextual typing, so
32
72
  // TypeScript widens literal 'auto' to `string` instead of `BlockTextAlign`.
@@ -38,7 +78,7 @@ const baseHeader: {
38
78
  textAlign: BlockTextAlign;
39
79
  } = {
40
80
  fontFamily: getSystemFont(),
41
- fontWeight: '',
81
+ fontWeight: DEFAULT_HEADING_FONT_WEIGHT,
42
82
  marginTop: 0,
43
83
  marginBottom: 8,
44
84
  textAlign: 'auto',
@@ -57,38 +97,38 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
57
97
  },
58
98
  h1: {
59
99
  ...baseHeader,
60
- fontSize: 30,
61
- color: defaultHeadingColor,
100
+ fontSize: HEADING_DEFAULTS.h1.fontSize,
101
+ color: normalizeColor(HEADING_DEFAULTS.h1.color)!,
62
102
  lineHeight: Platform.select({ ios: 36, android: 38, default: 38 })!,
63
103
  },
64
104
  h2: {
65
105
  ...baseHeader,
66
- fontSize: 24,
67
- color: defaultHeadingColor,
106
+ fontSize: HEADING_DEFAULTS.h2.fontSize,
107
+ color: normalizeColor(HEADING_DEFAULTS.h2.color)!,
68
108
  lineHeight: Platform.select({ ios: 30, android: 32, default: 32 })!,
69
109
  },
70
110
  h3: {
71
111
  ...baseHeader,
72
- fontSize: 20,
73
- color: defaultHeadingColor,
112
+ fontSize: HEADING_DEFAULTS.h3.fontSize,
113
+ color: normalizeColor(HEADING_DEFAULTS.h3.color)!,
74
114
  lineHeight: Platform.select({ ios: 26, android: 28, default: 28 })!,
75
115
  },
76
116
  h4: {
77
117
  ...baseHeader,
78
- fontSize: 18,
79
- color: defaultHeadingColor,
118
+ fontSize: HEADING_DEFAULTS.h4.fontSize,
119
+ color: normalizeColor(HEADING_DEFAULTS.h4.color)!,
80
120
  lineHeight: Platform.select({ ios: 24, android: 26, default: 26 })!,
81
121
  },
82
122
  h5: {
83
123
  ...baseHeader,
84
- fontSize: 16,
85
- color: normalizeColor('#374151')!,
124
+ fontSize: HEADING_DEFAULTS.h5.fontSize,
125
+ color: normalizeColor(HEADING_DEFAULTS.h5.color)!,
86
126
  lineHeight: Platform.select({ ios: 22, android: 24, default: 24 })!,
87
127
  },
88
128
  h6: {
89
129
  ...baseHeader,
90
- fontSize: 14,
91
- color: normalizeColor('#4B5563')!,
130
+ fontSize: HEADING_DEFAULTS.h6.fontSize,
131
+ color: normalizeColor(HEADING_DEFAULTS.h6.color)!,
92
132
  lineHeight: Platform.select({ ios: 20, android: 22, default: 22 })!,
93
133
  },
94
134
  blockquote: {
@@ -103,6 +143,8 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
103
143
  borderWidth: 3,
104
144
  gapWidth: 16,
105
145
  backgroundColor: normalizeColor('#F9FAFB')!,
146
+ borderRadius: 0,
147
+ padding: 0,
106
148
  },
107
149
  list: {
108
150
  fontSize: 16,
@@ -119,12 +161,13 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
119
161
  markerFontWeight: '500',
120
162
  gapWidth: 12,
121
163
  marginLeft: 24,
164
+ itemSpacing: 0,
122
165
  },
123
166
  codeBlock: {
124
167
  fontSize: 14,
125
168
  fontFamily: getMonospaceFont(),
126
169
  fontWeight: '',
127
- color: normalizeColor('#F3F4F6')!,
170
+ color: codeBlockTextColor,
128
171
  lineHeight: Platform.select({ ios: 20, android: 22, default: 22 })!,
129
172
  marginTop: 0,
130
173
  marginBottom: 16,
@@ -133,12 +176,18 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
133
176
  borderRadius: 8,
134
177
  borderWidth: 1,
135
178
  padding: 16,
179
+ syntaxColors: { ...DEFAULT_CODE_BLOCK_SYNTAX_COLORS },
136
180
  },
137
181
  link: {
138
182
  fontFamily: '',
139
183
  color: normalizeColor('#2563EB')!,
140
184
  underline: true,
141
185
  backgroundColor: normalizeColor('transparent')!,
186
+ borderRadius: 0,
187
+ paddingHorizontal: 0,
188
+ paddingVertical: 0,
189
+ borderColor: normalizeColor('transparent')!,
190
+ borderWidth: 0,
142
191
  },
143
192
  linkVariants: [],
144
193
  strong: { fontFamily: '', fontWeight: 'bold', color: undefined },
@@ -158,7 +207,15 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
158
207
  backgroundColor: normalizeColor('#FDF2F4')!,
159
208
  borderColor: normalizeColor('#F8D7DA')!,
160
209
  },
161
- image: { height: 200, borderRadius: 8, marginTop: 0, marginBottom: 16 },
210
+ image: {
211
+ height: 200,
212
+ maxHeight: 0,
213
+ aspectRatio: 0,
214
+ resizeMode: '' as const,
215
+ borderRadius: 8,
216
+ marginTop: 0,
217
+ marginBottom: 16,
218
+ },
162
219
  inlineImage: { size: 20 },
163
220
  thematicBreak: {
164
221
  color: normalizeColor('#E5E7EB')!,
@@ -184,6 +241,8 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
184
241
  borderRadius: 6,
185
242
  cellPaddingHorizontal: 12,
186
243
  cellPaddingVertical: 8,
244
+ horizontalOverflow: 0,
245
+ align: '' as const,
187
246
  },
188
247
  math: {
189
248
  fontSize: 20,
@@ -194,11 +253,13 @@ const DEFAULT_NORMALIZED_STYLE = Object.freeze({
194
253
  marginBottom: 16,
195
254
  textAlign: 'center' as BlockTextAlign,
196
255
  fontWeight: 'normal',
256
+ glyphOverflow: 0,
197
257
  },
198
258
  inlineMath: {
199
259
  color: defaultTextColor,
200
260
  paddingVertical: 4,
201
261
  fontWeight: 'normal',
262
+ glyphOverflow: 0,
202
263
  },
203
264
  taskList: {
204
265
  checkedColor: Platform.select({
@@ -284,9 +345,17 @@ export const normalizeMarkdownStyle = (
284
345
  color: ((override.color ? normalizeColor(override.color) : null) ??
285
346
  linkBase.color) as string,
286
347
  underline: override.underline ?? linkBase.underline,
348
+ // Chip ("box") properties never inherit from the base link style.
287
349
  backgroundColor: (override.backgroundColor
288
350
  ? (normalizeColor(override.backgroundColor) ?? transparent)
289
351
  : transparent) as string,
352
+ borderRadius: override.borderRadius ?? 0,
353
+ paddingHorizontal: override.paddingHorizontal ?? 0,
354
+ paddingVertical: override.paddingVertical ?? 0,
355
+ borderColor: (override.borderColor
356
+ ? (normalizeColor(override.borderColor) ?? transparent)
357
+ : transparent) as string,
358
+ borderWidth: override.borderWidth ?? 0,
290
359
  };
291
360
  }
292
361
  );
@@ -298,6 +367,12 @@ export const normalizeMarkdownStyle = (
298
367
  );
299
368
  }
300
369
 
370
+ // maxHeight/aspectRatio sizing is resize-mode driven; default to 'cover'.
371
+ const image = result.image as MarkdownStyleInternal['image'];
372
+ if (!image.resizeMode && (image.maxHeight > 0 || image.aspectRatio > 0)) {
373
+ (result.image as { resizeMode: string }).resizeMode = 'cover';
374
+ }
375
+
301
376
  if (!style.highlight?.color) {
302
377
  const paragraphColor = (
303
378
  result.paragraph as MarkdownStyleInternal['paragraph']
@@ -306,6 +381,32 @@ export const normalizeMarkdownStyle = (
306
381
  paragraphColor;
307
382
  }
308
383
 
384
+ const codeBlock = result.codeBlock as MarkdownStyleInternal['codeBlock'];
385
+ const userSyntaxColors = style.codeBlock?.syntaxColors as
386
+ | Record<string, unknown>
387
+ | undefined;
388
+ const resolvedSyntaxColors: Record<string, unknown> = {};
389
+ for (const token in DEFAULT_CODE_BLOCK_SYNTAX_COLORS) {
390
+ const publicKey = PUBLIC_SYNTAX_TOKEN_KEYS[token] ?? token;
391
+ const userValue = userSyntaxColors?.[publicKey];
392
+ if (typeof userValue === 'string') {
393
+ resolvedSyntaxColors[token] =
394
+ normalizeColor(userValue) ??
395
+ DEFAULT_CODE_BLOCK_SYNTAX_COLORS[
396
+ token as keyof typeof DEFAULT_CODE_BLOCK_SYNTAX_COLORS
397
+ ];
398
+ } else if (INHERIT_SYNTAX_TOKENS.has(token)) {
399
+ resolvedSyntaxColors[token] = codeBlock.color;
400
+ } else {
401
+ resolvedSyntaxColors[token] =
402
+ DEFAULT_CODE_BLOCK_SYNTAX_COLORS[
403
+ token as keyof typeof DEFAULT_CODE_BLOCK_SYNTAX_COLORS
404
+ ];
405
+ }
406
+ }
407
+ (codeBlock as unknown as Record<string, unknown>).syntaxColors =
408
+ resolvedSyntaxColors;
409
+
309
410
  const finalResult = Object.freeze(result) as unknown as MarkdownStyleInternal;
310
411
  refCache.set(style, finalResult);
311
412
  structuralCache.unshift({ style, result: finalResult });