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
@@ -7,6 +7,7 @@ import android.text.SpannableString
7
7
  import android.text.StaticLayout
8
8
  import android.text.TextPaint
9
9
  import android.util.Log
10
+ import androidx.emoji2.text.EmojiCompat
10
11
  import com.facebook.react.bridge.ReadableMap
11
12
  import com.facebook.react.uimanager.PixelUtil
12
13
  import com.facebook.yoga.YogaMeasureMode
@@ -19,16 +20,21 @@ import com.swmansion.enriched.markdown.spans.MathMetrics
19
20
  import com.swmansion.enriched.markdown.spans.MathRenderMode
20
21
  import com.swmansion.enriched.markdown.styles.StyleConfig
21
22
  import com.swmansion.enriched.markdown.utils.common.BreakStrategyUtils
23
+ import com.swmansion.enriched.markdown.utils.common.CodeBlockStreamingMode
22
24
  import com.swmansion.enriched.markdown.utils.common.FeatureFlags
23
25
  import com.swmansion.enriched.markdown.utils.common.MarkdownSegmentRenderer
24
26
  import com.swmansion.enriched.markdown.utils.common.RenderedSegment
25
27
  import com.swmansion.enriched.markdown.utils.common.StreamingMarkdownFilter
26
28
  import com.swmansion.enriched.markdown.utils.common.TableStreamingMode
29
+ import com.swmansion.enriched.markdown.utils.common.getArrayOrNull
27
30
  import com.swmansion.enriched.markdown.utils.common.getBooleanOrDefault
31
+ import com.swmansion.enriched.markdown.utils.common.getFloatOrDefault
28
32
  import com.swmansion.enriched.markdown.utils.common.getMapOrNull
29
33
  import com.swmansion.enriched.markdown.utils.common.getStringOrDefault
34
+ import com.swmansion.enriched.markdown.utils.common.parseImageRequestHeaders
30
35
  import com.swmansion.enriched.markdown.utils.common.splitASTIntoSegments
31
36
  import com.swmansion.enriched.markdown.utils.text.extensions.replaceMathSpansWithPlaceholders
37
+ import com.swmansion.enriched.markdown.views.CodeBlockContainerView
32
38
  import com.swmansion.enriched.markdown.views.TableContainerView
33
39
  import java.util.concurrent.ConcurrentHashMap
34
40
  import kotlin.math.ceil
