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
@@ -5,6 +5,7 @@ import android.graphics.Canvas
5
5
  import android.os.Build
6
6
  import android.text.Layout
7
7
  import android.util.AttributeSet
8
+ import android.view.ActionMode
8
9
  import android.view.MotionEvent
9
10
  import com.swmansion.enriched.markdown.accessibility.AccessibilityLabels
10
11
  import com.swmansion.enriched.markdown.accessibility.AccessibleMarkdownTextView
@@ -12,12 +13,15 @@ import com.swmansion.enriched.markdown.spoiler.SpoilerCapable
12
13
  import com.swmansion.enriched.markdown.spoiler.SpoilerOverlay
13
14
  import com.swmansion.enriched.markdown.spoiler.SpoilerOverlayDrawer
14
15
  import com.swmansion.enriched.markdown.utils.text.interaction.CheckboxTouchHelper
16
+ import com.swmansion.enriched.markdown.utils.text.view.HeadlessActionMode
15
17
  import com.swmansion.enriched.markdown.utils.text.view.LinkLongPressMovementMethod
16
18
  import com.swmansion.enriched.markdown.utils.text.view.SelectionMenuConfig
17
19
  import com.swmansion.enriched.markdown.utils.text.view.applySelectableState
18
20
  import com.swmansion.enriched.markdown.utils.text.view.cancelJSTouchForCheckboxTap
19
21
  import com.swmansion.enriched.markdown.utils.text.view.cancelJSTouchForLinkTap
22
+ import com.swmansion.enriched.markdown.utils.text.view.clearTextSelection
20
23
  import com.swmansion.enriched.markdown.utils.text.view.createSelectionActionModeCallback
24
+ import com.swmansion.enriched.markdown.utils.text.view.isRomSelectionPopupShower
21
25
  import com.swmansion.enriched.markdown.utils.text.view.reallowParentInterceptIfLinkReleased
22
26
  import com.swmansion.enriched.markdown.utils.text.view.setupAsMarkdownTextView
23
27
  import com.swmansion.enriched.markdown.views.BlockSegmentView
@@ -41,6 +45,12 @@ class EnrichedMarkdownInternalText
41
45
  checkboxTouchHelper.onCheckboxTap = value
42
46
  }
43
47
 
48
+ var enableTaskListItemToggle: Boolean
49
+ get() = checkboxTouchHelper.isEnabled
50
+ set(value) {
51
+ checkboxTouchHelper.isEnabled = value
52
+ }
53
+
44
54
  override val segmentMarginBottom: Int get() = lastElementMarginBottom.toInt()
45
55
 
46
56
  override var spoilerOverlayDrawer: SpoilerOverlayDrawer? = null
@@ -49,6 +59,19 @@ class EnrichedMarkdownInternalText
49
59
  private var contextMenuItemTexts: List<String> = emptyList()
50
60
  private var onContextMenuItemPress: ((itemText: String, selectedText: String, selectionStart: Int, selectionEnd: Int) -> Unit)? = null
51
61
  var selectionMenuConfig: SelectionMenuConfig = SelectionMenuConfig()
62
+ var onCopyRequest: ((markdown: String, text: String, fullSelection: Boolean) -> Unit)? = null
63
+
64
+ // Read from onSelectionChanged, which TextView already calls from its own
65
+ // constructor — so it must stay nullable.
66
+ var onSelectionChangedCallback: ((view: EnrichedMarkdownInternalText, hasSelection: Boolean) -> Unit)? = null
67
+ private var activeActionMode: ActionMode? = null
68
+ var contextMenuHidden: Boolean = false
69
+ set(value) {
70
+ if (field == value) return
71
+ field = value
72
+ // See EnrichedMarkdownText.setContextMenuHidden.
73
+ activeActionMode?.invalidate()
74
+ }
52
75
  var accessibilityLabels: AccessibilityLabels = AccessibilityLabels()
53
76
  set(value) {
54
77
  field = value
@@ -62,9 +85,14 @@ class EnrichedMarkdownInternalText
62
85
  this,
63
86
  getCustomItemTexts = { contextMenuItemTexts },
64
87
  getSelectionMenuConfig = { selectionMenuConfig },
88
+ isContextMenuHidden = { contextMenuHidden },
89
+ onActionModeChanged = { activeActionMode = it },
65
90
  onCustomItemPress = { itemText, selectedText, start, end ->
66
91
  onContextMenuItemPress?.invoke(itemText, selectedText, start, end)
67
92
  },
93
+ onCopyRequest = { markdown, text, fullSelection ->
94
+ onCopyRequest?.invoke(markdown, text, fullSelection)
95
+ },
68
96
  )
