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,7 +5,7 @@
5
5
  #import "StyleConfig.h"
6
6
  #import <objc/runtime.h>
7
7
 
8
- #define CACHE_KEY_PROCESSED(url, w, h, r) [NSString stringWithFormat:@"%@_w%.1f_h%.1f_r%.1f", url, w, h, r]
8
+ #define CACHE_KEY_PROCESSED(url, w, h, r, m) [NSString stringWithFormat:@"%@_w%.1f_h%.1f_r%.1f_m%@", url, w, h, r, m]
9
9
 
10
10
  static inline NSUInteger ENRMImageByteCost(RCTUIImage *image)
11
11
  {
@@ -22,13 +22,19 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
22
22
  @interface ENRMImageAttachment ()
23
23
 
24
24
  @property (nonatomic, copy) NSString *imageURL;
25
+ @property (nonatomic, copy, nullable) NSDictionary<NSString *, NSString *> *requestHeaders;
26
+ @property (nonatomic, copy) NSString *cacheKey;
25
27
  @property (nonatomic, assign) BOOL isInline;
26
28
  @property (nonatomic, assign) CGFloat cachedHeight;
29
+ @property (nonatomic, assign) CGFloat cachedMaxHeight;
30
+ @property (nonatomic, assign) CGFloat cachedAspectRatio;
31
+ @property (nonatomic, copy) NSString *cachedResizeMode;
27
32
  @property (nonatomic, assign) CGFloat cachedBorderRadius;
28
33
  @property (nonatomic, weak) NSTextContainer *textContainer;
29
34
  @property (nonatomic, weak) ENRMPlatformTextView *textView;
30
35
  @property (nonatomic, strong) RCTUIImage *originalImage;
31
36
  @property (nonatomic, strong) RCTUIImage *loadedImage;
37
+ @property (nonatomic, strong) RCTUIImage *placeholderImage;
32
38
  @property (nonatomic, copy) NSString *lastProcessedKey;
33
39
 
34
40
  @end
@@ -66,7 +72,8 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
66
72
 
67
73
  + (instancetype)attachmentForURL:(NSString *)imageURL config:(StyleConfig *)config isInline:(BOOL)isInline
68
74
  {
69
- NSString *key = [NSString stringWithFormat:@"%@_%d", imageURL, isInline];
75
+ NSString *key =
76
+ [NSString stringWithFormat:@"%@_%d", ENRMImageCacheKey(imageURL, [config imageRequestHeaders]), isInline];
70
77
  ENRMImageAttachment *existing = [[self attachmentRegistry] objectForKey:key];
71
78
  if (existing && existing.loadedImage) {
72
79
  return existing;
@@ -86,9 +93,14 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
86
93
  self = [super init];
87
94
  if (self) {
88
95
  _imageURL = imageURL;
96
+ _requestHeaders = [[config imageRequestHeaders] copy];
97
+ _cacheKey = ENRMImageCacheKey(imageURL, _requestHeaders);
89
98
  _isInline = isInline;
90
99
 
91
100
  _cachedHeight = isInline ? [config inlineImageSize] : [config imageHeight];
101
+ _cachedMaxHeight = [config imageMaxHeight];
102
+ _cachedAspectRatio = [config imageAspectRatio];
103
+ _cachedResizeMode = [config imageResizeMode];
92
104
  _cachedBorderRadius = [config imageBorderRadius];
93
105
 
94
106
  [self setupPlaceholder];
@@ -97,6 +109,33 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
97
109
  return self;
98
110
  }
99
111
 
112
+ - (CGFloat)resolvedBoxHeightForWidth:(CGFloat)width
113
+ {
114
+ if (self.cachedAspectRatio > 0 && width > 0) {
115
+ return width / self.cachedAspectRatio;
116
+ }
117
+
118
+ if (self.cachedMaxHeight > 0) {
119
+ RCTUIImage *source = self.originalImage;
120
+ if (source && width > 0 && source.size.width > 0 && source.size.height > 0) {
121
+ CGFloat fitted = width * source.size.height / source.size.width;
122
+ return MIN(self.cachedMaxHeight, fitted);
123
+ }
124
+ // Intrinsic size not known yet — fall back to the full max height; the box
125
+ // shrinks once the image loads and layout is invalidated.
126
+ return self.cachedMaxHeight;
127
+ }
128
+
129
+ return self.cachedHeight;
130
+ }
131
+
132
+ // True when resizeMode is unset ('') - legacy always implies a fixed height box.
133
+
134
+ - (BOOL)isLegacyBlockSizing
135
+ {
136
+ return !self.isInline && self.cachedResizeMode.length == 0;
137
+ }
138
+
100
139
  - (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer
101
140
  proposedLineFragment:(CGRect)lineFragment
102
141
  glyphPosition:(CGPoint)position
@@ -105,26 +144,27 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
105
144
  CGFloat height = self.cachedHeight;
106
145
  CGFloat width = self.isInline ? height : (lineFragment.size.width > 0 ? lineFragment.size.width : height);
107
146
 
108
- if (self.isInline) {
109
- UIFont *appliedFont = nil;
110
- NSLayoutManager *layoutManager = textContainer.layoutManager;
111
- NSTextStorage *textStorage = layoutManager.textStorage;
147
+ if (!self.isInline) {
148
+ height = [self resolvedBoxHeightForWidth:width];
149
+ return CGRectMake(0, 0, width, height);
150
+ }
112
151
 
113
- if (textStorage && characterIndex < textStorage.length) {
114
- appliedFont = [textStorage attribute:NSFontAttributeName atIndex:characterIndex effectiveRange:NULL];
115
- }
152
+ UIFont *appliedFont = nil;
153
+ NSLayoutManager *layoutManager = textContainer.layoutManager;
154
+ NSTextStorage *textStorage = layoutManager.textStorage;
116
155
 
117
- CGFloat verticalOffset;
118
- if (appliedFont) {
119
- verticalOffset = (appliedFont.capHeight - height) / 2.0;
120
- } else {
121
- verticalOffset = (lineFragment.size.height - height) / 2.0;
122
- }
156
+ if (textStorage && characterIndex < textStorage.length) {
157
+ appliedFont = [textStorage attribute:NSFontAttributeName atIndex:characterIndex effectiveRange:NULL];
158
+ }
123
159
 
124
- return CGRectMake(0, verticalOffset, width, height);
160
+ CGFloat verticalOffset;
161
+ if (appliedFont) {
162
+ verticalOffset = (appliedFont.capHeight - height) / 2.0;
163
+ } else {
164
+ verticalOffset = (lineFragment.size.height - height) / 2.0;
125
165
  }
126
166
 
127
- return CGRectMake(0, 0, width, height);
167
+ return CGRectMake(0, verticalOffset, width, height);
128
168
  }
129
169
 
130
170
  - (RCTUIImage *)imageForBounds:(CGRect)imageBounds
@@ -138,7 +178,7 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
138
178
  [self processAndApplyImage:self.originalImage withTargetWidth:imageBounds.size.width];
139
179
  }
140
180
 
141
- return self.loadedImage ?: self.image;
181
+ return self.loadedImage ?: self.placeholderImage;
142
182
  }
143
183
 
144
184
  - (void)handleLoadedImage:(RCTUIImage *)image
@@ -146,7 +186,15 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
146
186
  if (!image)
147
187
  return;
148
188
 
189
+ // The downloader completes synchronously on cache hits, which can happen on the render queue
190
+ if (!NSThread.isMainThread) {
191
+ dispatch_async(dispatch_get_main_queue(), ^{ [self handleLoadedImage:image]; });
192
+ return;
193
+ }
194
+
149
195
  self.originalImage = image;
196
+ // UIKit reads the plain image property for save/drag/copy — it must hold the original
197
+ self.image = image;
150
198
  CGFloat targetWidth = self.isInline ? self.cachedHeight : self.bounds.size.width;
151
199
 
152
200
  // Defer processing if we don't have valid bounds yet (common for non-inline block images)
@@ -162,7 +210,10 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
162
210
  if (targetWidth <= 0)
163
211
  return;
164
212
 
165
- NSString *processedKey = CACHE_KEY_PROCESSED(self.imageURL, targetWidth, self.cachedHeight, self.cachedBorderRadius);
213
+ CGFloat boxHeight = self.isInline ? self.cachedHeight : [self resolvedBoxHeightForWidth:targetWidth];
214
+
215
+ NSString *processedKey =
216
+ CACHE_KEY_PROCESSED(self.cacheKey, targetWidth, boxHeight, self.cachedBorderRadius, self.cachedResizeMode);
166
217
 
167
218
  if ([processedKey isEqualToString:self.lastProcessedKey])
168
219
  return;
@@ -172,8 +223,6 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
172
223
 
173
224
  if (cachedProcessed) {
174
225
  self.loadedImage = cachedProcessed;
175
- if (self.isInline)
176
- self.image = cachedProcessed;
177
226
  [self refreshDisplay];
178
227
  return;
179
228
  }
@@ -186,7 +235,7 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
186
235
 
187
236
  RCTUIImage *processedImage = [strongSelf createScaledImage:image
188
237
  toWidth:targetWidth
189
- height:strongSelf.cachedHeight
238
+ height:boxHeight
190
239
  borderRadius:strongSelf.cachedBorderRadius];
191
240
 
192
241
  if (processedImage) {
@@ -198,10 +247,7 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
198
247
  dispatch_async(dispatch_get_main_queue(), ^{
199
248
  strongSelf.loadedImage = processedImage;
200
249
  if (strongSelf.isInline) {
201
- strongSelf.image = processedImage;
202
250
  strongSelf.bounds = CGRectMake(0, 0, strongSelf.cachedHeight, strongSelf.cachedHeight);
203
- } else {
204
- strongSelf.image = image; // Keep original for layout references
205
251
  }
206
252
  [strongSelf refreshDisplay];
207
253
  });
@@ -218,32 +264,64 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
218
264
  if (sourceWidth <= 0 || sourceHeight <= 0)
219
265
  return nil;
220
266
 
221
- CGFloat drawingWidth, drawingHeight;
267
+ CGSize source = CGSizeMake(sourceWidth, sourceHeight);
268
+ CGSize box = CGSizeMake(targetWidth, targetHeight);
269
+ BOOL legacy = [self isLegacyBlockSizing];
222
270
 
223
- if (!self.isInline) {
224
- CGFloat aspectRatioScale = targetWidth / sourceWidth;
225
- drawingWidth = targetWidth;
226
- drawingHeight = sourceHeight * aspectRatioScale;
271
+ CGRect drawingRect;
272
+ if (self.isInline || legacy) {
273
+ CGFloat drawingWidth, drawingHeight;
274
+ if (!self.isInline) {
275
+ CGFloat aspectRatioScale = targetWidth / sourceWidth;
276
+ drawingWidth = targetWidth;
277
+ drawingHeight = sourceHeight * aspectRatioScale;
278
+ } else {
279
+ drawingWidth = targetWidth;
280
+ drawingHeight = targetHeight;
281
+ }
282
+ drawingRect = CGRectMake((targetWidth - drawingWidth) / 2.0, (targetHeight - drawingHeight) / 2.0, drawingWidth,
283
+ drawingHeight);
227
284
  } else {
228
- drawingWidth = targetWidth;
229
- drawingHeight = targetHeight;
285
+ drawingRect = [self drawingRectForResizeMode:self.cachedResizeMode source:source box:box];
230
286
  }
231
287
 
232
- CGRect drawingRect =
233
- CGRectMake((targetWidth - drawingWidth) / 2.0, (targetHeight - drawingHeight) / 2.0, drawingWidth, drawingHeight);
234
-
235
- RCTUIGraphicsImageRenderer *renderer = ImageRendererForSize(CGSizeMake(targetWidth, targetHeight));
288
+ RCTUIGraphicsImageRenderer *renderer = ImageRendererForSize(box);
236
289
 
237
290
  return [renderer imageWithActions:^(RCTUIGraphicsImageRendererContext *context) {
238
291
  if (radius > 0) {
239
- CGRect clippingRect = CGRectIntersection(CGRectMake(0, 0, targetWidth, targetHeight), drawingRect);
240
- UIBezierPath *path = UIBezierPathWithRoundedRect(clippingRect, radius);
292
+ CGRect clipRect = CGRectIntersection(CGRectMake(0, 0, targetWidth, targetHeight), drawingRect);
293
+ UIBezierPath *path = UIBezierPathWithRoundedRect(clipRect, radius);
241
294
  [path addClip];
242
295
  }
243
296
  [image drawInRect:drawingRect];
244
297
  }];
245
298
  }
246
299
 
300
+ - (CGRect)drawingRectForResizeMode:(NSString *)mode source:(CGSize)source box:(CGSize)box
301
+ {
302
+ if ([mode isEqualToString:@"stretch"]) {
303
+ return CGRectMake(0, 0, box.width, box.height);
304
+ }
305
+
306
+ CGFloat widthScale = box.width / source.width;
307
+ CGFloat heightScale = box.height / source.height;
308
+
309
+ CGFloat scale;
310
+ if ([mode isEqualToString:@"contain"]) {
311
+ scale = MIN(widthScale, heightScale);
312
+ } else if ([mode isEqualToString:@"center"]) {
313
+ scale = MIN(1.0, MIN(widthScale, heightScale));
314
+ } else if ([mode isEqualToString:@"none"]) {
315
+ scale = 1.0;
316
+ } else { // cover (default)
317
+ scale = MAX(widthScale, heightScale);
318
+ }
319
+
320
+ CGFloat drawingWidth = source.width * scale;
321
+ CGFloat drawingHeight = source.height * scale;
322
+ return CGRectMake((box.width - drawingWidth) / 2.0, (box.height - drawingHeight) / 2.0, drawingWidth, drawingHeight);
323
+ }
324
+
247
325
  - (void)startDownloadingImage
248
326
  {
249
327
  if (self.imageURL.length == 0)
@@ -251,6 +329,7 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
251
329
 
252
330
  __weak typeof(self) weakSelf = self;
253
331
  [[ENRMImageDownloader shared] downloadURL:self.imageURL
332
+ headers:self.requestHeaders
254
333
  completion:^(RCTUIImage *image) { [weakSelf handleLoadedImage:image]; }];
255
334
  }
256
335
 
@@ -265,10 +344,34 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
265
344
  [textView.layoutManager invalidateDisplayForCharacterRange:range];
266
345
  if (!self.isInline) {
267
346
  [textView.layoutManager invalidateLayoutForCharacterRange:range actualCharacterRange:NULL];
347
+ [self notifyImageLayoutObserver:textView];
268
348
  }
269
349
  }
270
350
  }
271
351
 
352
+ // With maxHeight/aspectRatio sizing the box height can settle after the image
353
+ // loads, while the component was measured (and its size cached) with the
354
+ // pre-load fallback. Notify the hosting component so it can re-measure.
355
+ // Dispatched async: refreshDisplay can run mid-layout (imageForBounds) and
356
+ // re-measuring would re-enter the layout manager.
357
+ - (void)notifyImageLayoutObserver:(UITextView *)textView
358
+ {
359
+ // Only maxHeight/aspectRatio boxes can change height after load; a fixed
360
+ // height box (legacy or explicit resizeMode) never needs a re-measure.
361
+ if (self.cachedMaxHeight <= 0 && self.cachedAspectRatio <= 0)
362
+ return;
363
+
364
+ RCTUIView *candidate = textView;
365
+ while (candidate && ![candidate conformsToProtocol:@protocol(ENRMImageLayoutObserver)]) {
366
+ candidate = candidate.superview;
367
+ }
368
+ if (!candidate)
369
+ return;
370
+
371
+ id<ENRMImageLayoutObserver> observer = (id<ENRMImageLayoutObserver>)candidate;
372
+ dispatch_async(dispatch_get_main_queue(), ^{ [observer imageAttachmentDidResolveLayout]; });
373
+ }
374
+
272
375
  - (ENRMPlatformTextView *)fetchAssociatedTextView
273
376
  {
274
377
  if (self.textView)
@@ -284,7 +387,7 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
284
387
  CGFloat size = self.cachedHeight;
285
388
  self.bounds = CGRectMake(0, 0, size, size);
286
389
  RCTUIGraphicsImageRenderer *renderer = [[RCTUIGraphicsImageRenderer alloc] initWithSize:CGSizeMake(1, 1)];
287
- self.image = [renderer imageWithActions:^(RCTUIGraphicsImageRendererContext *ctx){}];
390
+ self.placeholderImage = [renderer imageWithActions:^(RCTUIGraphicsImageRendererContext *ctx){}];
288
391
  }
289
392
 
290
393
  - (NSRange)findAttachmentRangeInText:(NSAttributedString *)attributedString
@@ -302,4 +405,4 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
302
405
  return foundRange;
303
406
  }
