react-native-enriched-markdown 0.1.0 → 0.2.0

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 (226) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +551 -0
  3. package/ReactNativeEnrichedMarkdown.podspec +27 -0
  4. package/android/build.gradle +101 -0
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +54 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +26 -0
  7. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.cpp +22 -0
  8. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.h +24 -0
  9. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +33 -0
  10. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +31 -0
  11. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +82 -0
  12. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +1388 -0
  13. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ShadowNodes.cpp +17 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ShadowNodes.h +32 -0
  15. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/States.cpp +16 -0
  16. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/States.h +20 -0
  17. package/android/gradle.properties +5 -0
  18. package/android/src/main/AndroidManifest.xml +2 -0
  19. package/android/src/main/baseline-prof.txt +65 -0
  20. package/android/src/main/cpp/jni-adapter.cpp +220 -0
  21. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +270 -0
  22. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +15 -0
  23. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +173 -0
  24. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextPackage.kt +17 -0
  25. package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +385 -0
  26. package/android/src/main/java/com/swmansion/enriched/markdown/accessibility/MarkdownAccessibilityHelper.kt +279 -0
  27. package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkLongPressEvent.kt +23 -0
  28. package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkPressEvent.kt +23 -0
  29. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +31 -0
  30. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +62 -0
  31. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +166 -0
  32. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +84 -0
  33. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +104 -0
  34. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeRenderer.kt +36 -0
  35. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/DocumentRenderer.kt +16 -0
  36. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/EmphasisRenderer.kt +27 -0
  37. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +70 -0
  38. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt +68 -0
  39. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LineBreakRenderer.kt +16 -0
  40. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt +29 -0
  41. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +105 -0
  42. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +59 -0
  43. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +76 -0
  44. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +103 -0
  45. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ParagraphRenderer.kt +80 -0
  46. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/Renderer.kt +109 -0
  47. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +86 -0
  48. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/StrikethroughRenderer.kt +27 -0
  49. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/StrongRenderer.kt +27 -0
  50. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/TextRenderer.kt +30 -0
  51. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ThematicBreakRenderer.kt +45 -0
  52. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/UnderlineRenderer.kt +27 -0
  53. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +136 -0
  54. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +135 -0
  55. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +180 -0
  56. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +196 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +27 -0
  58. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +34 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/spans/HeadingSpan.kt +38 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +321 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/spans/LineHeightSpan.kt +27 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +51 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/spans/MarginBottomSpan.kt +76 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +87 -0
  65. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrikethroughSpan.kt +12 -0
  66. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +37 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TextSpan.kt +26 -0
  68. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ThematicBreakSpan.kt +69 -0
  69. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +69 -0
  70. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BaseBlockStyle.kt +11 -0
  71. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +51 -0
  72. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +54 -0
  73. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeStyle.kt +21 -0
  74. package/android/src/main/java/com/swmansion/enriched/markdown/styles/EmphasisStyle.kt +17 -0
  75. package/android/src/main/java/com/swmansion/enriched/markdown/styles/HeadingStyle.kt +33 -0
  76. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +23 -0
  77. package/android/src/main/java/com/swmansion/enriched/markdown/styles/InlineImageStyle.kt +17 -0
  78. package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkStyle.kt +19 -0
  79. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +57 -0
  80. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ParagraphStyle.kt +33 -0
  81. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StrikethroughStyle.kt +17 -0
  82. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StrongStyle.kt +17 -0
  83. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +211 -0
  84. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleParser.kt +92 -0
  85. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TextAlignment.kt +32 -0
  86. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ThematicBreakStyle.kt +23 -0
  87. package/android/src/main/java/com/swmansion/enriched/markdown/styles/UnderlineStyle.kt +17 -0
  88. package/android/src/main/java/com/swmansion/enriched/markdown/utils/AsyncDrawable.kt +91 -0
  89. package/android/src/main/java/com/swmansion/enriched/markdown/utils/HTMLGenerator.kt +827 -0
  90. package/android/src/main/java/com/swmansion/enriched/markdown/utils/LinkLongPressMovementMethod.kt +121 -0
  91. package/android/src/main/java/com/swmansion/enriched/markdown/utils/MarkdownExtractor.kt +375 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/utils/SelectionActionMode.kt +139 -0
  93. package/android/src/main/java/com/swmansion/enriched/markdown/utils/Utils.kt +183 -0
  94. package/android/src/main/jni/CMakeLists.txt +70 -0
  95. package/android/src/main/jni/EnrichedMarkdownTextSpec.cpp +21 -0
  96. package/android/src/main/jni/EnrichedMarkdownTextSpec.h +25 -0
  97. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextComponentDescriptor.h +29 -0
  98. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextMeasurementManager.cpp +45 -0
  99. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextMeasurementManager.h +21 -0
  100. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +20 -0
  101. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +37 -0
  102. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +22 -0
  103. package/cpp/md4c/md4c.c +6492 -0
  104. package/cpp/md4c/md4c.h +402 -0
  105. package/cpp/parser/MD4CParser.cpp +327 -0
  106. package/cpp/parser/MD4CParser.hpp +27 -0
  107. package/cpp/parser/MarkdownASTNode.hpp +51 -0
  108. package/ios/EnrichedMarkdownText.h +18 -0
  109. package/ios/EnrichedMarkdownText.mm +1401 -0
  110. package/ios/attachments/EnrichedMarkdownImageAttachment.h +23 -0
  111. package/ios/attachments/EnrichedMarkdownImageAttachment.m +185 -0
  112. package/ios/attachments/ThematicBreakAttachment.h +15 -0
  113. package/ios/attachments/ThematicBreakAttachment.m +33 -0
  114. package/ios/generated/EnrichedMarkdownTextSpec/ComponentDescriptors.cpp +22 -0
  115. package/ios/generated/EnrichedMarkdownTextSpec/ComponentDescriptors.h +24 -0
  116. package/ios/generated/EnrichedMarkdownTextSpec/EventEmitters.cpp +33 -0
  117. package/ios/generated/EnrichedMarkdownTextSpec/EventEmitters.h +31 -0
  118. package/ios/generated/EnrichedMarkdownTextSpec/Props.cpp +82 -0
  119. package/ios/generated/EnrichedMarkdownTextSpec/Props.h +1388 -0
  120. package/ios/generated/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +20 -0
  121. package/ios/generated/EnrichedMarkdownTextSpec/ShadowNodes.cpp +17 -0
  122. package/ios/generated/EnrichedMarkdownTextSpec/ShadowNodes.h +32 -0
  123. package/ios/generated/EnrichedMarkdownTextSpec/States.cpp +16 -0
  124. package/ios/generated/EnrichedMarkdownTextSpec/States.h +20 -0
  125. package/ios/internals/EnrichedMarkdownTextComponentDescriptor.h +19 -0
  126. package/ios/internals/EnrichedMarkdownTextShadowNode.h +43 -0
  127. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +85 -0
  128. package/ios/internals/EnrichedMarkdownTextState.h +24 -0
  129. package/ios/parser/MarkdownASTNode.h +35 -0
  130. package/ios/parser/MarkdownASTNode.m +32 -0
  131. package/ios/parser/MarkdownParser.h +17 -0
  132. package/ios/parser/MarkdownParser.mm +42 -0
  133. package/ios/parser/MarkdownParserBridge.mm +120 -0
  134. package/ios/renderer/AttributedRenderer.h +11 -0
  135. package/ios/renderer/AttributedRenderer.m +152 -0
  136. package/ios/renderer/BlockquoteRenderer.h +7 -0
  137. package/ios/renderer/BlockquoteRenderer.m +160 -0
  138. package/ios/renderer/CodeBlockRenderer.h +10 -0
  139. package/ios/renderer/CodeBlockRenderer.m +90 -0
  140. package/ios/renderer/CodeRenderer.h +10 -0
  141. package/ios/renderer/CodeRenderer.m +60 -0
  142. package/ios/renderer/EmphasisRenderer.h +6 -0
  143. package/ios/renderer/EmphasisRenderer.m +96 -0
  144. package/ios/renderer/HeadingRenderer.h +7 -0
  145. package/ios/renderer/HeadingRenderer.m +105 -0
  146. package/ios/renderer/ImageRenderer.h +12 -0
  147. package/ios/renderer/ImageRenderer.m +83 -0
  148. package/ios/renderer/LinkRenderer.h +7 -0
  149. package/ios/renderer/LinkRenderer.m +69 -0
  150. package/ios/renderer/ListItemRenderer.h +16 -0
  151. package/ios/renderer/ListItemRenderer.m +103 -0
  152. package/ios/renderer/ListRenderer.h +13 -0
  153. package/ios/renderer/ListRenderer.m +70 -0
  154. package/ios/renderer/NodeRenderer.h +8 -0
  155. package/ios/renderer/ParagraphRenderer.h +7 -0
  156. package/ios/renderer/ParagraphRenderer.m +80 -0
  157. package/ios/renderer/RenderContext.h +105 -0
  158. package/ios/renderer/RenderContext.m +312 -0
  159. package/ios/renderer/RendererFactory.h +12 -0
  160. package/ios/renderer/RendererFactory.m +116 -0
  161. package/ios/renderer/StrikethroughRenderer.h +6 -0
  162. package/ios/renderer/StrikethroughRenderer.m +40 -0
  163. package/ios/renderer/StrongRenderer.h +6 -0
  164. package/ios/renderer/StrongRenderer.m +83 -0
  165. package/ios/renderer/TextRenderer.h +6 -0
  166. package/ios/renderer/TextRenderer.m +16 -0
  167. package/ios/renderer/ThematicBreakRenderer.h +5 -0
  168. package/ios/renderer/ThematicBreakRenderer.m +53 -0
  169. package/ios/renderer/UnderlineRenderer.h +6 -0
  170. package/ios/renderer/UnderlineRenderer.m +39 -0
  171. package/ios/styles/StyleConfig.h +274 -0
  172. package/ios/styles/StyleConfig.mm +1806 -0
  173. package/ios/utils/AccessibilityInfo.h +35 -0
  174. package/ios/utils/AccessibilityInfo.m +24 -0
  175. package/ios/utils/BlockquoteBorder.h +20 -0
  176. package/ios/utils/BlockquoteBorder.m +92 -0
  177. package/ios/utils/CodeBackground.h +19 -0
  178. package/ios/utils/CodeBackground.m +191 -0
  179. package/ios/utils/CodeBlockBackground.h +17 -0
  180. package/ios/utils/CodeBlockBackground.m +82 -0
  181. package/ios/utils/EditMenuUtils.h +22 -0
  182. package/ios/utils/EditMenuUtils.m +118 -0
  183. package/ios/utils/FontUtils.h +25 -0
  184. package/ios/utils/FontUtils.m +27 -0
  185. package/ios/utils/HTMLGenerator.h +20 -0
  186. package/ios/utils/HTMLGenerator.m +793 -0
  187. package/ios/utils/LastElementUtils.h +53 -0
  188. package/ios/utils/ListMarkerDrawer.h +15 -0
  189. package/ios/utils/ListMarkerDrawer.m +127 -0
  190. package/ios/utils/MarkdownAccessibilityElementBuilder.h +45 -0
  191. package/ios/utils/MarkdownAccessibilityElementBuilder.m +323 -0
  192. package/ios/utils/MarkdownExtractor.h +17 -0
  193. package/ios/utils/MarkdownExtractor.m +308 -0
  194. package/ios/utils/ParagraphStyleUtils.h +21 -0
  195. package/ios/utils/ParagraphStyleUtils.m +111 -0
  196. package/ios/utils/PasteboardUtils.h +36 -0
  197. package/ios/utils/PasteboardUtils.m +134 -0
  198. package/ios/utils/RTFExportUtils.h +24 -0
  199. package/ios/utils/RTFExportUtils.m +297 -0
  200. package/ios/utils/RuntimeKeys.h +38 -0
  201. package/ios/utils/RuntimeKeys.m +11 -0
  202. package/ios/utils/TextViewLayoutManager.h +14 -0
  203. package/ios/utils/TextViewLayoutManager.mm +113 -0
  204. package/lib/module/EnrichedMarkdownText.js +65 -0
  205. package/lib/module/EnrichedMarkdownText.js.map +1 -0
  206. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +210 -0
  207. package/lib/module/index.js +4 -0
  208. package/lib/module/index.js.map +1 -0
  209. package/lib/module/normalizeMarkdownStyle.js +384 -0
  210. package/lib/module/normalizeMarkdownStyle.js.map +1 -0
  211. package/lib/module/package.json +1 -0
  212. package/lib/typescript/package.json +1 -0
  213. package/lib/typescript/src/EnrichedMarkdownText.d.ts +183 -0
  214. package/lib/typescript/src/EnrichedMarkdownText.d.ts.map +1 -0
  215. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +185 -0
  216. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -0
  217. package/lib/typescript/src/index.d.ts +4 -0
  218. package/lib/typescript/src/index.d.ts.map +1 -0
  219. package/lib/typescript/src/normalizeMarkdownStyle.d.ts +6 -0
  220. package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -0
  221. package/package.json +186 -1
  222. package/react-native.config.js +13 -0
  223. package/src/EnrichedMarkdownText.tsx +280 -0
  224. package/src/EnrichedMarkdownTextNativeComponent.ts +210 -0
  225. package/src/index.tsx +10 -0
  226. package/src/normalizeMarkdownStyle.ts +423 -0