69
97
  }
70
98
 
@@ -94,6 +122,40 @@ class EnrichedMarkdownInternalText
94
122
  applySelectableState(selectable)
95
123
  }
96
124
 
125
+ override fun onSelectionChanged(
126
+ selStart: Int,
127
+ selEnd: Int,
128
+ ) {
129
+ super.onSelectionChanged(selStart, selEnd)
130
+ onSelectionChangedCallback?.invoke(this, selEnd > selStart)
131
+ }
132
+
133
+ // See HeadlessActionMode: with the menu hidden, no toolbar window is created.
134
+ override fun startActionMode(
135
+ callback: ActionMode.Callback?,
136
+ type: Int,
137
+ ): ActionMode? {
138
+ if (contextMenuHidden && type == ActionMode.TYPE_FLOATING && callback != null) {
139
+ return HeadlessActionMode.start(this, callback)
140
+ }
141
+ return super.startActionMode(callback, type)
142
+ }
143
+
144
+ // See isRomSelectionPopupShower: MIUI shows its own selection popup this way.
145
+ override fun postDelayed(
146
+ action: Runnable?,
147
+ delayMillis: Long,
148
+ ): Boolean {
149
+ if (contextMenuHidden && isRomSelectionPopupShower(action)) return false
150
+ return super.postDelayed(action, delayMillis)
151
+ }
152
+
153
+ /** Clears the selection and ends its ActionMode. */
154
+ fun clearSelection() {
155
+ clearTextSelection()
156
+ activeActionMode?.finish()
157
+ }
158
+
97
159
  fun setContextMenuItems(
98
160
  items: List<String>,
99
161
  onPress: (itemText: String, selectedText: String, selectionStart: Int, selectionEnd: Int) -> Unit,
@@ -4,7 +4,9 @@ import android.content.Context
4
4
  import com.facebook.react.bridge.ReadableArray
5
5
  import com.facebook.react.bridge.ReadableMap
6
6
  import com.facebook.react.module.annotations.ReactModule
7
+ import com.facebook.react.uimanager.ReactStylesDiffMap
7
8
  import com.facebook.react.uimanager.SimpleViewManager
9
+ import com.facebook.react.uimanager.StateWrapper
8
10
  import com.facebook.react.uimanager.ThemedReactContext
9
11
  import com.facebook.react.uimanager.ViewManagerDelegate
10
12
  import com.facebook.react.uimanager.annotations.ReactProp
@@ -12,14 +14,18 @@ import com.facebook.react.viewmanagers.EnrichedMarkdownManagerDelegate
12
14
  import com.facebook.react.viewmanagers.EnrichedMarkdownManagerInterface
13
15
  import com.facebook.yoga.YogaMeasureMode
14
16
  import com.swmansion.enriched.markdown.spoiler.SpoilerOverlay
17
+ import com.swmansion.enriched.markdown.utils.common.CodeBlockStreamingMode
15
18
  import com.swmansion.enriched.markdown.utils.common.TableStreamingMode
16
19
  import com.swmansion.enriched.markdown.utils.common.emitContextMenuItemPress
20
+ import com.swmansion.enriched.markdown.utils.common.emitCopyPress
21
+ import com.swmansion.enriched.markdown.utils.common.emitCopyRequest
17
22
  import com.swmansion.enriched.markdown.utils.common.emitLinkLongPress
18
23
  import com.swmansion.enriched.markdown.utils.common.emitLinkPress
19
24
  import com.swmansion.enriched.markdown.utils.common.emitTaskListItemPress
20
25
  import com.swmansion.enriched.markdown.utils.common.markdownEventTypeConstants
21
26
  import com.swmansion.enriched.markdown.utils.common.parseAccessibilityLabels
22
27
  import com.swmansion.enriched.markdown.utils.common.parseContextMenuItems
28
+ import com.swmansion.enriched.markdown.utils.common.parseImageRequestHeaders
23
29
  import com.swmansion.enriched.markdown.utils.common.parseMd4cFlags
24
30
  import com.swmansion.enriched.markdown.utils.common.parseSelectionMenuConfig
25
31
  import com.swmansion.enriched.markdown.utils.text.interaction.TaskListToggleUtils
@@ -56,6 +62,14 @@ class EnrichedMarkdownManager :
56
62
  emitTaskListItemPress(view, taskIndex, newChecked, itemText)
57
63
  }
58
64
 
65
+ view.setOnCopyPressCallback { code, language ->
66
+ emitCopyPress(view, code, language)
67
+ }
68
+
69
+ view.onCopyRequestCallback = { source, markdown, text, whole ->
70
+ emitCopyRequest(view, source, markdown, text, whole)
71
+ }
72
+
59
73
  return view