304
407
 
305
- @end
408
+ @end
@@ -29,7 +29,8 @@
29
29
  displayMode:NO
30
30
  fontSize:self.fontSize
31
31
  color:color
32
- bold:self.bold];
32
+ bold:self.bold
33
+ glyphOverflow:self.glyphOverflow];
33
34
  if (!result)
34
35
  return;
35
36
 
@@ -9,9 +9,14 @@ NS_ASSUME_NONNULL_BEGIN
9
9
  @property (nonatomic, assign) CGFloat fontSize;
10
10
  @property (nonatomic, strong, nullable) RCTUIColor *mathTextColor;
11
11
 
12
+ @property (nonatomic, readonly) CGFloat boxHeight;
13
+
12
14
  /// Typeset the glyphs at bold weight (synthetic — see ENRMRaTeXBridge).
13
15
  @property (nonatomic, assign) BOOL bold;
14
16
 
17
+ /// Ink headroom above and below the formula box (`inlineMath.glyphOverflow`, points).
18
+ @property (nonatomic, assign) CGFloat glyphOverflow;
19
+
15
20
  /// YES if block math (`$$...$$`), NO for inline (`$...$`).
16
21
  @property (nonatomic, assign) BOOL displayMode;
17
22
 
@@ -1,3 +1,4 @@
1
+ #import "ENRMMathFallback.h"
1
2
  #import "ENRMMathInlineAttachmentShared.h"
