react-native-enriched-markdown-scaffold 0.7.4-scaffold.8 → 1.0.2-scaffold.1

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 (469) hide show
  1. package/README.md +54 -8
  2. package/ReactNativeEnrichedMarkdown.podspec +82 -73
  3. package/android/build.gradle +191 -1
  4. package/android/consumer-rules.pro +1 -1
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +9 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +3 -0
  7. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +27 -0
  8. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +9 -0
  9. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +9 -0
  10. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +3 -0
  11. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
  12. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
  13. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +40 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +839 -23
  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 +175 -11
  18. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +17 -0
  19. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +50 -0
  20. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +48 -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 +42 -0
  23. package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +82 -4
  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/input/EnrichedMarkdownTextInputManager.kt +62 -4
  26. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +911 -460
  27. package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
  28. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
  29. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
  30. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
  31. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
  32. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
  33. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +101 -7
  34. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
  35. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
  36. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
  37. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
  38. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
  39. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
  40. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
  41. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
  42. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockSyntaxSentinel.kt +69 -0
  43. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
  44. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
  45. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +180 -27
  46. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
  47. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
  48. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
  49. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +7 -2
  50. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
  51. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
  52. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
  53. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
  54. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
  55. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
  56. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
  58. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
  65. package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
  66. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
  68. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
  69. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
  70. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
  71. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
  72. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
  73. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
  74. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
  75. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
  76. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
  77. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +30 -27
  78. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
  79. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
  80. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +27 -3
  81. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
  82. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
  83. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
  84. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
  85. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
  86. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
  87. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
  88. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
  89. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
  90. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
  91. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
  93. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
  94. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
  95. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
  96. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
  97. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
  98. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
  99. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
  100. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
  101. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +33 -7
  102. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
  103. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
  104. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
  105. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
  106. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
  107. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
  108. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +20 -0
  109. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
  110. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
  111. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
  112. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
  113. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
  114. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
  115. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
  116. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
  117. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +19 -2
  118. package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +388 -0
  119. package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
  120. package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
  121. package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +32 -5
  122. package/android/src/main/jni/CMakeLists.txt +53 -0
  123. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
  124. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
  125. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
  126. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
  127. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
  128. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
  129. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
  130. package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
  131. package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +7 -2
  132. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
  133. package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +2 -0
  134. package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
  135. package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
  136. package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
  137. package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
  138. package/cpp/highlight/HighlightGrammars.hpp +28 -0
  139. package/cpp/highlight/code_highlight_podspec.rb +211 -0
  140. package/cpp/highlight/gen-registry.mjs +155 -0
  141. package/cpp/highlight/grammar-versions.json +159 -0
  142. package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
  143. package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
  144. package/cpp/parser/MD4CParser.cpp +173 -61
  145. package/cpp/parser/MD4CParser.hpp +1 -0
  146. package/cpp/parser/MarkdownASTNode.hpp +2 -1
  147. package/cpp/wasm/ASTSerializer.cpp +2 -0
  148. package/cpp/wasm/build.sh +1 -0
  149. package/cpp/wasm/md4c_wasm.cpp +3 -1
  150. package/docs/ACCESSIBILITY.md +14 -2
  151. package/docs/API_REFERENCE.md +231 -8
  152. package/docs/BREAKING_CHANGES.md +129 -0
  153. package/docs/CODE_HIGHLIGHT.md +133 -0
  154. package/docs/COPY_OPTIONS.md +21 -3
  155. package/docs/ELEMENTS_STRUCTURE.md +52 -4
  156. package/docs/IMAGE_CACHING.md +30 -0
  157. package/docs/INPUT.md +146 -5
  158. package/docs/LATEX_MATH.md +87 -45
  159. package/docs/MACOS.md +1 -1
  160. package/docs/MARKDOWN_STREAMING.md +27 -1
  161. package/docs/NATIVE_ASSETS.md +127 -0
  162. package/docs/RTL.md +1 -1
  163. package/docs/STYLES.md +46 -6
  164. package/docs/TESTING.md +112 -0
  165. package/docs/TEXT.md +16 -6
  166. package/docs/WEB.md +3 -1
  167. package/ios/EnrichedMarkdown.h +7 -0
  168. package/ios/EnrichedMarkdown.mm +262 -67
  169. package/ios/EnrichedMarkdownText.h +7 -0
  170. package/ios/EnrichedMarkdownText.mm +97 -68
  171. package/ios/attachments/ENRMImageAttachment.h +9 -0
  172. package/ios/attachments/ENRMImageAttachment.m +143 -40
  173. package/ios/attachments/ENRMMathInlineAttachment.h +2 -0
  174. package/ios/attachments/ENRMMathInlineAttachment.m +48 -81
  175. package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
  176. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
  177. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
  178. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +40 -0
  179. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +839 -23
  180. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +131 -0
  181. package/ios/input/ENRMAutoLinkDetector.h +2 -1
  182. package/ios/input/ENRMAutoLinkDetector.mm +79 -41
  183. package/ios/input/ENRMBlockEditCoordinator.h +71 -0
  184. package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
  185. package/ios/input/ENRMBlockRange.h +28 -0
  186. package/ios/input/ENRMBlockRange.mm +30 -0
  187. package/ios/input/ENRMBlockStore.h +56 -0
  188. package/ios/input/ENRMBlockStore.mm +275 -0
  189. package/ios/input/ENRMBlockSyntaxSentinel.h +25 -0
  190. package/ios/input/ENRMBlockSyntaxSentinel.mm +80 -0
  191. package/ios/input/ENRMClipboardCoordinator.h +45 -0
  192. package/ios/input/ENRMClipboardCoordinator.mm +120 -0
  193. package/ios/input/ENRMDetectorPipeline.h +2 -1
  194. package/ios/input/ENRMEditPipeline.h +76 -0
  195. package/ios/input/ENRMEditPipeline.mm +228 -0
  196. package/ios/input/ENRMEditSession.h +36 -0
  197. package/ios/input/ENRMEditSession.mm +63 -0
  198. package/ios/input/ENRMFormattingStore.h +17 -0
  199. package/ios/input/ENRMFormattingStore.mm +95 -105
  200. package/ios/input/ENRMInputBlockType.h +91 -0
  201. package/ios/input/ENRMInputBlockType.mm +5 -0
  202. package/ios/input/ENRMInputDecorationDrawer.h +18 -0
  203. package/ios/input/ENRMInputEventEmitter.h +56 -0
  204. package/ios/input/ENRMInputEventEmitter.mm +308 -0
  205. package/ios/input/ENRMInputFormatter.h +29 -69
  206. package/ios/input/ENRMInputFormatter.mm +216 -124
  207. package/ios/input/ENRMInputFormatterStyle.h +99 -0
  208. package/ios/input/ENRMInputFormatterStyle.mm +188 -0
  209. package/ios/input/ENRMInputLayoutManager.h +9 -0
  210. package/ios/input/ENRMInputLayoutManager.mm +30 -0
  211. package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
  212. package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
  213. package/ios/input/ENRMInputParser.h +10 -6
  214. package/ios/input/ENRMInputParser.mm +527 -171
  215. package/ios/input/ENRMInputRemend.mm +2 -2
  216. package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
  217. package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
  218. package/ios/input/ENRMInputTextView.mm +103 -8
  219. package/ios/input/ENRMInputTypingAttributesController.h +42 -0
  220. package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
  221. package/ios/input/ENRMLinkCoordinator.h +41 -0
  222. package/ios/input/ENRMLinkCoordinator.mm +89 -0
  223. package/ios/input/ENRMMarkdownSerializer.h +29 -5
  224. package/ios/input/ENRMMarkdownSerializer.mm +170 -48
  225. package/ios/input/ENRMMathAtom.h +26 -0
  226. package/ios/input/ENRMMathAtom.mm +12 -0
  227. package/ios/input/ENRMMentionCoordinator.h +45 -0
  228. package/ios/input/ENRMMentionCoordinator.mm +167 -0
  229. package/ios/input/ENRMRangeEditAdjustment.h +38 -0
  230. package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
  231. package/ios/input/ENRMRangeStoreUtils.h +39 -0
  232. package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
  233. package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
  234. package/ios/input/EnrichedMarkdownTextInput.h +7 -1
  235. package/ios/input/EnrichedMarkdownTextInput.mm +1104 -1024
  236. package/ios/input/InputStylePropsUtils.h +109 -68
  237. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
  238. package/ios/input/styles/ENRMBlockHandler.h +46 -0
  239. package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
  240. package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
  241. package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
  242. package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
  243. package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
  244. package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
  245. package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
  246. package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
  247. package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
  248. package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
  249. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
  250. package/ios/internals/MeasurementCache.h +33 -7
  251. package/ios/internals/ShadowMeasurementUtils.h +63 -58
  252. package/ios/math/ENRMMathChipController.h +74 -0
  253. package/ios/math/ENRMMathChipController.mm +476 -0
  254. package/ios/math/ENRMRaTeXBridge.swift +4 -1
  255. package/ios/parser/ENRMMarkdownParser.h +1 -8
  256. package/ios/parser/ENRMMarkdownParser.mm +2 -11
  257. package/ios/parser/MarkdownASTNode.h +2 -1
  258. package/ios/parser/MarkdownParserBridge.mm +4 -0
  259. package/ios/renderer/AttributedRenderer.m +20 -2
  260. package/ios/renderer/BaseRenderer.h +17 -2
  261. package/ios/renderer/BaseRenderer.m +30 -0
  262. package/ios/renderer/BlockquoteRenderer.h +1 -1
  263. package/ios/renderer/BlockquoteRenderer.m +144 -35
  264. package/ios/renderer/CodeBlockRenderer.h +1 -1
  265. package/ios/renderer/CodeBlockRenderer.m +27 -23
  266. package/ios/renderer/CodeRenderer.h +1 -1
  267. package/ios/renderer/CodeRenderer.m +3 -1
  268. package/ios/renderer/ENRMImageRenderer.h +1 -1
  269. package/ios/renderer/ENRMImageRenderer.m +5 -1
  270. package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
  271. package/ios/renderer/ENRMMathInlineRenderer.m +5 -1
  272. package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
  273. package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
  274. package/ios/renderer/EmphasisRenderer.h +1 -1
  275. package/ios/renderer/EmphasisRenderer.m +3 -1
  276. package/ios/renderer/HeadingRenderer.h +1 -1
  277. package/ios/renderer/HeadingRenderer.m +13 -6
  278. package/ios/renderer/HighlightRenderer.h +1 -1
  279. package/ios/renderer/HighlightRenderer.m +3 -1
  280. package/ios/renderer/LinkRenderer.h +1 -1
  281. package/ios/renderer/LinkRenderer.m +3 -1
  282. package/ios/renderer/ListItemRenderer.h +13 -1
  283. package/ios/renderer/ListItemRenderer.m +102 -44
  284. package/ios/renderer/ListRenderer.h +2 -2
  285. package/ios/renderer/ListRenderer.m +63 -25
  286. package/ios/renderer/ParagraphRenderer.h +1 -1
  287. package/ios/renderer/ParagraphRenderer.m +16 -8
  288. package/ios/renderer/RenderContext.h +10 -0
  289. package/ios/renderer/RenderContext.m +44 -0
  290. package/ios/renderer/RendererFactory.m +14 -0
  291. package/ios/renderer/StrikethroughRenderer.h +1 -1
  292. package/ios/renderer/StrikethroughRenderer.m +3 -1
  293. package/ios/renderer/StrongRenderer.h +1 -1
  294. package/ios/renderer/StrongRenderer.m +3 -1
  295. package/ios/renderer/SubscriptRenderer.h +1 -1
  296. package/ios/renderer/SubscriptRenderer.m +3 -1
  297. package/ios/renderer/SuperscriptRenderer.h +1 -1
  298. package/ios/renderer/SuperscriptRenderer.m +3 -1
  299. package/ios/renderer/TextRenderer.h +2 -2
  300. package/ios/renderer/TextRenderer.m +3 -1
  301. package/ios/renderer/ThematicBreakRenderer.h +1 -1
  302. package/ios/renderer/ThematicBreakRenderer.m +3 -1
  303. package/ios/renderer/UnderlineRenderer.h +1 -1
  304. package/ios/renderer/UnderlineRenderer.m +3 -1
  305. package/ios/styles/StyleConfig.h +22 -0
  306. package/ios/styles/StyleConfig.mm +132 -0
  307. package/ios/utils/BlockquoteBorder.h +6 -0
  308. package/ios/utils/BlockquoteBorder.m +249 -52
  309. package/ios/utils/CodeBlockBackground.m +16 -2
  310. package/ios/utils/ENRMAtomicSize.h +65 -0
  311. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  312. package/ios/utils/ENRMCodeBlockContent.mm +79 -0
  313. package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
  314. package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
  315. package/ios/utils/ENRMFeatureFlags.h +7 -0
  316. package/ios/utils/ENRMImageDownloader.h +11 -1
  317. package/ios/utils/ENRMImageDownloader.m +60 -16
  318. package/ios/utils/ENRMLocalImageLoader.h +31 -0
  319. package/ios/utils/ENRMLocalImageLoader.m +68 -0
  320. package/ios/utils/ENRMMathFallback.h +26 -0
  321. package/ios/utils/ENRMMathFallback.m +18 -0
  322. package/ios/utils/ENRMTextViewSetup.h +35 -17
  323. package/ios/utils/EditMenuUtils.m +22 -1
  324. package/ios/utils/ImageRequestHeaderUtils.h +35 -0
  325. package/ios/utils/LastElementUtils.h +1 -0
  326. package/ios/utils/ListMarkerDrawer.m +29 -42
  327. package/ios/utils/MarkdownASTSerializer.m +4 -0
  328. package/ios/utils/ParagraphStyleUtils.h +5 -0
  329. package/ios/utils/ParagraphStyleUtils.m +77 -17
  330. package/ios/utils/RenderedMarkdownSegment.h +13 -1
  331. package/ios/utils/RenderedMarkdownSegment.m +20 -0
  332. package/ios/utils/SegmentRenderer.m +17 -4
  333. package/ios/utils/StreamingMarkdownFilter.h +11 -1
  334. package/ios/utils/StreamingMarkdownFilter.m +98 -2
  335. package/ios/utils/StylePropsUtils.h +63 -0
  336. package/ios/utils/TaskListTapUtils.m +24 -0
  337. package/ios/views/ENRMCodeBlockContainerView.h +46 -0
  338. package/ios/views/ENRMCodeBlockContainerView.m +566 -0
  339. package/ios/views/ENRMMathContainerView.h +12 -0
  340. package/ios/views/ENRMMathContainerView.m +71 -1
  341. package/ios/views/TableContainerView.h +18 -0
  342. package/ios/views/TableContainerView.m +259 -159
  343. package/jest.d.ts +1 -0
  344. package/jest.js +5 -0
  345. package/lib/module/EnrichedMarkdownNativeComponent.ts +65 -0
  346. package/lib/module/EnrichedMarkdownTextInput.js +86 -5
  347. package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
  348. package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +89 -5
  349. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +66 -0
  350. package/lib/module/headingDefaults.js +34 -0
  351. package/lib/module/headingDefaults.js.map +1 -0
  352. package/lib/module/index.js.map +1 -1
  353. package/lib/module/jest/index.js +191 -0
  354. package/lib/module/jest/index.js.map +1 -0
  355. package/lib/module/native/EnrichedMarkdownText.js +30 -4
  356. package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
  357. package/lib/module/normalizeMarkdownStyle.js +81 -19
  358. package/lib/module/normalizeMarkdownStyle.js.map +1 -1
  359. package/lib/module/normalizeMarkdownStyle.web.js +56 -18
  360. package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
  361. package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
  362. package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
  363. package/lib/module/normalizeMenuItem.js +1 -1
  364. package/lib/module/utils/textInputState.js +26 -0
  365. package/lib/module/utils/textInputState.js.map +1 -0
  366. package/lib/module/web/EnrichedMarkdownText.js +9 -5
  367. package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
  368. package/lib/module/web/parseMarkdown.js +4 -3
  369. package/lib/module/web/parseMarkdown.js.map +1 -1
  370. package/lib/module/web/renderers/InlineRenderers.js +6 -0
  371. package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
  372. package/lib/module/web/renderers/ListRenderers.js +7 -2
  373. package/lib/module/web/renderers/ListRenderers.js.map +1 -1
  374. package/lib/module/web/renderers/index.js +7 -4
  375. package/lib/module/web/renderers/index.js.map +1 -1
  376. package/lib/module/web/styles.js +83 -6
  377. package/lib/module/web/styles.js.map +1 -1
  378. package/lib/module/web/utils.js +1 -0
  379. package/lib/module/web/utils.js.map +1 -1
  380. package/lib/module/web/wasm/md4c.js +0 -0
  381. package/lib/module/web/wasm/md4c.js.map +1 -1
  382. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +62 -0
  383. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
  384. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +95 -9
  385. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
  386. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +80 -5
  387. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
  388. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +62 -0
  389. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
  390. package/lib/typescript/src/headingDefaults.d.ts +9 -0
  391. package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
  392. package/lib/typescript/src/index.d.ts +2 -2
  393. package/lib/typescript/src/index.d.ts.map +1 -1
  394. package/lib/typescript/src/index.web.d.ts +1 -1
  395. package/lib/typescript/src/index.web.d.ts.map +1 -1
  396. package/lib/typescript/src/jest/index.d.ts +6 -0
  397. package/lib/typescript/src/jest/index.d.ts.map +1 -0
  398. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +3 -3
  399. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
  400. package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
  401. package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
  402. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
  403. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
  404. package/lib/typescript/src/types/MarkdownStyle.d.ts +72 -0
  405. package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
  406. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +27 -0
  407. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
  408. package/lib/typescript/src/types/MarkdownTextProps.d.ts +65 -1
  409. package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
  410. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +19 -0
  411. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
  412. package/lib/typescript/src/types/events.d.ts +19 -0
  413. package/lib/typescript/src/types/events.d.ts.map +1 -1
  414. package/lib/typescript/src/utils/textInputState.d.ts +24 -0
  415. package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
  416. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
  417. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
  418. package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
  419. package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
  420. package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
  421. package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
  422. package/lib/typescript/src/web/renderers/index.d.ts +2 -1
  423. package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
  424. package/lib/typescript/src/web/styles.d.ts +2 -1
  425. package/lib/typescript/src/web/styles.d.ts.map +1 -1
  426. package/lib/typescript/src/web/types.d.ts +6 -2
  427. package/lib/typescript/src/web/types.d.ts.map +1 -1
  428. package/lib/typescript/src/web/utils.d.ts.map +1 -1
  429. package/package.json +36 -9
  430. package/postinstall.mjs +131 -0
  431. package/ratex-version.json +21 -0
  432. package/src/EnrichedMarkdownNativeComponent.ts +65 -0
  433. package/src/EnrichedMarkdownTextInput.tsx +162 -8
  434. package/src/EnrichedMarkdownTextInputNativeComponent.ts +89 -5
  435. package/src/EnrichedMarkdownTextNativeComponent.ts +66 -0
  436. package/src/headingDefaults.ts +21 -0
  437. package/src/index.tsx +9 -0
  438. package/src/index.web.tsx +1 -0
  439. package/src/jest/index.tsx +215 -0
  440. package/src/native/EnrichedMarkdownText.tsx +40 -2
  441. package/src/normalizeMarkdownStyle.ts +102 -16
  442. package/src/normalizeMarkdownStyle.web.ts +63 -15
  443. package/src/normalizeMarkdownTextInputStyle.ts +110 -35
  444. package/src/normalizeMenuItem.ts +1 -1
  445. package/src/types/MarkdownStyle.ts +74 -0
  446. package/src/types/MarkdownStyleInternal.ts +39 -0
  447. package/src/types/MarkdownTextProps.ts +65 -0
  448. package/src/types/MarkdownTextProps.web.ts +19 -0
  449. package/src/types/events.ts +21 -0
  450. package/src/utils/textInputState.ts +35 -0
  451. package/src/web/EnrichedMarkdownText.tsx +16 -2
  452. package/src/web/parseMarkdown.ts +6 -2
  453. package/src/web/renderers/InlineRenderers.tsx +5 -0
  454. package/src/web/renderers/ListRenderers.tsx +14 -2
  455. package/src/web/renderers/index.tsx +6 -2
  456. package/src/web/styles.ts +89 -5
  457. package/src/web/types.ts +6 -1
  458. package/src/web/utils.ts +1 -0
  459. package/src/web/wasm/md4c.js +0 -0
  460. package/vendor-grammars.mjs +511 -0
  461. package/vendor-ratex.mjs +173 -0
  462. package/app.plugin.js +0 -2
  463. package/plugin/build/withAndroidMath.js +0 -19
  464. package/plugin/build/withIosMath.js +0 -28
  465. package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
  466. package/plugin/src/withAndroidMath.ts +0 -24
  467. package/plugin/src/withIosMath.ts +0 -35
  468. package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
  469. package/plugin/tsconfig.build.json +0 -16