60
74
  }
61
75
 
@@ -64,12 +78,23 @@ class EnrichedMarkdownManager :
64
78
  view.commitProps()
65
79
  }
66
80
 
81
+ override fun updateState(
82
+ view: EnrichedMarkdown,
83
+ props: ReactStylesDiffMap?,
84
+ stateWrapper: StateWrapper?,
85
+ ): Any? {
86
+ view.stateWrapper = stateWrapper
87
+ return super.updateState(view, props, stateWrapper)
88
+ }
89
+
67
90
  override fun onDropViewInstance(view: EnrichedMarkdown) {
68
91
  super.onDropViewInstance(view)
69
92
  view.cleanup()
70
93
  MeasurementStore.release(view.id)
71
94
  MeasurementStore.clearStreamingTableMode(view.id)
95
+ MeasurementStore.clearStreamingCodeBlockMode(view.id)
72
96
  MeasurementStore.clearBreakStrategy(view.id)
97
+ MeasurementStore.clearFontScalingSettings(view.id)
73
98
  }
74
99
 
75
100
  override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> = markdownEventTypeConstants()
@@ -144,6 +169,36 @@ class EnrichedMarkdownManager :
144
169
  view?.setAllowTrailingMargin(allowTrailingMargin)
145
170
  }
146
171
 
172
+ @ReactProp(name = "contextMenuHidden", defaultBoolean = false)
173
+ override fun setContextMenuHidden(
174
+ view: EnrichedMarkdown?,
175
+ contextMenuHidden: Boolean,
176
+ ) {
177
+ view?.setContextMenuHidden(contextMenuHidden)
178
+ }
179
+
180
+ @ReactProp(name = "emitLinkLayout", defaultBoolean = false)
181
+ override fun setEmitLinkLayout(
182
+ view: EnrichedMarkdown?,
183
+ emitLinkLayout: Boolean,
184
+ ) {
185
+ view?.setEmitLinkLayout(emitLinkLayout)
186
+ }
187
+
188
+ @ReactProp(name = "emitSelectionChange", defaultBoolean = false)
189
+ override fun setEmitSelectionChange(
190
+ view: EnrichedMarkdown?,
191
+ emitSelectionChange: Boolean,
192
+ ) {
193
+ view?.setEmitSelectionChange(emitSelectionChange)
194
+ }
195
+
196
+ // Commands
197
+
198
+ override fun clearSelection(view: EnrichedMarkdown?) {
199
+ view?.clearSelection()
200
+ }
201
+
147
202
  @ReactProp(name = "enableLinkPreview", defaultBoolean = true)
148
203
  override fun setEnableLinkPreview(
149
204
  view: EnrichedMarkdown?,
@@ -152,6 +207,22 @@ class EnrichedMarkdownManager :
152
207
  // No-op on Android — only used on iOS
153
208
  }
154
209
 
210
+ @ReactProp(name = "linkLongPressSelects", defaultBoolean = false)
211
+ override fun setLinkLongPressSelects(
212
+ view: EnrichedMarkdown?,
213
+ linkLongPressSelects: Boolean,
214
+ ) {
215
+ // No-op on Android — only used on iOS
216
+ }
217
+
218
+ @ReactProp(name = "enableTaskListItemToggle", defaultBoolean = true)
219
+ override fun setEnableTaskListItemToggle(
220
+ view: EnrichedMarkdown?,
221
+ enableTaskListItemToggle: Boolean,
222
+ ) {
223
+ view?.enableTaskListItemToggle = enableTaskListItemToggle
224
+ }
225
+
155
226
  @ReactProp(name = "lineBreakStrategyIOS")
156
227
  override fun setLineBreakStrategyIOS(
157
228
  view: EnrichedMarkdown?,
@@ -188,6 +259,11 @@ class EnrichedMarkdownManager :
188
259
  else -> TableStreamingMode.PROGRESSIVE
189
260
  }
190
261
  view.tableStreamingMode = tableMode
262
+ view.codeBlockStreamingMode =
263
+ when (config?.getString("codeBlockMode")) {
264
+ "hidden" -> CodeBlockStreamingMode.HIDDEN
265
+ else -> CodeBlockStreamingMode.PROGRESSIVE
266
+ }
191
267
  }
192
268
 
193
269
  @ReactProp(name = "spoilerOverlay")
@@ -215,6 +291,15 @@ class EnrichedMarkdownManager :
215
291
  view.setContextMenuItems(parseContextMenuItems(value))
216
292
  }