@@ -67,6 +73,8 @@ object MeasurementStore {
67
73
 
68
74
  private val streamingTableModes = ConcurrentHashMap<Int, TableStreamingMode>()
69
75
 
76
+ private val streamingCodeBlockModes = ConcurrentHashMap<Int, CodeBlockStreamingMode>()
77
+
70
78
  private fun resolveFontScalingSettings(
71
79
  viewId: Int?,
72
80
  props: ReadableMap?,
@@ -85,6 +93,38 @@ object MeasurementStore {
85
93
  }
86
94
 
87
95
  private val measurePaint = TextPaint()
96
+
97
+ @Volatile
98
+ private var emojiInitCallbackRegistered = false
99
+
100
+ // A view measured before EmojiCompat loaded keeps a size without its emoji glyphs.
101
+ private val emojiInitCallback =
102
+ object : EmojiCompat.InitCallback() {
103
+ override fun onInitialized() {
104
+ data.clear()
105
+ }
106
+ }
107
+
108
+ // AppCompatTextView draws emoji the system font lacks through EmojiCompat, which can be
109
+ // wider than the fallback glyph and wrap a line earlier; measure the same glyphs.
110
+ private fun withEmojiSpans(text: CharSequence): CharSequence {
111
+ if (text.isEmpty() || !EmojiCompat.isConfigured()) return text
112
+ val emojiCompat = EmojiCompat.get()
113
+ if (emojiCompat.loadState != EmojiCompat.LOAD_STATE_SUCCEEDED) {
114
+ if (!emojiInitCallbackRegistered) {
115
+ emojiInitCallbackRegistered = true
116
+ emojiCompat.registerInitCallback(emojiInitCallback)
117
+ }
118
+ return text
119
+ }
120
+ return try {
121
+ emojiCompat.process(SpannableString(text)) ?: text
122
+ } catch (e: IllegalStateException) {
123
+ Log.w(TAG, "EmojiCompat processing failed, measuring raw text", e)
124
+ text
125
+ }
126
+ }
127
+
88
128
  private val measureRenderer = Renderer()
89
129
 
90
130
  @Volatile
@@ -95,6 +135,7 @@ object MeasurementStore {
95
135
  id: Int,
96
136
  spannable: CharSequence?,
97
137
  paint: TextPaint,
138
+ trailingMarginBottomPx: Float = 0f,
98
139
  ): Boolean {
99
140
  val cached = data[id]
100
141
  val width = cached?.cachedWidth ?: 0f
@@ -102,7 +143,14 @@ object MeasurementStore {
102
143
  val existingHash = cached?.markdownHash ?: 0
103
144
  val paintParams = PaintParams(paint.typeface ?: Typeface.DEFAULT, paint.textSize)
104
145
 
105
- val newSize = measure(width, spannable, paint, id)
146
+ var newSize = measure(width, spannable, paint, id)
147
+ if (trailingMarginBottomPx > 0f) {
148
+ newSize =
149
+ YogaMeasureOutput.make(
150
+ YogaMeasureOutput.getWidth(newSize),
151
+ YogaMeasureOutput.getHeight(newSize) + PixelUtil.toDIPFromPixel(trailingMarginBottomPx),
152
+ )
153
+ }
106
154
  data[id] = MeasurementParams(width, newSize, spannable, paintParams, existingHash)
107
155
  return oldSize != newSize
108
156
  }
@@ -151,7 +199,11 @@ object MeasurementStore {
151
199
  allowFontScaling: Boolean,
152
200
  maxFontSizeMultiplier: Float,
153
201
  ) {
202
+ val previous = fontScalingSettings[viewId]
154
203
  fontScalingSettings[viewId] = FontScalingSettings(allowFontScaling, maxFontSizeMultiplier)
204
+ if (previous != null && (previous.allowFontScaling != allowFontScaling || previous.maxFontSizeMultiplier != maxFontSizeMultiplier)) {
205
+ data.remove(viewId)
206
+ }
155
207
  }
156
208
 
157
209
  fun clearFontScalingSettings(viewId: Int) {
@@ -182,6 +234,17 @@ object MeasurementStore {
182
234
  streamingTableModes.remove(viewId)
183
235
  }
184
236
 
237
+ fun updateStreamingCodeBlockMode(
238
+ viewId: Int,
239
+ mode: CodeBlockStreamingMode,
240
+ ) {
241
+ streamingCodeBlockModes[viewId] = mode
242
+ }
243
+
244
+ fun clearStreamingCodeBlockMode(viewId: Int) {
245
+ streamingCodeBlockModes.remove(viewId)
246
+ }
247
+
185
248
  private fun getMeasureByIdInternal(
186
249
  context: Context,
187
250
  id: Int?,
@@ -237,6 +300,7 @@ object MeasurementStore {
237
300
  val styleMap = props.getMapOrNull("markdownStyle")
238
301
  val md4cFlagsMap = props.getMapOrNull("md4cFlags")
239
302
  val allowTrailingMargin = props.getBooleanOrDefault("allowTrailingMargin", false)
303
+ val imageRequestHeaders = parseImageRequestHeaders(props.getArrayOrNull("imageRequestHeaders"))
240
304
  var result = markdown.hashCode()
241
305
  result = 31 * result + (styleMap?.hashCode() ?: 0)
242
306
  result = 31 * result + (md4cFlagsMap?.hashCode() ?: 0)
@@ -244,6 +308,7 @@ object MeasurementStore {
244
308
  result = 31 * result + allowFontScaling.hashCode()
245
309
  result = 31 * result + maxFontSizeMultiplier.toBits()
246
310
  result = 31 * result + allowTrailingMargin.hashCode()
311
+ result = 31 * result + imageRequestHeaders.hashCode()
247
312
  return result
248
313
  }
249
314
 
@@ -292,13 +357,26 @@ object MeasurementStore {
292
357
  superscript = props.getMapOrNull("md4cFlags").getBooleanOrDefault("superscript", false),
293
358
  subscript = props.getMapOrNull("md4cFlags").getBooleanOrDefault("subscript", false),
294
359
  highlight = props.getMapOrNull("md4cFlags").getBooleanOrDefault("highlight", false),
360
+ hardSoftBreaks = props.getMapOrNull("md4cFlags").getBooleanOrDefault("hardSoftBreaks", false),
295
361
  )
296
362
 
297
363
  val fontSize = getInitialFontSize(styleMap, context, allowFontScaling, fontScale, maxFontSizeMultiplier)
298
364
  val propsHash = computePropsHash(props, allowFontScaling, fontScale, maxFontSizeMultiplier)
299
365
 
300
366
  // 2. Render & Measure
301
- val spannable = tryRenderMarkdown(markdown, styleMap, context, md4cFlags, allowFontScaling, maxFontSizeMultiplier)
367
+ measurePaint.textSize = fontSize
368
+ val imageRequestHeaders = parseImageRequestHeaders(props.getArrayOrNull("imageRequestHeaders"))
369
+ val spannable =
370
+ tryRenderMarkdown(markdown, styleMap, context, md4cFlags, allowFontScaling, maxFontSizeMultiplier, imageRequestHeaders)
371
+ // Placeholders must be built with the same inlineMath.paddingVertical the real spans use,
372
+ // or the measured line box won't match the drawn one.
373
+ val inlineMathMap = styleMap.getMapOrNull("inlineMath")
374
+ val inlineMathOverflowDip = inlineMathMap.getFloatOrDefault("glyphOverflow", 0f)
375
+ spannable?.replaceMathSpansWithPlaceholders(
376
+ context,
377
+ PixelUtil.toPixelFromDIP(inlineMathMap.getFloatOrDefault("paddingVertical", 0f)) +
378
+ if (inlineMathOverflowDip > 0f) ceil(PixelUtil.toPixelFromDIP(inlineMathOverflowDip)) else 0f,
379
+ )
302
380
  val textToMeasure = spannable ?: markdown
303
381
  val (size, _) = measureWithLayout(width, textToMeasure, measurePaint, id)
304
382
 
@@ -343,9 +421,17 @@ object MeasurementStore {
343
421
  } else {
344
422
  TableStreamingMode.PROGRESSIVE
345
423
  }
424
+ val codeBlockMode =
425
+ if (isStreaming) {
426
+ id?.let {
427
+ streamingCodeBlockModes[it]
428
+ } ?: CodeBlockStreamingMode.PROGRESSIVE
429
+ } else {
430
+ CodeBlockStreamingMode.PROGRESSIVE
431
+ }
346
432
  val markdown =
347
433
  if (isStreaming) {
348
- StreamingMarkdownFilter.renderableMarkdownForStreaming(rawMarkdown, tableMode)
434
+ StreamingMarkdownFilter.renderableMarkdownForStreaming(rawMarkdown, tableMode, codeBlockMode).markdown
349
435
  } else {
350
436
  rawMarkdown
351
437
  }
@@ -371,6 +457,7 @@ object MeasurementStore {
371
457
  superscript = props.getMapOrNull("md4cFlags").getBooleanOrDefault("superscript", false),
372
458
  subscript = props.getMapOrNull("md4cFlags").getBooleanOrDefault("subscript", false),
373
459
  highlight = props.getMapOrNull("md4cFlags").getBooleanOrDefault("highlight", false),
460
+ hardSoftBreaks = props.getMapOrNull("md4cFlags").getBooleanOrDefault("hardSoftBreaks", false),
374
461
  )
375
462
  val allowTrailingMargin = props.getBooleanOrDefault("allowTrailingMargin", false)
376
463
  val fontSize = getInitialFontSize(styleMap, context, allowFontScaling, fontScale, maxFontSizeMultiplier)
@@ -381,6 +468,7 @@ object MeasurementStore {
381
468
  ?: return YogaMeasureOutput.make(PixelUtil.toDIPFromPixel(width), 0f)
382
469
 
383
470
  val style = StyleConfig(styleMap, context, allowFontScaling, maxFontSizeMultiplier)
471
+ style.imageRequestHeaders = parseImageRequestHeaders(props.getArrayOrNull("imageRequestHeaders"))
384
472
  val segments = splitASTIntoSegments(ast)
385
473
  val renderedSegments = MarkdownSegmentRenderer.render(segments, style, context, null, null)
386
474
 
@@ -404,7 +492,8 @@ object MeasurementStore {
404
492
  for (i in mathSegmentIndices.indices) {
405
493
  val metrics = mathResults[i]
406
494
  mathHeightByIndex[mathSegmentIndices[i]] =
407
- ceil(metrics.ascent + metrics.descent).toInt() + (style.mathStyle.padding * 2)
495
+ ceil(metrics.ascent + metrics.descent).toInt() + (style.mathStyle.padding * 2) +
496
+ (style.mathStyle.glyphOverflow * 2)
408
497
  }
409
498
  }
410
499
 
@@ -419,7 +508,7 @@ object MeasurementStore {
419
508
 
420
509
  when (segment) {
421
510
  is RenderedSegment.Text -> {
422
- segment.styledText.replaceMathSpansWithPlaceholders(context, style.inlineMathStyle.paddingVertical)
511
+ segment.styledText.replaceMathSpansWithPlaceholders(context, style.inlineMathStyle.boxPaddingVertical)
423
512
 
424
513
  val layout = createStaticLayout(segment.styledText, fontSize, widthPx, id)
425
514
  totalHeightPx += layout.height
@@ -449,6 +538,15 @@ object MeasurementStore {
449
538
  totalHeightPx += style.mathStyle.marginBottom
450
539
  }
451
540
  }
541
+
542
+ is RenderedSegment.CodeBlock -> {
543
+ totalHeightPx += style.codeBlockStyle.marginTop
544
+ totalHeightPx += CodeBlockContainerView.measureCodeBlockNodeHeight(segment.node, style, context, width)
545
+ maxContentWidthPx = width
546
+ if (includeBottomMargin) {
547
+ totalHeightPx += style.codeBlockStyle.marginBottom
548
+ }
549
+ }
452
550
  }
453
551
  }
454
552
 
@@ -466,6 +564,18 @@ object MeasurementStore {
466
564
  }
467
565
  }
468
566
 
567
+ private fun prepareImageSpansForMeasurement(
568
+ text: CharSequence?,
569
+ widthPx: Int,
570
+ ) {
571
+ // widthPx == 1 is the coerceAtLeast(1) fallback for a not-yet-measured view
572
+ if (widthPx <= 1) return
573
+ val spanned = text as? android.text.Spanned ?: return
574
+ spanned
575
+ .getSpans(0, spanned.length, com.swmansion.enriched.markdown.spans.ImageSpan::class.java)
576
+ .forEach { it.prepareForMeasurement(spanned, widthPx) }
577
+ }
578
+
469
579
  private fun createStaticLayout(
470
580
  text: CharSequence,
471
581
  fontSize: Float,
@@ -473,8 +583,10 @@ object MeasurementStore {
473
583
  viewId: Int?,
474
584
  ): StaticLayout {
475
585
  measurePaint.textSize = fontSize
586
+ val content = withEmojiSpans(text)
587
+ prepareImageSpansForMeasurement(content, widthPx)
476
588
  return StaticLayout.Builder
477
- .obtain(text, 0, text.length, measurePaint, widthPx)
589
+ .obtain(content, 0, content.length, measurePaint, widthPx)
478
590
  .setIncludePad(false)
479
591
  .setLineSpacing(0f, 1f)
480
592
  .apply {
@@ -495,15 +607,17 @@ object MeasurementStore {
495
607
  md4cFlags: Md4cFlags,
496
608
  allowFontScaling: Boolean,
497
609
  maxFontSizeMultiplier: Float,
610
+ imageRequestHeaders: Map<String, String> = emptyMap(),
498
611
  ): SpannableString? {
499
612
  if (styleMap == null) return null
500
613
 
501
614
  return try {
502
615
  val ast = Parser.shared.parseMarkdown(markdown, md4cFlags) ?: return null
503
616
  val style = StyleConfig(styleMap, context, allowFontScaling, maxFontSizeMultiplier)
617
+ style.imageRequestHeaders = imageRequestHeaders
504
618
  measureRenderer.configure(style, context)
505
619
  measureRenderer.renderDocument(ast, null).apply {
506
- replaceMathSpansWithPlaceholders(context, style.inlineMathStyle.paddingVertical)
620
+ replaceMathSpansWithPlaceholders(context, style.inlineMathStyle.boxPaddingVertical)
507
621
  }
508
622
  } catch (e: Exception) {
509
623
  Log.w(TAG, "Failed to render markdown for measurement, falling back to raw text", e)
@@ -518,7 +632,7 @@ object MeasurementStore {
518
632
  fontScale: Float,
519
633
  maxFontSizeMultiplier: Float,
520
634
  ): Float {
521
- val fontSizeSp = styleMap?.getMap("paragraph")?.getDouble("fontSize")?.toFloat() ?: 16f
635
+ val fontSizeSp = styleMap.getMapOrNull("paragraph").getFloatOrDefault("fontSize", 16f)
522
636
  val density = context.resources.displayMetrics.density
523
637
 
524
638
  if (!allowFontScaling) {
@@ -552,8 +666,9 @@ object MeasurementStore {
552
666
  paint: TextPaint,
553
667
  viewId: Int?,
554
668
  ): Long {
555
- val content = text ?: ""
669
+ val content = withEmojiSpans(text ?: "")
556
670
  val safeWidth = ceil(maxWidth).toInt().coerceAtLeast(1)
671
+ prepareImageSpansForMeasurement(content, safeWidth)
557
672
 
558
673
  val builder =
559
674
  StaticLayout.Builder
@@ -591,8 +706,9 @@ object MeasurementStore {
591
706
  paint: TextPaint,
592
707
  viewId: Int?,
593
708
  ): Pair<Long, StaticLayout> {
594
- val content = text ?: ""
709
+ val content = withEmojiSpans(text ?: "")
595
710
  val widthPx = ceil(maxWidth).toInt().coerceAtLeast(1)
711
+ prepareImageSpansForMeasurement(content, widthPx)
596
712
 
597
713
  val layout =
598
714
  StaticLayout.Builder
@@ -0,0 +1,24 @@
1
+ package com.swmansion.enriched.markdown.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+
7
+ class CopyPressEvent(
8
+ surfaceId: Int,
9
+ viewId: Int,
10
+ private val code: String,
11
+ private val language: String,
12
+ ) : Event<CopyPressEvent>(surfaceId, viewId) {
13
+ override fun getEventName(): String = EVENT_NAME
14
+
15
+ override fun getEventData(): WritableMap =
16
+ Arguments.createMap().apply {
17
+ putString("code", code)
18
+ putString("language", language)
19
+ }
20
+
21
+ companion object {
22
+ const val EVENT_NAME: String = "onCopyPress"
23
+ }
24
+ }
@@ -0,0 +1,28 @@
1
+ package com.swmansion.enriched.markdown.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+
7
+ class CopyRequestEvent(
8
+ surfaceId: Int,
9
+ viewId: Int,
10
+ private val source: String,
11
+ private val markdown: String,
12
+ private val text: String,
13
+ private val whole: Boolean,
14
+ ) : Event<CopyRequestEvent>(surfaceId, viewId) {
15
+ override fun getEventName(): String = EVENT_NAME
16
+
17
+ override fun getEventData(): WritableMap =
18
+ Arguments.createMap().apply {
19
+ putString("source", source)
20
+ putString("markdown", markdown)
21
+ putString("text", text)
22
+ putBoolean("whole", whole)
23
+ }
24
+
25
+ companion object {
26
+ const val EVENT_NAME: String = "onCopyRequest"
27
+ }
28
+ }
@@ -0,0 +1,36 @@
1
+ package com.swmansion.enriched.markdown.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+ import com.swmansion.enriched.markdown.utils.text.view.LinkLayoutFragment
7
+
8
+ class LinkLayoutEvent(
9
+ surfaceId: Int,
10
+ viewId: Int,
11
+ private val fragments: List<LinkLayoutFragment>,
12
+ ) : Event<LinkLayoutEvent>(surfaceId, viewId) {
13
+ override fun getEventName(): String = EVENT_NAME
14
+
15
+ override fun getEventData(): WritableMap {
16
+ val array = Arguments.createArray()
17
+ fragments.forEach { fragment ->
18
+ array.pushMap(
19
+ Arguments.createMap().apply {
20
+ putInt("linkIndex", fragment.linkIndex)
21
+ putString("url", fragment.url)
22
+ putString("text", fragment.text)
23
+ putDouble("x", fragment.x.toDouble())
24
+ putDouble("y", fragment.y.toDouble())
25
+ putDouble("width", fragment.width.toDouble())
26
+ putDouble("height", fragment.height.toDouble())
27
+ },
28
+ )
29
+ }
30
+ return Arguments.createMap().apply { putArray("fragments", array) }
31
+ }
32
+
33
+ companion object {
34
+ const val EVENT_NAME: String = "onLinkLayout"
35
+ }
36
+ }
@@ -0,0 +1,43 @@
1
+ package com.swmansion.enriched.markdown.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+ import com.swmansion.enriched.markdown.utils.text.view.SelectionRect
7
+ import com.swmansion.enriched.markdown.utils.text.view.SelectionSnapshot
8
+
9
+ class SelectionChangeEvent(
10
+ surfaceId: Int,
11
+ viewId: Int,
12
+ private val snapshot: SelectionSnapshot,
13
+ ) : Event<SelectionChangeEvent>(surfaceId, viewId) {
14
+ override fun getEventName(): String = EVENT_NAME
15
+
16
+ // Every state is distinct (active/inactive flips must all arrive), so never merge.
17
+ override fun canCoalesce(): Boolean = false
18
+
19
+ override fun getEventData(): WritableMap =
20
+ Arguments.createMap().apply {
21
+ putBoolean("active", snapshot.active)
22
+ putString("source", snapshot.source)
23
+ putString("text", snapshot.text)
24
+ putString("markdown", snapshot.markdown)
25
+ putBoolean("whole", snapshot.whole)
26
+ putMap("rect", snapshot.rect.toWritableMap())
27
+ putMap("startRect", snapshot.startRect.toWritableMap())
28
+ putMap("endRect", snapshot.endRect.toWritableMap())
29
+ putBoolean("adjusting", snapshot.adjusting)
30
+ }
31
+
32
+ private fun SelectionRect.toWritableMap(): WritableMap =
33
+ Arguments.createMap().apply {
34
+ putDouble("x", x.toDouble())
35
+ putDouble("y", y.toDouble())
36
+ putDouble("width", width.toDouble())
37
+ putDouble("height", height.toDouble())
38
+ }
39
+
40
+ companion object {
41
+ const val EVENT_NAME: String = "onSelectionChange"
42
+ }
43
+ }
@@ -25,8 +25,10 @@ import com.swmansion.enriched.markdown.input.events.OnContextMenuItemPressEvent
25
25
  import com.swmansion.enriched.markdown.input.events.OnEndMentionEvent
26
26
  import com.swmansion.enriched.markdown.input.events.OnInputBlurEvent
27
27
  import com.swmansion.enriched.markdown.input.events.OnInputFocusEvent
28
+ import com.swmansion.enriched.markdown.input.events.OnInputKeyPressEvent
28
29
  import com.swmansion.enriched.markdown.input.events.OnLinkDetectedEvent
29
30
  import com.swmansion.enriched.markdown.input.events.OnMathPressEvent
31
+ import com.swmansion.enriched.markdown.input.events.OnPasteEvent
30
32
  import com.swmansion.enriched.markdown.input.events.OnRequestCaretRectResultEvent
31
33
  import com.swmansion.enriched.markdown.input.events.OnRequestMarkdownResultEvent
32
34
  import com.swmansion.enriched.markdown.input.events.OnStartMentionEvent
@@ -104,6 +106,7 @@ class EnrichedMarkdownTextInputManager :
104
106
  OnChangeMarkdownEvent.EVENT_NAME,
105
107
  OnChangeSelectionEvent.EVENT_NAME,
106
108
  OnChangeStateEvent.EVENT_NAME,
109
+ OnInputKeyPressEvent.EVENT_NAME,
107
110
  OnRequestMarkdownResultEvent.EVENT_NAME,
108
111
  OnRequestCaretRectResultEvent.EVENT_NAME,
109
112
  OnCaretRectChangeEvent.EVENT_NAME,
@@ -112,6 +115,7 @@ class EnrichedMarkdownTextInputManager :
112
115
  OnContextMenuItemPressEvent.EVENT_NAME,
113
116
  OnLinkDetectedEvent.EVENT_NAME,
114
117
  OnMathPressEvent.EVENT_NAME,
118
+ OnPasteEvent.EVENT_NAME,
115
119
  OnStartMentionEvent.EVENT_NAME,
116
120
  OnChangeMentionEvent.EVENT_NAME,
117
121
  OnEndMentionEvent.EVENT_NAME,
@@ -134,7 +138,7 @@ class EnrichedMarkdownTextInputManager :
134
138
  view: EnrichedMarkdownTextInputView?,
135
139
  value: String?,
136
140
  ) {
137
- view?.hint = value
141
+ view?.setUserHint(value)
138
142
  }
139
143
 
140
144
  @ReactProp(name = "placeholderTextColor", customType = "Color")
@@ -186,6 +190,14 @@ class EnrichedMarkdownTextInputManager :
186
190
  view?.setAutoCapitalize(value)
187
191
  }
188
192
 
193
+ @ReactProp(name = "interceptPaste", defaultBoolean = false)
194
+ override fun setInterceptPaste(
195
+ view: EnrichedMarkdownTextInputView?,
196
+ value: Boolean,
197
+ ) {
198
+ view?.interceptPaste = value
199
+ }
200
+
189
201
  @ReactProp(name = "multiline", defaultBoolean = true)
190
202
  override fun setMultiline(
191
203
  view: EnrichedMarkdownTextInputView?,
@@ -220,9 +232,7 @@ class EnrichedMarkdownTextInputManager :
220
232
  if (view == null || value == null) return
221
233
 
222
234
  val style = MarkdownStyleParser.parse(value)
223
- view.setAutoLinkStyle(style)
224
- view.applyInputStyle(style)
225
- val changed = view.formatter.updateStyle(style)
235
+ val changed = view.setMarkdownStyleFromProps(style)
226
236
  if (changed) {
227
237
  view.applyFormatting()
228
238
  }
@@ -445,6 +455,29 @@ class EnrichedMarkdownTextInputManager :
445
455
  view?.toggleInlineStyle(StyleType.SPOILER)
446
456
  }
447
457
 
458
+ override fun toggleHeading(
459
+ view: EnrichedMarkdownTextInputView?,
460
+ level: Int,
461
+ ) {
462
+ view?.toggleHeading(level)
463
+ }
464
+
465
+ override fun toggleUnorderedList(view: EnrichedMarkdownTextInputView?) {
466
+ view?.toggleUnorderedList()
467
+ }
468
+
469
+ override fun toggleOrderedList(view: EnrichedMarkdownTextInputView?) {
470
+ view?.toggleOrderedList()
471
+ }
472
+
473
+ override fun indentList(view: EnrichedMarkdownTextInputView?) {
474
+ view?.indentList()
475
+ }
476
+
477
+ override fun outdentList(view: EnrichedMarkdownTextInputView?) {
478
+ view?.outdentList()
479
+ }
480
+
448
481
  override fun setLink(
449
482
  view: EnrichedMarkdownTextInputView?,
450
483
  url: String?,
@@ -464,6 +497,15 @@ class EnrichedMarkdownTextInputManager :
464
497
  }
465
498
  }
466
499
 
500
+ override fun insertText(
501
+ view: EnrichedMarkdownTextInputView?,
502
+ text: String?,
503
+ ) {
504
+ if (text != null) {
505
+ view?.insertTextAtCursor(text)
506
+ }
507
+ }
508
+
467
509
  override fun insertMention(
468
510
  view: EnrichedMarkdownTextInputView?,
469
511
  displayText: String?,
@@ -517,6 +559,14 @@ class EnrichedMarkdownTextInputManager :
517
559
  view?.copyToClipboard()
518
560
  }
519
561
 
562
+ override fun resolvePaste(
563
+ view: EnrichedMarkdownTextInputView?,
564
+ text: String?,
565
+ markdown: String?,
566
+ ) {
567
+ view?.resolvePaste(text ?: "", markdown ?: "")
568
+ }
569
+
520
570
  override fun requestMarkdown(
521
571
  view: EnrichedMarkdownTextInputView?,
522
572
  requestId: Int,