@@ -0,0 +1,566 @@
1
+ #import "ENRMCodeBlockContainerView.h"
2
+ #import "ENRMCodeBlockContent.h"
3
+ #import "ENRMCodeBlockHighlighter.h"
4
+ #import "MarkdownASTNode.h"
5
+ #import "PasteboardUtils.h"
6
+ #if TARGET_OS_OSX
7
+ #import "ENRMMenuAction.h"
8
+ #endif
9
+
10
+ // Block segment view for fenced code blocks (see SegmentRenderer.m):
11
+ // a fixed header bar (language name, copy button) above a horizontally
12
+ // scrolling, non-wrapping code pane. The container's drawRect: draws
13
+ // background, border, label, and divider; only the copy button and the
14
+ // scroll view are subviews. Syntax coloring comes from the
15
+ // ENRMCodeBlockHighlighter seam and falls back to plain text. The box
16
+ // visuals must stay in sync with the commonmark flavor's CodeBlockBackground.
17
+ //
18
+ // measureHeight: must stay in sync with the drawn content: it uses the
19
+ // unconstrained bounding rect of the same attributed string and the same
20
+ // header metrics, so the reported height matches the drawn height. Since
21
+ // lines never wrap, the height is independent of the available width.
22
+
23
+ static const CGFloat kENRMHeaderLabelScale = 0.85;
24
+ // The copy glyph reads cleaner a touch smaller than the language label and at a
25
+ // regular (not medium) weight; sized independently so the two never couple.
26
+ static const CGFloat kENRMHeaderIconScale = 0.72;
27
+ static const CGFloat kENRMHeaderSecondaryAlpha = 0.6;
28
+ static const CGFloat kENRMHeaderDividerAlpha = 0.2;
29
+
30
+ // Height geometry and code-run construction shared by the instance layout path
31
+ // and the view-free measureHeightForCodeBlockNode:, so the two cannot drift.
32
+
33
+ static CGFloat ENRMCodeBlockContentInset(StyleConfig *config)
34
+ {
35
+ return [config codeBlockPadding] + [config codeBlockBorderWidth];
36
+ }
37
+
38
+ #if !TARGET_OS_OSX
39
+ static UIFont *ENRMCodeBlockHeaderFont(StyleConfig *config)
40
+ {
41
+ return [UIFont systemFontOfSize:[config codeBlockFont].pointSize * kENRMHeaderLabelScale weight:UIFontWeightMedium];
42
+ }
43
+
44
+ static CGFloat ENRMCodeBlockHeaderLabelLineHeight(UIFont *headerFont)
45
+ {
46
+ return ceil(headerFont.lineHeight);
47
+ }
48
+ #else
49
+ static NSFont *ENRMCodeBlockHeaderFont(StyleConfig *config)
50
+ {
51
+ return [NSFont systemFontOfSize:[config codeBlockFont].pointSize * kENRMHeaderLabelScale weight:NSFontWeightMedium];
52
+ }
53
+
54
+ static CGFloat ENRMCodeBlockHeaderLabelLineHeight(NSFont *headerFont)
55
+ {
56
+ return ceil(headerFont.ascender - headerFont.descender);
57
+ }
58
+ #endif
59
+
60
+ static NSAttributedString *ENRMCodeBlockPlainAttributedCode(NSString *code, StyleConfig *config)
61
+ {
62
+ if (code.length == 0) {
63
+ return [[NSAttributedString alloc] initWithString:@""];
64
+ }
65
+ NSMutableAttributedString *attributed = [[NSMutableAttributedString alloc] initWithString:code];
66
+ ENRMApplyCodeBlockTextAttributes(attributed, NSMakeRange(0, attributed.length), config);
67
+ return attributed;
68
+ }
69
+
70
+ // Unwrapped code extent: width feeds the horizontal scroll, height the box
71
+ // measurement. Width-independent since lines never wrap.
72
+ static CGSize ENRMCodeBlockCodeSize(NSAttributedString *attributedCode)
73
+ {
74
+ if (attributedCode.length == 0) {
75
+ return CGSizeZero;
76
+ }
77
+ CGRect bounds = [attributedCode boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)
78
+ options:NSStringDrawingUsesLineFragmentOrigin
79
+ context:nil];
80
+ return CGSizeMake(ceil(bounds.size.width), ceil(bounds.size.height));
81
+ }
82
+
83
+ // Used only to pick the scroll indicator style for the code pane, so the
84
+ // indicator stays visible on dark code block backgrounds without affecting
85
+ // any other scroll view.
86
+ static BOOL ENRMColorIsDark(RCTUIColor *color)
87
+ {
88
+ if (!color) {
89
+ return NO;
90
+ }
91
+ CGFloat r = 0, g = 0, b = 0, a = 0;
92
+ #if !TARGET_OS_OSX
93
+ if (![color getRed:&r green:&g blue:&b alpha:&a]) {
94
+ CGFloat white = 0;
95
+ if (![color getWhite:&white alpha:&a]) {
96
+ return NO;
97
+ }
98
+ r = g = b = white;
99
+ }
100
+ #else
101
+ NSColor *rgb = [color colorUsingColorSpace:[NSColorSpace sRGBColorSpace]];
102
+ if (!rgb) {
103
+ return NO;
104
+ }
105
+ [rgb getRed:&r green:&g blue:&b alpha:&a];
106
+ #endif
107
+ return (0.299 * r + 0.587 * g + 0.114 * b) < 0.5;
108
+ }
109
+
110
+ // Scrollable code pane content. Draws the attributed code unwrapped at a
111
+ // fixed origin; the hosting ENRMCodeBlockContainerView draws everything else.
112
+ @interface ENRMCodeBlockContentView : RCTUIView
113
+ @property (nonatomic, strong, nullable) NSAttributedString *attributedCode;
114
+ @property (nonatomic, assign) CGPoint textOrigin;
115
+ #if TARGET_OS_OSX
116
+ @property (nonatomic, copy, nullable) NSMenu * (^menuProvider)(void);
117
+ #endif
118
+ @end
119
+
120
+ @implementation ENRMCodeBlockContentView
121
+
122
+ #if TARGET_OS_OSX
123
+ - (BOOL)isFlipped
124
+ {
125
+ return YES;
126
+ }
127
+
128
+ - (NSMenu *)menuForEvent:(NSEvent *)event
129
+ {
130
+ return self.menuProvider ? self.menuProvider() : [super menuForEvent:event];
131
+ }
132
+ #endif
133
+
134
+ - (void)drawRect:(CGRect)rect
135
+ {
136
+ if (self.attributedCode.length > 0) {
137
+ [self.attributedCode drawAtPoint:self.textOrigin];
138
+ }
139
+ }
140
+
141
+ @end
142
+
143
+ #if !TARGET_OS_OSX
144
+ @interface ENRMCodeBlockContainerView () <UIContextMenuInteractionDelegate>
145
+ @end
146
+ #endif
147
+
148
+ @implementation ENRMCodeBlockContainerView {
149
+ NSAttributedString *_attributedCode;
150
+ NSString *_cachedCode;
151
+ NSString *_cachedLanguage;
152
+ NSString *_displayLanguage;
153
+ NSString *_fenceChar;
154
+ RCTUIScrollView *_scrollView;
155
+ ENRMCodeBlockContentView *_codeContentView;
156
+ CGSize _codeSize;
157
+ CGFloat _headerLabelLineHeight;
158
+ NSAttributedString *_languageLabel;
159
+ CGSize _languageLabelSize;
160
+ #if !TARGET_OS_OSX
161
+ UIFont *_headerFont;
162
+ UIButton *_copyButton;
163
+ #else
164
+ NSFont *_headerFont;
165
+ NSButton *_copyButton;
166
+ #endif
167
+ }
168
+
169
+ @synthesize copyLabel = _copyLabel;
170
+ @synthesize copyAsMarkdownLabel = _copyAsMarkdownLabel;
171
+
172
+ - (void)setCopyLabel:(NSString *)copyLabel
173
+ {
174
+ _copyLabel = [copyLabel copy];
175
+ _copyButton.accessibilityLabel = _copyLabel;
176
+ }
177
+
178
+ - (void)setPending:(BOOL)pending
179
+ {
180
+ if (_pending == pending) {
181
+ return;
182
+ }
183
+ _pending = pending;
184
+ // Header stays visible while streaming; only copying is held back.
185
+ _copyButton.enabled = !pending;
186
+ // The reconciler can reuse an unchanged block without re-applying the node, so
187
+ // re-derive here to pick up highlighting once the block closes.
188
+ [self rebuildAttributedCode];
189
+ #if !TARGET_OS_OSX
190
+ [self setNeedsLayout];
191
+ [self setNeedsDisplay];
192
+ [_codeContentView setNeedsDisplay];
193
+ #else
194
+ self.needsLayout = YES;
195
+ [self setNeedsDisplay:YES];
196
+ [_codeContentView setNeedsDisplay:YES];
197
+ #endif
198
+ }
199
+
200
+ - (instancetype)initWithConfig:(StyleConfig *)config
201
+ {
202
+ self = [super initWithFrame:CGRectZero];
203
+ if (self) {
204
+ _config = config;
205
+ _cachedCode = @"";
206
+ _fenceChar = @"`";
207
+ _headerFont = ENRMCodeBlockHeaderFont(config);
208
+ _headerLabelLineHeight = ENRMCodeBlockHeaderLabelLineHeight(_headerFont);
209
+ self.backgroundColor = [RCTUIColor clearColor];
210
+ [self setupScrollView];
211
+
212
+ #if !TARGET_OS_OSX
213
+ self.contentMode = UIViewContentModeRedraw;
214
+ self.isAccessibilityElement = YES;
215
+
216
+ UIContextMenuInteraction *contextMenu = [[UIContextMenuInteraction alloc] initWithDelegate:self];
217
+ [self addInteraction:contextMenu];
218
+
219
+ _copyButton = [UIButton buttonWithType:UIButtonTypeSystem];
220
+ UIImageSymbolConfiguration *symbolConfig =
221
+ [UIImageSymbolConfiguration configurationWithPointSize:[config codeBlockFont].pointSize * kENRMHeaderIconScale
222
+ weight:UIImageSymbolWeightRegular];
223
+ [_copyButton setImage:[UIImage systemImageNamed:@"doc.on.doc" withConfiguration:symbolConfig]
224
+ forState:UIControlStateNormal];
225
+ _copyButton.tintColor = [[config codeBlockColor] colorWithAlphaComponent:kENRMHeaderSecondaryAlpha];
226
+ [_copyButton addTarget:self action:@selector(copyCodeToPasteboard) forControlEvents:UIControlEventTouchUpInside];
227
+ [self addSubview:_copyButton];
228
+ #else
229
+ NSImageSymbolConfiguration *symbolConfig =
230
+ [NSImageSymbolConfiguration configurationWithPointSize:[config codeBlockFont].pointSize * kENRMHeaderIconScale
231
+ weight:NSFontWeightRegular];
232
+ NSImage *copyImage = [[NSImage imageWithSystemSymbolName:@"doc.on.doc"
233
+ accessibilityDescription:nil] imageWithSymbolConfiguration:symbolConfig];
234
+ _copyButton = [NSButton buttonWithImage:copyImage target:self action:@selector(copyCodeToPasteboard)];
235
+ _copyButton.bordered = NO;
236
+ _copyButton.contentTintColor = [[config codeBlockColor] colorWithAlphaComponent:kENRMHeaderSecondaryAlpha];
237
+ [self addSubview:_copyButton];
238
+ #endif
239
+ }
240
+ return self;
241
+ }
242
+
243
+ - (void)setupScrollView
244
+ {
245
+ _scrollView = [[RCTUIScrollView alloc] init];
246
+ _scrollView.showsVerticalScrollIndicator = NO;
247
+ _scrollView.showsHorizontalScrollIndicator = YES;
248
+ _codeContentView = [[ENRMCodeBlockContentView alloc] initWithFrame:CGRectZero];
249
+ BOOL darkBackground = ENRMColorIsDark([_config codeBlockBackgroundColor]);
250
+ #if !TARGET_OS_OSX
251
+ _scrollView.bounces = YES;
252
+ _scrollView.alwaysBounceHorizontal = NO;
253
+ _scrollView.backgroundColor = [UIColor clearColor];
254
+ _scrollView.isAccessibilityElement = NO;
255
+ _scrollView.accessibilityElementsHidden = YES;
256
+ _scrollView.indicatorStyle = darkBackground ? UIScrollViewIndicatorStyleWhite : UIScrollViewIndicatorStyleDefault;
257
+ _codeContentView.backgroundColor = [UIColor clearColor];
258
+ _codeContentView.contentMode = UIViewContentModeRedraw;
259
+ [_scrollView addSubview:_codeContentView];
260
+ [_codeContentView addInteraction:[[UIContextMenuInteraction alloc] initWithDelegate:self]];
261
+ #else
262
+ ((NSScrollView *)_scrollView).drawsBackground = NO;
263
+ ((NSScrollView *)_scrollView).scrollerKnobStyle =
264
+ darkBackground ? NSScrollerKnobStyleLight : NSScrollerKnobStyleDefault;
265
+ __weak ENRMCodeBlockContainerView *weakSelf = self;
266
+ NSMenu * (^menuProvider)(void) = ^{ return [weakSelf buildContextMenu]; };
267
+ _codeContentView.menuProvider = menuProvider;
268
+ [(NSScrollView *)_scrollView setDocumentView:_codeContentView];
269
+ #endif
270
+ [self addSubview:_scrollView];
271
+ }
272
+
273
+ - (void)layoutScrollArea
274
+ {
275
+ CGFloat borderW = ceil([_config codeBlockBorderWidth]);
276
+ CGFloat headerH = [self headerHeight];
277
+ CGFloat inset = [self contentInset];
278
+ CGRect frame = CGRectMake(borderW, headerH, MAX(self.bounds.size.width - borderW * 2, 0),
279
+ MAX(self.bounds.size.height - headerH - borderW, 0));
280
+ _scrollView.frame = frame;
281
+
282
+ CGFloat horizontalPad = MAX(inset - borderW, 0);
283
+ CGFloat contentWidth = MAX(_codeSize.width + horizontalPad * 2, frame.size.width);
284
+ _codeContentView.textOrigin = CGPointMake(horizontalPad, inset);
285
+ _codeContentView.frame = CGRectMake(0, 0, contentWidth, frame.size.height);
286
+ #if !TARGET_OS_OSX
287
+ _scrollView.contentSize = CGSizeMake(contentWidth, frame.size.height);
288
+ _scrollView.scrollEnabled = contentWidth > frame.size.width;
289
+ #endif
290
+ }
291
+
292
+ // Header is the top content inset plus one label line; the code text's own
293
+ // top inset then forms the single gap below the label.
294
+ - (CGFloat)headerHeight
295
+ {
296
+ return [self contentInset] + _headerLabelLineHeight;
297
+ }
298
+
299
+ - (void)layoutHeaderButton
300
+ {
301
+ CGFloat headerH = [self headerHeight];
302
+ CGFloat iconWidth = _copyButton.intrinsicContentSize.width;
303
+ if (iconWidth <= 0 || iconWidth > headerH) {
304
+ iconWidth = headerH;
305
+ }
306
+ CGFloat iconSlack = (headerH - iconWidth) / 2;
307
+ CGFloat buttonLeft = MAX(self.bounds.size.width - [self contentInset] - headerH + iconSlack, 0);
308
+ CGFloat labelCenterY = headerH - _headerLabelLineHeight / 2;
309
+ CGFloat buttonTop = MAX(labelCenterY - headerH / 2, 0);
310
+ _copyButton.frame = CGRectMake(buttonLeft, buttonTop, headerH, headerH);
311
+ }
312
+
313
+ #if !TARGET_OS_OSX
314
+ - (void)layoutSubviews
315
+ {
316
+ [super layoutSubviews];
317
+ [self layoutHeaderButton];
318
+ [self layoutScrollArea];
319
+ }
320
+ #else
321
+ - (void)layout
322
+ {
323
+ [super layout];
324
+ [self layoutHeaderButton];
325
+ [self layoutScrollArea];
326
+ }
327
+ #endif
328
+
329
+ #if TARGET_OS_OSX
330
+ - (BOOL)isFlipped
331
+ {
332
+ return YES;
333
+ }
334
+
335
+ - (void)setFrameSize:(NSSize)newSize
336
+ {
337
+ [super setFrameSize:newSize];
338
+ [self setNeedsDisplay:YES];
339
+ }
340
+ #endif
341
+
342
+ // Highlighting is deferred while pending, applied once the block closes.
343
+ - (void)rebuildAttributedCode
344
+ {
345
+ NSAttributedString *plainCode = [self plainAttributedCode];
346
+ NSAttributedString *highlighted =
347
+ _pending ? nil : ENRMHighlightedAttributedCode(plainCode, _cachedCode, _cachedLanguage, _config);
348
+ _attributedCode = highlighted ?: plainCode;
349
+ _codeSize = ENRMCodeBlockCodeSize(_attributedCode);
350
+ _codeContentView.attributedCode = _attributedCode;
351
+ }
352
+
353
+ - (void)applyCodeBlockNode:(MarkdownASTNode *)node
354
+ {
355
+ _cachedCode = ENRMCodeBlockExtractCode(node);
356
+ _fenceChar = ENRMCodeBlockFenceChar(node);
357
+
358
+ NSString *newLanguage = ENRMCodeBlockLanguage(node);
359
+ BOOL languageChanged = newLanguage != _cachedLanguage && ![newLanguage isEqualToString:_cachedLanguage];
360
+ if (languageChanged) {
361
+ _cachedLanguage = newLanguage;
362
+ _displayLanguage = ENRMCodeBlockDisplayLanguageName(newLanguage);
363
+ [self rebuildLanguageLabel];
364
+ }
365
+
366
+ [self rebuildAttributedCode];
367
+
368
+ #if !TARGET_OS_OSX
369
+ [self setNeedsLayout];
370
+ [self setNeedsDisplay];
371
+ [_codeContentView setNeedsDisplay];
372
+ #else
373
+ self.needsLayout = YES;
374
+ [self setNeedsDisplay:YES];
375
+ [_codeContentView setNeedsDisplay:YES];
376
+ #endif
377
+ }
378
+
379
+ - (void)rebuildLanguageLabel
380
+ {
381
+ if (_displayLanguage.length == 0) {
382
+ _languageLabel = nil;
383
+ _languageLabelSize = CGSizeZero;
384
+ return;
385
+ }
386
+ NSMutableDictionary *labelAttributes = [NSMutableDictionary dictionary];
387
+ labelAttributes[NSFontAttributeName] = _headerFont;
388
+ RCTUIColor *labelColor = [[_config codeBlockColor] colorWithAlphaComponent:kENRMHeaderSecondaryAlpha];
389
+ if (labelColor) {
390
+ labelAttributes[NSForegroundColorAttributeName] = labelColor;
391
+ }
392
+ _languageLabel = [[NSAttributedString alloc] initWithString:_displayLanguage attributes:labelAttributes];
393
+ _languageLabelSize = _languageLabel.size;
394
+ }
395
+
396
+ - (NSAttributedString *)plainAttributedCode
397
+ {
398
+ return ENRMCodeBlockPlainAttributedCode(_cachedCode, _config);
399
+ }
400
+
401
+ - (CGFloat)contentInset
402
+ {
403
+ return ENRMCodeBlockContentInset(_config);
404
+ }
405
+
406
+ - (CGFloat)measureHeight:(CGFloat)maxWidth
407
+ {
408
+ CGFloat inset = [self contentInset];
409
+ return _codeSize.height + inset * 2 + [self headerHeight];
410
+ }
411
+
412
+ + (CGFloat)measureHeightForCodeBlockNode:(MarkdownASTNode *)node config:(StyleConfig *)config
413
+ {
414
+ CGFloat inset = ENRMCodeBlockContentInset(config);
415
+ CGFloat headerH = inset + ENRMCodeBlockHeaderLabelLineHeight(ENRMCodeBlockHeaderFont(config));
416
+ NSAttributedString *code = ENRMCodeBlockPlainAttributedCode(ENRMCodeBlockExtractCode(node), config);
417
+ return ENRMCodeBlockCodeSize(code).height + inset * 2 + headerH;
418
+ }
419
+
420
+ - (void)drawRect:(CGRect)rect
421
+ {
422
+ CGFloat borderWidth = [_config codeBlockBorderWidth];
423
+ CGFloat radius = [_config codeBlockBorderRadius];
424
+ CGRect borderRect = CGRectInset(self.bounds, borderWidth / 2, borderWidth / 2);
425
+
426
+ #if !TARGET_OS_OSX
427
+ UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:borderRect cornerRadius:radius];
428
+ #else
429
+ NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:borderRect xRadius:radius yRadius:radius];
430
+ #endif
431
+
432
+ RCTUIColor *backgroundColor = [_config codeBlockBackgroundColor];
433
+ if (backgroundColor) {
434
+ [backgroundColor setFill];
435
+ [path fill];
436
+ }
437
+ if (borderWidth > 0) {
438
+ RCTUIColor *borderColor = [_config codeBlockBorderColor];
439
+ if (borderColor) {
440
+ path.lineWidth = borderWidth;
441
+ [borderColor setStroke];
442
+ [path stroke];
443
+ }
444
+ }
445
+
446
+ CGFloat inset = [self contentInset];
447
+ CGFloat headerH = [self headerHeight];
448
+
449
+ // Divider between the header and the code, centered in the gap the code
450
+ // text's top inset creates, so it adds no height of its own.
451
+ RCTUIColor *dividerColor = [[_config codeBlockColor] colorWithAlphaComponent:kENRMHeaderDividerAlpha];
452
+ if (dividerColor) {
453
+ CGRect dividerRect = CGRectMake(borderWidth, headerH + inset / 2, self.bounds.size.width - borderWidth * 2, 1);
454
+ [dividerColor setFill];
455
+ #if !TARGET_OS_OSX
456
+ [[UIBezierPath bezierPathWithRect:dividerRect] fill];
457
+ #else
458
+ [[NSBezierPath bezierPathWithRect:dividerRect] fill];
459
+ #endif
460
+ }
461
+
462
+ if (_languageLabel.length > 0) {
463
+ [_languageLabel drawAtPoint:CGPointMake(inset, headerH - _languageLabelSize.height)];
464
+ }
465
+ }
466
+
467
+ - (NSString *)fencedMarkdown
468
+ {
469
+ return ENRMCodeBlockFencedMarkdown(_cachedCode, _cachedLanguage, _fenceChar);
470
+ }
471
+
472
+ - (void)copyCodeToPasteboard
473
+ {
474
+ copyStringToPasteboard(_cachedCode);
475
+ if (self.onCopyPress) {
476
+ self.onCopyPress(_cachedCode ?: @"", _cachedLanguage ?: @"");
477
+ }
478
+ }
479
+
480
+ - (void)copyMarkdownToPasteboard
481
+ {
482
+ copyStringToPasteboard([self fencedMarkdown]);
483
+ }
484
+
485
+ #if !TARGET_OS_OSX
486
+ - (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction
487
+ configurationForMenuAtLocation:(CGPoint)location
488
+ {
489
+ // Returning nil is the UIKit-sanctioned way to suppress a context menu.
490
+ if (_pending || self.contextMenuHidden) {
491
+ return nil;
492
+ }
493
+ return [UIContextMenuConfiguration
494
+ configurationWithIdentifier:nil
495
+ previewProvider:nil
496
+ actionProvider:^UIMenu *(NSArray<UIMenuElement *> *suggestedActions) {
497
+ UIAction *copyCode =
498
+ [UIAction actionWithTitle:self.copyLabel
499
+ image:[RCTUIImage systemImageNamed:@"doc.on.doc"]
500
+ identifier:nil
501
+ handler:^(__kindof UIAction *action) { [self copyCodeToPasteboard]; }];
502
+
503
+ UIAction *copyMarkdown =
504
+ [UIAction actionWithTitle:self.copyAsMarkdownLabel
505
+ image:[RCTUIImage systemImageNamed:@"doc.text"]
506
+ identifier:nil
507
+ handler:^(__kindof UIAction *action) { [self copyMarkdownToPasteboard]; }];
508
+
509
+ return [UIMenu menuWithTitle:@"" children:@[ copyCode, copyMarkdown ]];
510
+ }];
511
+ }
512
+ #endif
513
+
514
+ #if TARGET_OS_OSX
515
+ - (NSMenu *)buildContextMenu
516
+ {
517
+ // Both menuForEvent: paths return this directly, so nil fully suppresses the
518
+ // menu rather than restoring the AppKit default.
519
+ if (_pending || self.contextMenuHidden) {
520
+ return nil;
521
+ }
522
+ NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
523
+ [menu addItem:ENRMCreateMenuItem(self.copyLabel, ^{ [self copyCodeToPasteboard]; })];
524
+ [menu addItem:ENRMCreateMenuItem(self.copyAsMarkdownLabel, ^{ [self copyMarkdownToPasteboard]; })];
525
+ return menu;
526
+ }
527
+
528
+ - (NSMenu *)menuForEvent:(NSEvent *)event
529
+ {
530
+ return [self buildContextMenu];
531
+ }
532
+ #endif
533
+
534
+ - (NSString *)accessibilityLabel
535
+ {
536
+ return _cachedCode;
537
+ }
538
+
539
+ #if !TARGET_OS_OSX
540
+ - (UIAccessibilityTraits)accessibilityTraits
541
+ {
542
+ return UIAccessibilityTraitStaticText;
543
+ }
544
+
545
+ // The container is a single accessibility element, which hides the copy
546
+ // button subview from VoiceOver; expose the copy action explicitly instead.
547
+ - (NSArray<UIAccessibilityCustomAction *> *)accessibilityCustomActions
548
+ {
549
+ if (_pending || self.copyLabel.length == 0) {
550
+ return @[];
551
+ }
552
+ UIAccessibilityCustomAction *copyAction =
553
+ [[UIAccessibilityCustomAction alloc] initWithName:self.copyLabel
554
+ target:self
555
+ selector:@selector(performCopyAccessibilityAction:)];
556
+ return @[ copyAction ];
557
+ }
558
+
559
+ - (BOOL)performCopyAccessibilityAction:(UIAccessibilityCustomAction *)action
560
+ {
561
+ [self copyCodeToPasteboard];
562
+ return YES;
563
+ }
564
+ #endif
565
+
566
+ @end
@@ -14,6 +14,14 @@ NS_ASSUME_NONNULL_BEGIN
14
14
 
15
15
  - (CGFloat)measureHeight:(CGFloat)maxWidth;
16
16
 
17
+ /// View-free math-block height for shadow-node measurement (issue #550):
18
+ /// parses the LaTeX through the same RaTeX bridge `applyLatex:` uses and
19
+ /// applies the same padding math as `measureHeight:` — including the wrapped
20
+ /// source-fallback path when RaTeX cannot parse — without creating any view.
21
+ /// Runs on the calling thread. Like every member of this class, only
22
+ /// implemented when ENRICHED_MARKDOWN_MATH is on — guard call sites.
23
+ + (CGFloat)measureHeightForLatex:(NSString *)latex config:(StyleConfig *)config maxWidth:(CGFloat)maxWidth;
24
+
17
25
  @property (nonatomic, strong) StyleConfig *config;
18
26
  @property (nonatomic, copy, readonly) NSString *cachedLatex;
19
27
  @property (nonatomic, strong, nullable) ENRMAccessibilityLabels *accessibilityLabels;
@@ -23,6 +31,10 @@ NS_ASSUME_NONNULL_BEGIN
23
31
  @property (nonatomic, copy, nullable, getter=menuCopyLabel) NSString *copyLabel;
24
32
  @property (nonatomic, copy, nullable, getter=menuCopyAsMarkdownLabel) NSString *copyAsMarkdownLabel;
25
33
 
34
+ /// Suppresses the long-press copy menu on this block. Mirrors the
35
+ /// `contextMenuHidden` prop; selection and link handling are unaffected.
36
+ @property (nonatomic, assign) BOOL contextMenuHidden;
37
+
26
38
  @end
27
39
 
28
40
  NS_ASSUME_NONNULL_END