217
293
 
294
+ @ReactProp(name = "imageRequestHeaders")
295
+ override fun setImageRequestHeaders(
296
+ view: EnrichedMarkdown?,
297
+ value: ReadableArray?,
298
+ ) {
299
+ if (view == null) return
300
+ view.setImageRequestHeaders(parseImageRequestHeaders(value))
301
+ }
302
+
218
303
  @ReactProp(name = "selectionMenuConfig")
219
304
  override fun setSelectionMenuConfig(
220
305
  view: EnrichedMarkdown?,
@@ -9,8 +9,11 @@ import android.os.Looper
9
9
  import android.text.Layout
10
10
  import android.util.AttributeSet
11
11
  import android.util.Log
12
+ import android.util.TypedValue
13
+ import android.view.ActionMode
12
14
  import android.view.MotionEvent
13
15
  import com.facebook.react.bridge.ReadableMap
16
+ import com.facebook.react.uimanager.StateWrapper
14
17
  import com.swmansion.enriched.markdown.accessibility.AccessibilityLabels
15
18
  import com.swmansion.enriched.markdown.accessibility.AccessibleMarkdownTextView
16
19
  import com.swmansion.enriched.markdown.parser.Md4cFlags
@@ -21,17 +24,27 @@ import com.swmansion.enriched.markdown.spoiler.SpoilerOverlay
21
24
  import com.swmansion.enriched.markdown.spoiler.SpoilerOverlayDrawer
22
25
  import com.swmansion.enriched.markdown.styles.StyleConfig
23
26
  import com.swmansion.enriched.markdown.utils.common.BreakStrategyUtils
27
+ import com.swmansion.enriched.markdown.utils.common.emitLinkLayout
28
+ import com.swmansion.enriched.markdown.utils.common.emitSelectionChange
24
29
  import com.swmansion.enriched.markdown.utils.text.TailFadeInAnimator
25
30
  import com.swmansion.enriched.markdown.utils.text.interaction.CheckboxTouchHelper
31
+ import com.swmansion.enriched.markdown.utils.text.view.HeadlessActionMode
32
+ import com.swmansion.enriched.markdown.utils.text.view.LinkLayoutCollector
33
+ import com.swmansion.enriched.markdown.utils.text.view.LinkLayoutFragment
26
34
  import com.swmansion.enriched.markdown.utils.text.view.LinkLongPressMovementMethod
35
+ import com.swmansion.enriched.markdown.utils.text.view.SelectionChangeReporter
27
36
  import com.swmansion.enriched.markdown.utils.text.view.SelectionMenuConfig
37
+ import com.swmansion.enriched.markdown.utils.text.view.SelectionSnapshot
28
38
  import com.swmansion.enriched.markdown.utils.text.view.applySelectableState
29
39
  import com.swmansion.enriched.markdown.utils.text.view.applySelectionColors
30
40
  import com.swmansion.enriched.markdown.utils.text.view.cancelJSTouchForCheckboxTap
31
41
  import com.swmansion.enriched.markdown.utils.text.view.cancelJSTouchForLinkTap
42
+ import com.swmansion.enriched.markdown.utils.text.view.clearTextSelection
32
43
  import com.swmansion.enriched.markdown.utils.text.view.createSelectionActionModeCallback
44
+ import com.swmansion.enriched.markdown.utils.text.view.currentTextSelection
33
45
  import com.swmansion.enriched.markdown.utils.text.view.emitLinkLongPressEvent
34
46
  import com.swmansion.enriched.markdown.utils.text.view.emitLinkPressEvent
47
+ import com.swmansion.enriched.markdown.utils.text.view.isRomSelectionPopupShower
35
48
  import com.swmansion.enriched.markdown.utils.text.view.reallowParentInterceptIfLinkReleased
36
49
  import com.swmansion.enriched.markdown.utils.text.view.setupAsMarkdownTextView
37
50
  import java.util.concurrent.Executors
@@ -60,8 +73,12 @@ class EnrichedMarkdownText
60
73
 
61
74
  val layoutManager = EnrichedMarkdownTextLayoutManager(this)
62
75
 
76
+ // used to force a Yoga re-measure when a block image resolves its box height
77
+ var stateWrapper: StateWrapper? = null
78
+
63
79
  private var contextMenuItemTexts: List<String> = emptyList()
64
80
  var onContextMenuItemPressCallback: ((itemText: String, selectedText: String, selectionStart: Int, selectionEnd: Int) -> Unit)? = null
81
+ var onCopyRequestCallback: ((markdown: String, text: String, whole: Boolean) -> Unit)? = null
65
82
 
66
83
  var markdownStyle: StyleConfig? = null
67
84
  private set
@@ -78,6 +95,7 @@ class EnrichedMarkdownText
78
95
  private var allowFontScaling: Boolean = true
79
96
  private var maxFontSizeMultiplier: Float = 0f
80
97
  private var allowTrailingMargin: Boolean = false
98
+ private var imageRequestHeaders: Map<String, String> = emptyMap()
81
99
 
82
100
  private var streamingAnimation: Boolean = false
83
101
  private var previousTextLength: Int = 0
@@ -91,20 +109,46 @@ class EnrichedMarkdownText
91
109
  private var selectionColor: Int? = null
92
110
  private var selectionHandleColor: Int? = null
93
111
  private var selectionMenuConfig = SelectionMenuConfig()
112
+ private var contextMenuHidden = false
113
+ private var activeActionMode: ActionMode? = null
114
+
115
+ private var linkLayoutEnabled = false
116
+ private var lastLinkLayout: List<LinkLayoutFragment>? = null
117
+
118
+ // Nullable and assigned in init: TextView calls onSelectionChanged from its
119
+ // own constructor, before this class's fields exist.
120
+ private var selectionReporter: SelectionChangeReporter? = null
94
121
 
95
122
  init {
96
123
  setupAsMarkdownTextView()
124
+ selectionReporter =
125
+ SelectionChangeReporter(this, ::selectionSnapshot) { snapshot -> emitSelectionChange(this, snapshot) }
97
126
  customSelectionActionModeCallback =
98
127
  createSelectionActionModeCallback(
99
128
  this,
100
129
  getCustomItemTexts = { contextMenuItemTexts },
101
130
  getSelectionMenuConfig = { selectionMenuConfig },
131
+ isContextMenuHidden = { contextMenuHidden },
132
+ onActionModeChanged = { activeActionMode = it },
102
133
  onCustomItemPress = { itemText, selectedText, start, end ->
103
134
  onContextMenuItemPressCallback?.invoke(itemText, selectedText, start, end)
104
135
  },
136
+ // A full selection already carries the original markdown.
137
+ onCopyRequest = { markdown, text, fullSelection ->
138
+ onCopyRequestCallback?.invoke(markdown, text, fullSelection && currentMarkdown.isNotEmpty())
139
+ },
105
140
  )
106
141
  }
107
142
 
143
+ fun setContextMenuHidden(hidden: Boolean) {
144
+ if (contextMenuHidden == hidden) return
145
+ contextMenuHidden = hidden
146
+ // Rebuild a toolbar that is already on screen; without this the flip
147
+ // would only take effect on the next selection, leaving a working Copy
148
+ // menu up after the app asked for it to be hidden.
149
+ activeActionMode?.invalidate()
150
+ }
151
+
108
152
  fun setMarkdownContent(markdown: String) {
109
153
  if (currentMarkdown == markdown) return
110
154
  currentMarkdown = markdown
@@ -116,12 +160,20 @@ class EnrichedMarkdownText
116
160
  // Register font scaling settings when style is set (view should have ID by now)
117
161
  updateMeasurementStoreFontScaling()
118
162
  val newStyle = style?.let { StyleConfig(it, context, allowFontScaling, maxFontSizeMultiplier) }
163
+ newStyle?.imageRequestHeaders = imageRequestHeaders
119
164
  if (markdownStyle == newStyle) return
120
165
  markdownStyle = newStyle
121
166
  updateJustificationMode(newStyle)
122
167
  scheduleRender()
123
168
  }
124
169
 
170
+ fun setImageRequestHeaders(headers: Map<String, String>) {
171
+ if (imageRequestHeaders == headers) return
172
+ imageRequestHeaders = headers
173
+ markdownStyle?.imageRequestHeaders = headers
174
+ scheduleRenderIfNeeded()
175
+ }
176
+
125
177
  override fun onConfigurationChanged(newConfig: Configuration) {
126
178
  super.onConfigurationChanged(newConfig)
127
179
 
@@ -177,6 +229,10 @@ class EnrichedMarkdownText
177
229
  }
178
230
  }