2
3
 
3
4
  #if ENRICHED_MARKDOWN_MATH
@@ -10,21 +11,50 @@
10
11
 
11
12
  @implementation ENRMMathInlineAttachment
12
13
 
14
+ - (CGFloat)boxHeight
15
+ {
16
+ #if !TARGET_OS_OSX
17
+ [self prepareIfNeeded];
18
+ #endif
19
+ return _cachedSize.height + _containerPaddingVertical * 2;
20
+ }
21
+
22
+ /// Clears the cached glyph render so the next layout regenerates it
23
+ /// (e.g. after style or latex changes).
24
+ - (void)invalidateRender
25
+ {
26
+ _renderResult = nil;
27
+ _fallbackSource = nil;
28
+ _cachedSize = CGSizeZero;
29
+ _mathAscent = 0;
30
+ _mathDescent = 0;
31
+ }
32
+
13
33
  #if !TARGET_OS_OSX
14
34
 
15
35
  - (void)prepareIfNeeded
16
36
  {
17
- if (_renderResult)
37
+ if (_renderResult || _fallbackSource)
18
38
  return;
19
39
 
20
40
  RCTUIColor *color = self.mathTextColor ?: [RCTUIColor blackColor];
21
41
  ENRMRaTeXRenderResult *result = [ENRMRaTeXBridge parse:self.latex
22
- displayMode:self.displayMode
42
+ displayMode:NO
23
43
  fontSize:self.fontSize
24
44
  color:color
25
- bold:self.bold];
26
- if (!result)
45
+ bold:self.bold
46
+ glyphOverflow:self.glyphOverflow];
47
+ if (!result) {
48
+ _fallbackSource = ENRMMathFallbackString(self.latex, @"$", self.fontSize, color);
49
+ UIFont *font = [_fallbackSource attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL];
50
+ CGRect bounds = [_fallbackSource boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)
51
+ options:NSStringDrawingUsesLineFragmentOrigin
52
+ context:nil];
53
+ _mathAscent = font.ascender;
54
+ _mathDescent = -font.descender;
55
+ _cachedSize = CGSizeMake(ceil(bounds.size.width), ceil(_mathAscent + _mathDescent));
27
56
  return;