@@ -0,0 +1,17 @@
1
+
2
+ /**
3
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
4
+ *
5
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
6
+ * once the code is regenerated.
7
+ *
8
+ * @generated by codegen project: GenerateShadowNodeCpp.js
9
+ */
10
+
11
+ #include "ShadowNodes.h"
12
+
13
+ namespace facebook::react {
14
+
15
+ extern const char EnrichedMarkdownTextComponentName[] = "EnrichedMarkdownText";
16
+
17
+ } // namespace facebook::react
@@ -0,0 +1,32 @@
1
+
2
+ /**
3
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
4
+ *
5
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
6
+ * once the code is regenerated.
7
+ *
8
+ * @generated by codegen project: GenerateShadowNodeH.js
9
+ */
10
+
11
+ #pragma once
12
+
13
+ #include "EventEmitters.h"
14
+ #include "Props.h"
15
+ #include "States.h"
16
+ #include <react/renderer/components/view/ConcreteViewShadowNode.h>
17
+ #include <jsi/jsi.h>
18
+
19
+ namespace facebook::react {
20
+
21
+ JSI_EXPORT extern const char EnrichedMarkdownTextComponentName[];
22
+
23
+ /*
24
+ * `ShadowNode` for <EnrichedMarkdownText> component.
25
+ */
26
+ using EnrichedMarkdownTextShadowNode = ConcreteViewShadowNode<
27
+ EnrichedMarkdownTextComponentName,
28
+ EnrichedMarkdownTextProps,
29
+ EnrichedMarkdownTextEventEmitter,
30
+ EnrichedMarkdownTextState>;
31
+
32
+ } // namespace facebook::react
@@ -0,0 +1,16 @@
1
+
2
+ /**
3
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
4
+ *
5
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
6
+ * once the code is regenerated.
7
+ *
8
+ * @generated by codegen project: GenerateStateCpp.js
9
+ */
10
+ #include "States.h"
11
+
12
+ namespace facebook::react {
13
+
14
+
15
+
16
+ } // namespace facebook::react
@@ -0,0 +1,20 @@
1
+ /**
2
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
3
+ *
4
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
5
+ * once the code is regenerated.
6
+ *
7
+ * @generated by codegen project: GenerateStateH.js
8
+ */
9
+ #pragma once
10
+
11
+ #include <react/renderer/core/StateData.h>
12
+ #ifdef RN_SERIALIZABLE_STATE
13
+ #include <folly/dynamic.h>
14
+ #endif
15
+
16
+ namespace facebook::react {
17
+
18
+ using EnrichedMarkdownTextState = StateData;
19
+
20
+ } // namespace facebook::react
@@ -0,0 +1,5 @@
1
+ EnrichedMarkdown_kotlinVersion=2.0.21
2
+ EnrichedMarkdown_minSdkVersion=24
3
+ EnrichedMarkdown_targetSdkVersion=34
4
+ EnrichedMarkdown_compileSdkVersion=35
5
+ EnrichedMarkdown_ndkVersion=27.1.12297006
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,65 @@
1
+ # Baseline Profile for react-native-enriched-markdown
2
+ # These classes will be AOT compiled during app install
3
+ # to improve cold start performance.
4
+
5
+ # Core View and Rendering
6
+ Lcom/swmansion/enriched/markdown/EnrichedMarkdownText;
7
+ Lcom/swmansion/enriched/markdown/EnrichedMarkdownTextManager;
8
+ Lcom/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager;
9
+
10
+ # Renderer Classes
11
+ Lcom/swmansion/enriched/markdown/renderer/Renderer;
12
+ Lcom/swmansion/enriched/markdown/renderer/RendererFactory;
13
+ Lcom/swmansion/enriched/markdown/renderer/RendererConfig;
14
+ Lcom/swmansion/enriched/markdown/renderer/BlockStyleContext;
15
+ Lcom/swmansion/enriched/markdown/renderer/BlockStyle;
16
+ Lcom/swmansion/enriched/markdown/renderer/SpanStyleCache;
17
+ Lcom/swmansion/enriched/markdown/renderer/NodeRenderer;
18
+ Lcom/swmansion/enriched/markdown/renderer/TextRenderer;
19
+ Lcom/swmansion/enriched/markdown/renderer/ParagraphRenderer;
20
+ Lcom/swmansion/enriched/markdown/renderer/HeadingRenderer;
21
+ Lcom/swmansion/enriched/markdown/renderer/StrongRenderer;
22
+ Lcom/swmansion/enriched/markdown/renderer/EmphasisRenderer;
23
+ Lcom/swmansion/enriched/markdown/renderer/LinkRenderer;
24
+ Lcom/swmansion/enriched/markdown/renderer/ListRenderer;
25
+ Lcom/swmansion/enriched/markdown/renderer/ListItemRenderer;
26
+ Lcom/swmansion/enriched/markdown/renderer/BlockquoteRenderer;
27
+ Lcom/swmansion/enriched/markdown/renderer/CodeBlockRenderer;
28
+ Lcom/swmansion/enriched/markdown/renderer/CodeRenderer;
29
+ Lcom/swmansion/enriched/markdown/renderer/ImageRenderer;
30
+ Lcom/swmansion/enriched/markdown/renderer/LineBreakRenderer;
31
+ Lcom/swmansion/enriched/markdown/renderer/DocumentRenderer;
32
+
33
+ # Spans
34
+ Lcom/swmansion/enriched/markdown/spans/StrongSpan;
35
+ Lcom/swmansion/enriched/markdown/spans/EmphasisSpan;
36
+ Lcom/swmansion/enriched/markdown/spans/CodeSpan;
37
+ Lcom/swmansion/enriched/markdown/spans/TextSpan;
38
+ Lcom/swmansion/enriched/markdown/spans/HeadingSpan;
39
+ Lcom/swmansion/enriched/markdown/spans/LinkSpan;
40
+ Lcom/swmansion/enriched/markdown/spans/LineHeightSpan;
41
+ Lcom/swmansion/enriched/markdown/spans/MarginBottomSpan;
42
+ Lcom/swmansion/enriched/markdown/spans/BaseListSpan;
43
+ Lcom/swmansion/enriched/markdown/spans/UnorderedListSpan;
44
+ Lcom/swmansion/enriched/markdown/spans/OrderedListSpan;
45
+ Lcom/swmansion/enriched/markdown/spans/BlockquoteSpan;
46
+ Lcom/swmansion/enriched/markdown/spans/CodeBlockSpan;
47
+ Lcom/swmansion/enriched/markdown/spans/CodeBackgroundSpan;
48
+ Lcom/swmansion/enriched/markdown/spans/ImageSpan;
49
+
50
+ # Style Configuration
51
+ Lcom/swmansion/enriched/markdown/styles/StyleConfig;
52
+ Lcom/swmansion/enriched/markdown/styles/ParagraphStyle;
53
+ Lcom/swmansion/enriched/markdown/styles/HeadingStyle;
54
+ Lcom/swmansion/enriched/markdown/styles/ListStyle;
55
+ Lcom/swmansion/enriched/markdown/styles/BlockquoteStyle;
56
+ Lcom/swmansion/enriched/markdown/styles/CodeBlockStyle;
57
+ Lcom/swmansion/enriched/markdown/styles/CodeStyle;
58
+
59
+ # Parser
60
+ Lcom/swmansion/enriched/markdown/parser/Parser;
61
+ Lcom/swmansion/enriched/markdown/parser/MarkdownASTNode;
62
+ Lcom/swmansion/enriched/markdown/parser/MarkdownASTNode$NodeType;
63
+
64
+ # Utilities
65
+ Lcom/swmansion/enriched/markdown/utils/UtilsKt;
@@ -0,0 +1,220 @@
1
+ #include "MD4CParser.hpp"
2
+ #include <android/log.h>
3
+ #include <jni.h>
4
+ #include <string>
5
+
6
+ using namespace Markdown;
7
+
8
+ #define ENRICHEDMARKDOWN_LOG_TAG "EnrichedMarkdownJNI"
9
+ #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, ENRICHEDMARKDOWN_LOG_TAG, __VA_ARGS__)
10
+ #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, ENRICHEDMARKDOWN_LOG_TAG, __VA_ARGS__)
11
+
12
+ // Helper function to convert C++ NodeType to Kotlin enum ordinal
13
+ static jint nodeTypeToJavaOrdinal(NodeType type) {
14
+ switch (type) {
15
+ case NodeType::Document:
16
+ return 0;
17
+ case NodeType::Paragraph:
18
+ return 1;
19
+ case NodeType::Text:
20
+ return 2;
21
+ case NodeType::Link:
22
+ return 3;
23
+ case NodeType::Heading:
24
+ return 4;
25
+ case NodeType::LineBreak:
26
+ return 5;
27
+ case NodeType::Strong:
28
+ return 6;
29
+ case NodeType::Emphasis:
30
+ return 7;
31
+ case NodeType::Strikethrough:
32
+ return 8;
33
+ case NodeType::Underline:
34
+ return 9;
35
+ case NodeType::Code:
36
+ return 10;
37
+ case NodeType::Image:
38
+ return 11;
39
+ case NodeType::Blockquote:
40
+ return 12;
41
+ case NodeType::UnorderedList:
42
+ return 13;
43
+ case NodeType::OrderedList:
44
+ return 14;
45
+ case NodeType::ListItem:
46
+ return 15;
47
+ case NodeType::CodeBlock:
48
+ return 16;
49
+ case NodeType::ThematicBreak:
50
+ return 17;
51
+ default:
52
+ return 0;
53
+ }
54
+ }
55
+
56
+ // Helper function to create a Kotlin MarkdownASTNode object from C++ AST node
57
+ static jobject createJavaNode(JNIEnv *env, std::shared_ptr<MarkdownASTNode> node) {
58
+ if (!node) {
59
+ return nullptr;
60
+ }
61
+
62
+ // Find the MarkdownASTNode class
63
+ jclass nodeClass = env->FindClass("com/swmansion/enriched/markdown/parser/MarkdownASTNode");
64
+ if (!nodeClass) {
65
+ LOGE("Failed to find MarkdownASTNode class");
66
+ return nullptr;
67
+ }
68
+
69
+ // Find the NodeType enum class
70
+ jclass nodeTypeClass = env->FindClass("com/swmansion/enriched/markdown/parser/MarkdownASTNode$NodeType");
71
+ if (!nodeTypeClass) {
72
+ LOGE("Failed to find NodeType enum class");
73
+ return nullptr;
74
+ }
75
+
76
+ // Get the enum values array
77
+ jmethodID valuesMethod = env->GetStaticMethodID(
78
+ nodeTypeClass, "values", "()[Lcom/swmansion/enriched/markdown/parser/MarkdownASTNode$NodeType;");
79
+ if (!valuesMethod) {
80
+ LOGE("Failed to find NodeType.values() method");
81
+ return nullptr;
82
+ }
83
+
84
+ jobjectArray enumValues = (jobjectArray)env->CallStaticObjectMethod(nodeTypeClass, valuesMethod);
85
+ if (!enumValues) {
86
+ LOGE("Failed to get NodeType enum values");
87
+ return nullptr;
88
+ }
89
+
90
+ // Get the enum value for this node type
91
+ jint ordinal = nodeTypeToJavaOrdinal(node->type);
92
+ jobject nodeTypeEnum = env->GetObjectArrayElement(enumValues, ordinal);
93
+ if (!nodeTypeEnum) {
94
+ LOGE("Failed to get NodeType enum value at index %d", ordinal);
95
+ return nullptr;
96
+ }
97
+
98
+ // Create content string
99
+ jstring contentStr = env->NewStringUTF(node->content.c_str());
100
+ if (!contentStr && !node->content.empty()) {
101
+ LOGE("Failed to create content string");
102
+ return nullptr;
103
+ }
104
+
105
+ // Create attributes HashMap
106
+ jclass mapClass = env->FindClass("java/util/HashMap");
107
+ jmethodID mapInit = env->GetMethodID(mapClass, "<init>", "(I)V");
108
+ jmethodID mapPut = env->GetMethodID(mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
109
+
110
+ jobject attributesMap = env->NewObject(mapClass, mapInit, static_cast<jint>(node->attributes.size()));
111
+
112
+ for (const auto &pair : node->attributes) {
113
+ jstring key = env->NewStringUTF(pair.first.c_str());
114
+ jstring value = env->NewStringUTF(pair.second.c_str());
115
+ env->CallObjectMethod(attributesMap, mapPut, key, value);
116
+ env->DeleteLocalRef(key);
117
+ env->DeleteLocalRef(value);
118
+ }
119
+
120
+ // Create children ArrayList
121
+ jclass listClass = env->FindClass("java/util/ArrayList");
122
+ jmethodID listInit = env->GetMethodID(listClass, "<init>", "(I)V");
123
+ jmethodID listAdd = env->GetMethodID(listClass, "add", "(Ljava/lang/Object;)Z");
124
+
125
+ jobject childrenList = env->NewObject(listClass, listInit, static_cast<jint>(node->children.size()));
126
+
127
+ for (const auto &child : node->children) {
128
+ jobject childObj = createJavaNode(env, child);
129
+ if (childObj) {
130
+ env->CallBooleanMethod(childrenList, listAdd, childObj);
131
+ env->DeleteLocalRef(childObj);
132
+ }
133
+ }
134
+
135
+ // Find the MarkdownASTNode constructor
136
+ // Constructor signature: (Lcom/swmansion/enriched/markdown/parser/MarkdownASTNode$NodeType;Ljava/lang/String;Ljava/util/Map;Ljava/util/List;)V
137
+ jmethodID constructor = env->GetMethodID(nodeClass, "<init>",
138
+ "(Lcom/swmansion/enriched/markdown/parser/MarkdownASTNode$NodeType;Ljava/"
139
+ "lang/String;Ljava/util/Map;Ljava/util/List;)V");
140
+ if (!constructor) {
141
+ LOGE("Failed to find MarkdownASTNode constructor");
142
+ return nullptr;
143
+ }
144
+
145
+ // Create the Kotlin MarkdownASTNode object
146
+ jobject javaNode = env->NewObject(nodeClass, constructor, nodeTypeEnum, contentStr, attributesMap, childrenList);
147
+
148
+ // Clean up local references
149
+ env->DeleteLocalRef(nodeTypeClass);
150
+ env->DeleteLocalRef(enumValues);
151
+ env->DeleteLocalRef(nodeTypeEnum);
152
+ if (contentStr)
153
+ env->DeleteLocalRef(contentStr);
154
+ env->DeleteLocalRef(attributesMap);
155
+ env->DeleteLocalRef(childrenList);
156
+
157
+ return javaNode;
158
+ }
159
+
160
+ extern "C" {
161
+
162
+ JNIEXPORT jobject JNICALL Java_com_swmansion_enriched_markdown_parser_Parser_nativeParseMarkdown(JNIEnv *env,
163
+ jobject /* this */,
164
+ jstring markdown,
165
+ jobject flags) {
166
+ if (!markdown) {
167
+ LOGE("Markdown string is null");
168
+ return nullptr;
169
+ }
170
+
171
+ const char *markdownStr = env->GetStringUTFChars(markdown, nullptr);
172
+ if (!markdownStr) {
173
+ LOGE("Failed to get UTF-8 chars from markdown string");
174
+ return nullptr;
175
+ }
176
+
177
+ try {
178
+ // Extract flags from Kotlin Md4cFlags data class
179
+ Md4cFlags md4cFlags;
180
+ if (flags) {
181
+ jclass flagsClass = env->GetObjectClass(flags);
182
+ if (flagsClass) {
183
+ jfieldID underlineField = env->GetFieldID(flagsClass, "underline", "Z");
184
+ if (underlineField) {
185
+ md4cFlags.underline = env->GetBooleanField(flags, underlineField) == JNI_TRUE;
186
+ }
187
+ env->DeleteLocalRef(flagsClass);
188
+ }
189
+ }
190
+
191
+ MD4CParser parser;
192
+ auto ast = parser.parse(std::string(markdownStr), md4cFlags);
193
+
194
+ env->ReleaseStringUTFChars(markdown, markdownStr);
195
+
196
+ if (!ast) {
197
+ LOGE("Parser returned null AST");
198
+ return nullptr;
199
+ }
200
+
201
+ // Convert C++ AST to Kotlin MarkdownASTNode object
202
+ jobject javaNode = createJavaNode(env, ast);
203
+
204
+ if (!javaNode) {
205
+ LOGE("Failed to create Java node from AST");
206
+ }
207
+
208
+ return javaNode;
209
+ } catch (const std::exception &e) {
210
+ env->ReleaseStringUTFChars(markdown, markdownStr);
211
+ LOGE("Exception during parsing: %s", e.what());
212
+ return nullptr;
213
+ } catch (...) {
214
+ env->ReleaseStringUTFChars(markdown, markdownStr);
215
+ LOGE("Unknown exception during parsing");
216
+ return nullptr;
217
+ }
218
+ }
219
+
220
+ } // extern "C"
@@ -0,0 +1,270 @@
1
+ package com.swmansion.enriched.markdown
2
+
3
+ import android.content.Context
4
+ import android.content.res.Configuration
5
+ import android.graphics.Color
6
+ import android.os.Build
7
+ import android.os.Handler
8
+ import android.os.Looper
9
+ import android.text.Layout
10
+ import android.util.AttributeSet
11
+ import android.util.Log
12
+ import androidx.appcompat.widget.AppCompatTextView
13
+ import androidx.core.view.ViewCompat
14
+ import com.facebook.react.bridge.ReadableMap
15
+ import com.facebook.react.uimanager.UIManagerHelper
16
+ import com.swmansion.enriched.markdown.accessibility.MarkdownAccessibilityHelper
17
+ import com.swmansion.enriched.markdown.events.LinkLongPressEvent
18
+ import com.swmansion.enriched.markdown.events.LinkPressEvent
19
+ import com.swmansion.enriched.markdown.parser.Md4cFlags
20
+ import com.swmansion.enriched.markdown.parser.Parser
21
+ import com.swmansion.enriched.markdown.renderer.Renderer
22
+ import com.swmansion.enriched.markdown.styles.StyleConfig
23
+ import com.swmansion.enriched.markdown.utils.LinkLongPressMovementMethod
24
+ import com.swmansion.enriched.markdown.utils.createSelectionActionModeCallback
25
+ import java.util.concurrent.Executors
26
+
27
+ /**
28
+ * EnrichedMarkdownText that handles Markdown parsing and rendering on a background thread.
29
+ * View starts invisible and becomes visible after render completes to avoid layout shift.
30
+ */
31
+ class EnrichedMarkdownText
32
+ @JvmOverloads
33
+ constructor(
34
+ context: Context,
35
+ attrs: AttributeSet? = null,
36
+ defStyleAttr: Int = 0,
37
+ ) : AppCompatTextView(context, attrs, defStyleAttr) {
38
+ private val parser = Parser.shared
39
+ private val renderer = Renderer()
40
+ private var onLinkPressCallback: ((String) -> Unit)? = null
41
+ private var onLinkLongPressCallback: ((String) -> Unit)? = null
42
+
43
+ private val mainHandler = Handler(Looper.getMainLooper())
44
+ private val executor = Executors.newSingleThreadExecutor()
45
+ private var currentRenderId = 0L
46
+
47
+ val layoutManager = EnrichedMarkdownTextLayoutManager(this)
48
+
49
+ // Accessibility helper for TalkBack support
50
+ private val accessibilityHelper = MarkdownAccessibilityHelper(this)
51
+
52
+ var markdownStyle: StyleConfig? = null
53
+ private set
54
+
55
+ var currentMarkdown: String = ""
56
+ private set
57
+
58
+ var md4cFlags: Md4cFlags = Md4cFlags.DEFAULT
59
+ private set
60
+
61
+ private var lastKnownFontScale: Float = context.resources.configuration.fontScale
62
+ private var markdownStyleMap: ReadableMap? = null
63
+
64
+ private var allowFontScaling: Boolean = true
65
+ private var maxFontSizeMultiplier: Float = 0f
66
+ private var allowTrailingMargin: Boolean = false
67
+
68
+ init {
69
+ setBackgroundColor(Color.TRANSPARENT)
70
+ includeFontPadding = false // Must match setIncludePad(false) in MeasurementStore
71
+ movementMethod = LinkLongPressMovementMethod.createInstance()
72
+ setTextIsSelectable(true)
73
+ customSelectionActionModeCallback = createSelectionActionModeCallback(this)
74
+ isVerticalScrollBarEnabled = false
75
+ isHorizontalScrollBarEnabled = false
76
+
77
+ // Set up accessibility for TalkBack
78
+ // This enables virtual view hierarchy for semantic navigation (headings, links, etc.)
79
+ ViewCompat.setAccessibilityDelegate(this, accessibilityHelper)
80
+ }
81
+
82
+ fun setMarkdownContent(markdown: String) {
83
+ if (currentMarkdown == markdown) return
84
+ currentMarkdown = markdown
85
+ scheduleRender()
86
+ }
87
+
88
+ fun setMarkdownStyle(style: ReadableMap?) {
89
+ markdownStyleMap = style
90
+ // Register font scaling settings when style is set (view should have ID by now)
91
+ updateMeasurementStoreFontScaling()
92
+ val newStyle = style?.let { StyleConfig(it, context, allowFontScaling, maxFontSizeMultiplier) }
93
+ if (markdownStyle == newStyle) return
94
+ markdownStyle = newStyle
95
+ updateJustificationMode(newStyle)
96
+ scheduleRender()
97
+ }
98
+
99
+ override fun onConfigurationChanged(newConfig: Configuration) {
100
+ super.onConfigurationChanged(newConfig)
101
+
102
+ if (!allowFontScaling) {
103
+ return
104
+ }
105
+
106
+ val newFontScale = newConfig.fontScale
107
+ if (newFontScale != lastKnownFontScale) {
108
+ lastKnownFontScale = newFontScale
109
+ recreateStyleConfig()
110
+ scheduleRenderIfNeeded()
111
+ }
112
+ }
113
+
114
+ fun setMd4cFlags(flags: Md4cFlags) {
115
+ if (md4cFlags == flags) return
116
+ md4cFlags = flags
117
+ scheduleRenderIfNeeded()
118
+ }
119
+
120
+ fun setAllowFontScaling(allow: Boolean) {
121
+ if (allowFontScaling == allow) return
122
+ allowFontScaling = allow
123
+ updateMeasurementStoreFontScaling()
124
+ recreateStyleConfig()
125
+ scheduleRenderIfNeeded()
126
+ }
127
+
128
+ fun setMaxFontSizeMultiplier(multiplier: Float) {
129
+ if (maxFontSizeMultiplier == multiplier) return
130
+ maxFontSizeMultiplier = multiplier
131
+ updateMeasurementStoreFontScaling()
132
+ recreateStyleConfig()
133
+ scheduleRenderIfNeeded()
134
+ }
135
+
136
+ fun setAllowTrailingMargin(allow: Boolean) {
137
+ if (allowTrailingMargin == allow) return
138
+ allowTrailingMargin = allow
139
+ scheduleRenderIfNeeded()
140
+ }
141
+
142
+ private fun updateMeasurementStoreFontScaling() {
143
+ MeasurementStore.updateFontScalingSettings(id, allowFontScaling, maxFontSizeMultiplier)
144
+ }
145
+
146
+ private fun scheduleRenderIfNeeded() {
147
+ if (currentMarkdown.isNotEmpty()) {
148
+ scheduleRender()
149
+ }
150
+ }
151
+
152
+ private fun recreateStyleConfig() {
153
+ markdownStyleMap?.let { styleMap ->
154
+ markdownStyle = StyleConfig(styleMap, context, allowFontScaling, maxFontSizeMultiplier)
155
+ updateJustificationMode(markdownStyle)
156
+ }
157
+ }
158
+
159
+ private fun updateJustificationMode(style: StyleConfig?) {
160
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
161
+ justificationMode =
162
+ if (style?.needsJustify == true) {
163
+ Layout.JUSTIFICATION_MODE_INTER_WORD
164
+ } else {
165
+ Layout.JUSTIFICATION_MODE_NONE
166
+ }
167
+ }
168
+ }
169
+
170
+ private fun scheduleRender() {
171
+ val style = markdownStyle ?: return
172
+ val markdown = currentMarkdown
173
+ if (markdown.isEmpty()) return
174
+
175
+ val renderId = ++currentRenderId
176
+
177
+ executor.execute {
178
+ try {
179
+ // 1. Parse Markdown → AST (C++ md4c parser)
180
+ val parseStart = System.currentTimeMillis()
181
+ val ast =
182
+ parser.parseMarkdown(markdown, md4cFlags) ?: run {
183
+ mainHandler.post { if (renderId == currentRenderId) text = "" }
184
+ return@execute
185
+ }
186
+ val parseTime = System.currentTimeMillis() - parseStart
187
+
188
+ // 2. Render AST → Spannable
189
+ val renderStart = System.currentTimeMillis()
190
+ renderer.configure(style, context)
191
+ val styledText = renderer.renderDocument(ast, onLinkPressCallback, onLinkLongPressCallback)
192
+ val renderTime = System.currentTimeMillis() - renderStart
193
+
194
+ Log.i(TAG, "┌──────────────────────────────────────────────")
195
+ Log.i(TAG, "│ 📝 Input: ${markdown.length} chars of Markdown")
196
+ Log.i(TAG, "│ ⚡ md4c (C++ native): ${parseTime}ms → ${ast.children.size} AST nodes")
197
+ Log.i(TAG, "│ 🎨 Spannable render: ${renderTime}ms → ${styledText.length} styled chars")
198
+ Log.i(TAG, "└──────────────────────────────────────────────")
199
+
200
+ // 3. Apply to view on main thread
201
+ mainHandler.post {
202
+ if (renderId == currentRenderId) {
203
+ applyRenderedText(styledText)
204
+ }
205
+ }
206
+ } catch (e: Exception) {
207
+ Log.e(TAG, "❌ Render failed: ${e.message}", e)
208
+ mainHandler.post { if (renderId == currentRenderId) text = "" }
209
+ }
210
+ }
211
+ }
212
+
213
+ private fun applyRenderedText(styledText: CharSequence) {
214
+ text = styledText
215
+
216
+ // setText on a selectable TextView can reset movementMethod, so re-apply if needed
217
+ if (movementMethod !is LinkLongPressMovementMethod) {
218
+ movementMethod = LinkLongPressMovementMethod.createInstance()
219
+ }
220
+
221
+ // Register ImageSpans from the collector
222
+ renderer.getCollectedImageSpans().forEach { span ->
223
+ span.registerTextView(this)
224
+ }
225
+
226
+ layoutManager.invalidateLayout()
227
+
228
+ // Update accessibility items for TalkBack navigation
229
+ accessibilityHelper.invalidateAccessibilityItems()
230
+ }
231
+
232
+ fun setIsSelectable(selectable: Boolean) {
233
+ if (isTextSelectable == selectable) return
234
+ setTextIsSelectable(selectable)
235
+ movementMethod = LinkLongPressMovementMethod.createInstance()
236
+ if (!selectable && !isClickable) isClickable = true
237
+ }
238
+
239
+ fun emitOnLinkPress(url: String) {
240
+ val reactContext = context as? com.facebook.react.bridge.ReactContext ?: return
241
+ val surfaceId = UIManagerHelper.getSurfaceId(reactContext)
242
+ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id)
243
+
244
+ dispatcher?.dispatchEvent(
245
+ LinkPressEvent(surfaceId, id, url),
246
+ )
247
+ }
248
+
249
+ fun emitOnLinkLongPress(url: String) {
250
+ val reactContext = context as? com.facebook.react.bridge.ReactContext ?: return
251
+ val surfaceId = UIManagerHelper.getSurfaceId(reactContext)
252
+ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id)
253
+
254
+ dispatcher?.dispatchEvent(
255
+ LinkLongPressEvent(surfaceId, id, url),
256
+ )
257
+ }
258
+
259
+ fun setOnLinkPressCallback(callback: (String) -> Unit) {
260
+ onLinkPressCallback = callback
261
+ }
262
+
263
+ fun setOnLinkLongPressCallback(callback: (String) -> Unit) {
264
+ onLinkLongPressCallback = callback
265
+ }
266
+
267
+ companion object {
268
+ private const val TAG = "EnrichedMarkdownMeasure"
269
+ }
270
+ }
@@ -0,0 +1,15 @@
1
+ package com.swmansion.enriched.markdown
2
+
3
+ class EnrichedMarkdownTextLayoutManager(
4
+ private val view: EnrichedMarkdownText,
5
+ ) {
6
+ fun invalidateLayout() {
7
+ val text = view.text
8
+ val paint = view.paint
9
+ MeasurementStore.store(view.id, text, paint)
10
+ }
11
+
12
+ fun releaseMeasurementStore() {
13
+ MeasurementStore.release(view.id)
14
+ }
15
+ }