179
231
 
232
+ fun commitProps() {
233
+ updateMeasurementStoreFontScaling()
234
+ }
235
+
180
236
  private fun updateMeasurementStoreFontScaling() {
181
237
  MeasurementStore.updateFontScalingSettings(id, allowFontScaling, maxFontSizeMultiplier)
182
238
  }
@@ -189,7 +245,10 @@ class EnrichedMarkdownText
189
245
 
190
246
  private fun recreateStyleConfig() {
191
247
  markdownStyleMap?.let { styleMap ->
192
- markdownStyle = StyleConfig(styleMap, context, allowFontScaling, maxFontSizeMultiplier)
248
+ markdownStyle =
249
+ StyleConfig(styleMap, context, allowFontScaling, maxFontSizeMultiplier).also {
250
+ it.imageRequestHeaders = imageRequestHeaders
251
+ }
193
252
  updateJustificationMode(markdownStyle)
194
253
  }
195
254
  }
@@ -242,6 +301,10 @@ class EnrichedMarkdownText
242
301
  private fun applyRenderedText(styledText: CharSequence) {
243
302
  val tailStart = previousTextLength
244
303
 
304
+ markdownStyle?.paragraphStyle?.fontSize?.let {
305
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, it)
306
+ }
307
+
245
308
  text = styledText