57
+ }
28
58
 
29
59
  _renderResult = result;
30
60
  _mathAscent = result.ascent;
@@ -32,33 +62,16 @@
32
62
  _cachedSize = CGSizeMake(ceil(result.width), ceil(result.totalHeight));
33
63
  }
34
64
 
35
- - (void)invalidateRender
36
- {
37
- _renderResult = nil;
38
- _cachedSize = CGSizeZero;
39
- _mathAscent = 0;
40
- _mathDescent = 0;
41
- }
42
-
43
65
  - (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer
44
66
  proposedLineFragment:(CGRect)lineFragment
45
67
  glyphPosition:(CGPoint)position
46
68
  characterIndex:(NSUInteger)characterIndex
47
69
  {
48
70
  [self prepareIfNeeded];
49
-
50
- CGFloat intrinsicW = _cachedSize.width + _containerPaddingHorizontal * 2;
51
- CGFloat totalH = _cachedSize.height + _containerPaddingVertical * 2;
52
-
53
- if (_displayMode) {
54
- totalH += _blockMarginTop + _blockMarginBottom;
55
- // Block chip claims the full line fragment so text can't share the row.
56
- // Fall back to intrinsic width when the proposed fragment is degenerate
57
- // (e.g. during initial layout before the text container has a size).
58
- CGFloat fullW = MAX(lineFragment.size.width, intrinsicW);
59
- return CGRectMake(0, -(_mathDescent + _containerPaddingVertical + _blockMarginBottom), fullW, totalH);
60
- }
61
- return CGRectMake(0, -(_mathDescent + _containerPaddingVertical), intrinsicW, totalH);
71
+ // inlineMath.paddingVertical grows the glyph box symmetrically so a tall formula
72
+ // (\frac, \sum) stops sitting flush against the neighbouring line.
73
+ return CGRectMake(0, -(_mathDescent + _containerPaddingVertical), _cachedSize.width,
74
+ _cachedSize.height + _containerPaddingVertical * 2);
62
75
  }
63
76
 
64
77
  - (UIImage *)imageForBounds:(CGRect)imageBounds
@@ -66,72 +79,27 @@
66
79
  characterIndex:(NSUInteger)characterIndex
67
80
  {
68
81
  [self prepareIfNeeded];
69
- if (!_renderResult)
82
+ if (!_renderResult && !_fallbackSource)
70
83
  return nil;
71
84
 
72
- // Block chips claim the full line fragment (set in attachmentBounds…), so
73
- // the canvas is `imageBounds.width` wide and the formula floats inside it
74
- // according to `blockAlignment`. Inline chips fall back to intrinsic width.
75
- CGFloat intrinsicW = _cachedSize.width + _containerPaddingHorizontal * 2;
76
- CGFloat totalW = (_displayMode && imageBounds.size.width > intrinsicW) ? imageBounds.size.width : intrinsicW;
77
- CGFloat totalH = _cachedSize.height + _containerPaddingVertical * 2;
78
- CGSize totalSize = CGSizeMake(totalW, totalH);
79
-
80
- RCTUIColor *bg = _isSelected ? (_selectedBackgroundColor ?: _containerBackgroundColor) : _containerBackgroundColor;
81
- RCTUIColor *border = _isSelected ? (_selectedBorderColor ?: _containerBorderColor) : _containerBorderColor;
82
- CGFloat borderWidth = _containerBorderWidth;
83
- CGFloat borderRadius = _containerBorderRadius;
84
- CGFloat padH = _containerPaddingHorizontal;
85
- CGFloat padV = _containerPaddingVertical;
86
- ENRMRaTeXRenderResult *render = _renderResult;
87
- CGFloat formulaW = _cachedSize.width;
88
- NSTextAlignment alignment = _blockAlignment;
89
- BOOL displayMode = _displayMode;
90
-
91
85
  UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat preferredFormat];
92
86
  format.opaque = NO;
93
87
 
94
- UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:totalSize format:format];
88
+ CGFloat padV = _containerPaddingVertical;
89
+ CGSize boxSize = CGSizeMake(_cachedSize.width, _cachedSize.height + padV * 2);
90
+ UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:boxSize format:format];
95
91
 