246
309
 
247
310
  if (movementMethod !is LinkLongPressMovementMethod) {
@@ -266,8 +329,99 @@ class EnrichedMarkdownText
266
329
  }
267
330
 
268
331
  applySelectionColors(selectionColor, selectionHandleColor)
332
+ emitLinkLayoutIfNeeded()
333
+ // New text drops the selection; report it if setText didn't already.
334
+ selectionReporter?.schedule()
335
+ }
336
+
337
+ fun setEmitSelectionChange(enabled: Boolean) {
338
+ selectionReporter?.enabled = enabled
269
339
  }
270
340
 
341
+ // See HeadlessActionMode: with the menu hidden, no toolbar window is created.
342
+ override fun startActionMode(
343
+ callback: ActionMode.Callback?,
344
+ type: Int,
345
+ ): ActionMode? {
346
+ if (contextMenuHidden && type == ActionMode.TYPE_FLOATING && callback != null) {
347
+ return HeadlessActionMode.start(this, callback)
348
+ }
349
+ return super.startActionMode(callback, type)
350
+ }
351
+
352
+ // See isRomSelectionPopupShower: MIUI shows its own selection popup this way.
353
+ override fun postDelayed(
354
+ action: Runnable?,
355
+ delayMillis: Long,
356
+ ): Boolean {
357
+ if (contextMenuHidden && isRomSelectionPopupShower(action)) return false
358
+ return super.postDelayed(action, delayMillis)
359
+ }
360
+
361
+ /** Clears the selection (ending its ActionMode) and reports `active: false`. */
362
+ fun clearSelection() {
363
+ clearTextSelection()
364
+ activeActionMode?.finish()
365
+ selectionReporter?.flushNow()
366
+ }
367
+
368
+ override fun onSelectionChanged(
369
+ selStart: Int,
370
+ selEnd: Int,
371
+ ) {
372
+ super.onSelectionChanged(selStart, selEnd)
373
+ selectionReporter?.onSelectionChanged(selEnd > selStart)
374
+ }
375
+
376
+ private fun selectionSnapshot(): SelectionSnapshot {
377
+ val selection = currentTextSelection() ?: return SelectionSnapshot.INACTIVE
378
+ return SelectionSnapshot(
379
+ active = true,
380
+ source = "selection",
381
+ text = selection.text,
382
+ markdown = selection.markdown,
383
+ // Same rule as onCopyRequest: a full selection already carries the original markdown.
384
+ whole = selection.fullSelection && currentMarkdown.isNotEmpty(),
385
+ rect = selection.rect,
386
+ startRect = selection.startRect,
387
+ endRect = selection.endRect,
388
+ )
389
+ }
390
+
391
+ fun setEmitLinkLayout(enabled: Boolean) {
392
+ if (linkLayoutEnabled == enabled) return
393
+ linkLayoutEnabled = enabled
394
+ lastLinkLayout = null
395
+ emitLinkLayoutIfNeeded()
396
+ }
397
+
398
+ /**
399
+ * Reports link rects to JS (for `renderLinkDecoration`) after every render and layout;
400
+ * deduplicated so an unchanged layout — the common case while streaming — sends nothing.
401
+ */
402
+ private fun emitLinkLayoutIfNeeded() {
403
+ if (!linkLayoutEnabled || layout == null || width <= 0) return
404
+ val (fragments, _) = LinkLayoutCollector.collect(this)
405
+ if (fragments == lastLinkLayout) return
406
+ lastLinkLayout = fragments
407
+ emitLinkLayout(this, fragments)
408
+ }
409
+
410
+ override fun onLayout(
411
+ changed: Boolean,
412
+ left: Int,
413
+ top: Int,
414
+ right: Int,
415
+ bottom: Int,
416
+ ) {
417
+ super.onLayout(changed, left, top, right, bottom)
418
+ emitLinkLayoutIfNeeded()
419
+ }
420
+
421
+ // Trailing bottom margin included in the shadow-node measurement — must be
422
+ // mirrored when re-storing the measurement from the display text.
423
+ fun trailingMarginBottomPx(): Float = if (allowTrailingMargin) renderer.getLastElementMarginBottom() else 0f
424
+
271
425
  fun setContextMenuItems(items: List<String>) {
272
426
  contextMenuItemTexts = items
273
427
  }
@@ -326,6 +480,10 @@ class EnrichedMarkdownText
326
480
  checkboxTouchHelper.onCheckboxTap = callback
327
481
  }
328
482
 
483
+ fun setEnableTaskListItemToggle(enabled: Boolean) {
484
+ checkboxTouchHelper.isEnabled = enabled
485
+ }
486
+
329
487
  override fun onAttachedToWindow() {
330
488
  super.onAttachedToWindow()
331
489
  pendingStyledText?.let {
@@ -335,6 +493,7 @@ class EnrichedMarkdownText
335
493
  }
336
494
 
337
495
  override fun onDetachedFromWindow() {
496
+ selectionReporter?.cancel()
338
497
  stopSpoilerAnimations()
339
498
  super.onDetachedFromWindow()
340
499
  }
@@ -1,12 +1,21 @@
1
1
  package com.swmansion.enriched.markdown
2
2
 
3
+ import com.facebook.react.bridge.Arguments
4
+
3
5
  class EnrichedMarkdownTextLayoutManager(
4
6
  private val view: EnrichedMarkdownText,
5
7
  ) {
8
+ private var forceHeightRecalculationCounter = 0
9
+
6
10
  fun invalidateLayout() {
7
11
  val text = view.text
8
12
  val paint = view.paint
9
- MeasurementStore.store(view.id, text, paint)
13
+ val heightChanged = MeasurementStore.store(view.id, text, paint, view.trailingMarginBottomPx())
14
+ if (!heightChanged) return
15
+ val stateWrapper = view.stateWrapper ?: return
16
+ val state = Arguments.createMap()
17
+ state.putInt("forceHeightRecalculationCounter", ++forceHeightRecalculationCounter)
18
+ stateWrapper.updateState(state)
10
19
  }
11
20
 
12
21
  fun releaseMeasurementStore() {
@@ -4,7 +4,9 @@ import android.content.Context
4
4
  import com.facebook.react.bridge.ReadableArray
5
5
  import com.facebook.react.bridge.ReadableMap
6
6
  import com.facebook.react.module.annotations.ReactModule
7
+ import com.facebook.react.uimanager.ReactStylesDiffMap
7
8
  import com.facebook.react.uimanager.SimpleViewManager
9
+ import com.facebook.react.uimanager.StateWrapper
8
10
  import com.facebook.react.uimanager.ThemedReactContext
9
11
  import com.facebook.react.uimanager.ViewManagerDelegate
10
12
  import com.facebook.react.uimanager.annotations.ReactProp
@@ -13,12 +15,14 @@ import com.facebook.react.viewmanagers.EnrichedMarkdownTextManagerInterface
13
15
  import com.facebook.yoga.YogaMeasureMode
14
16
  import com.swmansion.enriched.markdown.spoiler.SpoilerOverlay
15
17
  import com.swmansion.enriched.markdown.utils.common.emitContextMenuItemPress
18
+ import com.swmansion.enriched.markdown.utils.common.emitCopyRequest
16
19
  import com.swmansion.enriched.markdown.utils.common.emitLinkLongPress
17
20
  import com.swmansion.enriched.markdown.utils.common.emitLinkPress
18
21
  import com.swmansion.enriched.markdown.utils.common.emitTaskListItemPress
19
22
  import com.swmansion.enriched.markdown.utils.common.markdownEventTypeConstants
20
23
  import com.swmansion.enriched.markdown.utils.common.parseAccessibilityLabels
21
24
  import com.swmansion.enriched.markdown.utils.common.parseContextMenuItems
25
+ import com.swmansion.enriched.markdown.utils.common.parseImageRequestHeaders
22
26
  import com.swmansion.enriched.markdown.utils.common.parseMd4cFlags
23
27
  import com.swmansion.enriched.markdown.utils.common.parseSelectionMenuConfig
24
28
  import com.swmansion.enriched.markdown.utils.text.interaction.TaskListTapUtils
@@ -39,6 +43,9 @@ class EnrichedMarkdownTextManager :
39
43
  view.onContextMenuItemPressCallback = { itemText, selectedText, selectionStart, selectionEnd ->
40
44
  emitContextMenuItemPress(view, itemText, selectedText, selectionStart, selectionEnd)
41
45
  }
46
+ view.onCopyRequestCallback = { markdown, text, whole ->
47
+ emitCopyRequest(view, "selection", markdown, text, whole)
48
+ }
42
49
 
43
50
  view.setOnLinkPressCallback { url ->
44
51
  emitLinkPress(view, url)
@@ -69,6 +76,20 @@ class EnrichedMarkdownTextManager :
69
76
  return view
70
77
  }
71
78
 
79
+ override fun onAfterUpdateTransaction(view: EnrichedMarkdownText) {
80
+ super.onAfterUpdateTransaction(view)
81
+ view.commitProps()
82
+ }
83
+
84
+ override fun updateState(
85
+ view: EnrichedMarkdownText,
86
+ props: ReactStylesDiffMap?,
87
+ stateWrapper: StateWrapper?,
88
+ ): Any? {
89
+ view.stateWrapper = stateWrapper
90
+ return super.updateState(view, props, stateWrapper)
91
+ }
92
+
72
93
  override fun onDropViewInstance(view: EnrichedMarkdownText) {
73
94
  super.onDropViewInstance(view)
74
95
  MeasurementStore.clearFontScalingSettings(view.id)
@@ -148,6 +169,36 @@ class EnrichedMarkdownTextManager :
148
169
  view?.setAllowTrailingMargin(allowTrailingMargin)
149
170
  }
150
171
 
172
+ @ReactProp(name = "contextMenuHidden", defaultBoolean = false)
173
+ override fun setContextMenuHidden(
174
+ view: EnrichedMarkdownText?,
175
+ contextMenuHidden: Boolean,
176
+ ) {
177
+ view?.setContextMenuHidden(contextMenuHidden)
178
+ }
179
+
180
+ @ReactProp(name = "emitLinkLayout", defaultBoolean = false)
181
+ override fun setEmitLinkLayout(
182
+ view: EnrichedMarkdownText?,
183
+ emitLinkLayout: Boolean,
184
+ ) {
185
+ view?.setEmitLinkLayout(emitLinkLayout)
186
+ }
187
+
188
+ @ReactProp(name = "emitSelectionChange", defaultBoolean = false)
189
+ override fun setEmitSelectionChange(
190
+ view: EnrichedMarkdownText?,
191
+ emitSelectionChange: Boolean,
192
+ ) {
193
+ view?.setEmitSelectionChange(emitSelectionChange)
194
+ }
195
+
196
+ // Commands
197
+
198
+ override fun clearSelection(view: EnrichedMarkdownText?) {
199
+ view?.clearSelection()
200
+ }
201
+
151
202
  @ReactProp(name = "enableLinkPreview", defaultBoolean = true)
152
203
  override fun setEnableLinkPreview(
153
204
  view: EnrichedMarkdownText?,
@@ -156,6 +207,22 @@ class EnrichedMarkdownTextManager :
156
207
  // No-op on Android — only used on iOS
157
208
  }
158
209
 
210
+ @ReactProp(name = "linkLongPressSelects", defaultBoolean = false)
211
+ override fun setLinkLongPressSelects(
212
+ view: EnrichedMarkdownText?,
213
+ linkLongPressSelects: Boolean,
214
+ ) {
215
+ // No-op on Android — only used on iOS
216
+ }
217
+
218
+ @ReactProp(name = "enableTaskListItemToggle", defaultBoolean = true)
219
+ override fun setEnableTaskListItemToggle(
220
+ view: EnrichedMarkdownText?,
221
+ enableTaskListItemToggle: Boolean,
222
+ ) {
223
+ view?.setEnableTaskListItemToggle(enableTaskListItemToggle)
224
+ }
225
+
159
226
  @ReactProp(name = "lineBreakStrategyIOS")
160
227
  override fun setLineBreakStrategyIOS(
161
228
  view: EnrichedMarkdownText?,
@@ -213,6 +280,15 @@ class EnrichedMarkdownTextManager :
213
280
  view.setContextMenuItems(parseContextMenuItems(value))
214
281
  }
215
282
 
283
+ @ReactProp(name = "imageRequestHeaders")
284
+ override fun setImageRequestHeaders(
285
+ view: EnrichedMarkdownText?,
286
+ value: ReadableArray?,
287
+ ) {
288
+ if (view == null) return
289
+ view.setImageRequestHeaders(parseImageRequestHeaders(value))
290
+ }
291
+
216
292
  @ReactProp(name = "selectionMenuConfig")
217
293
  override fun setSelectionMenuConfig(
218
294
  view: EnrichedMarkdownText?,