96
92
  return [renderer imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) {
97
93
  CGContextRef ctx = rendererContext.CGContext;
98
-
99
- if (bg) {
100
- CGFloat inset = borderWidth / 2.0;
101
- CGRect rect = CGRectMake(inset, inset, totalW - borderWidth, totalH - borderWidth);
102
- UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:borderRadius];
103
- [bg setFill];
104
- [path fill];
105
- }
106
-
107
- if (border && borderWidth > 0) {
108
- CGFloat inset = borderWidth / 2.0;
109
- CGRect rect = CGRectMake(inset, inset, totalW - borderWidth, totalH - borderWidth);
110
- UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:borderRadius];
111
- [border setStroke];
112
- path.lineWidth = borderWidth;
113
- [path stroke];
114
- }
115
-
116
- CGFloat glyphOffset = padH;
117
- if (displayMode && totalW > intrinsicW) {
118
- CGFloat slack = totalW - formulaW - padH * 2;
119
- switch (alignment) {
120
- case NSTextAlignmentCenter:
121
- glyphOffset = padH + slack / 2.0;
122
- break;
123
- case NSTextAlignmentRight:
124
- glyphOffset = padH + slack;
125
- break;
126
- default:
127
- glyphOffset = padH;
128
- break;
129
- }
130
- }
131
-
132
94
  CGContextSaveGState(ctx);
133
- CGContextTranslateCTM(ctx, glyphOffset, padV);
134
- [render drawIn:ctx];
95
+ CGContextTranslateCTM(ctx, 0, padV);
96
+ if (_renderResult) {
97
+ [_renderResult drawIn:ctx];
98
+ } else {
99
+ [_fallbackSource drawWithRect:CGRectMake(0, 0, _cachedSize.width, _cachedSize.height)
100
+ options:NSStringDrawingUsesLineFragmentOrigin
101
+ context:nil];
102
+ }
135
103
  CGContextRestoreGState(ctx);
136
104
  }];
137
105
  }
@@ -11,6 +11,8 @@
11
11
  CGFloat _mathAscent;
12
12
  CGFloat _mathDescent;
13
13
  ENRMRaTeXRenderResult *_renderResult;
14
+ // Visible-source fallback when RaTeX cannot parse the span; see ENRMMathFallback.h.
15
+ NSAttributedString *_fallbackSource;
14
16
  }
15
17
  @end
16
18