react-native-enriched-markdown-scaffold 0.7.4-scaffold.9 → 1.0.2-scaffold.2

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 +186 -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 +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 +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 +35 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +886 -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 +189 -13
  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 +54 -4
  26. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +901 -462
  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/FormattingStore.kt +80 -87
  43. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
  44. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +116 -22
  45. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
  46. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
  47. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
  48. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +4 -2
  49. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
  50. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
  51. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
  52. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
  53. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
  54. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
  55. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
  56. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
  58. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
  65. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
  66. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
  68. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
  69. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
  70. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
  71. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
  72. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
  73. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
  74. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
  75. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
  76. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +30 -27
  77. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
  78. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
  79. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +27 -3
  80. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
  81. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
  82. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
  83. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
  84. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
  85. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
  86. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
  87. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
  88. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
  89. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
  90. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
  91. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
  93. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
  94. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
  95. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
  96. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
  97. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
  98. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
  99. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
  100. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +37 -7
  101. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
  102. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
  103. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
  104. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
  105. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
  106. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
  107. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +20 -0
  108. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
  109. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
  110. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
  111. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
  112. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
  113. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
  114. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
  115. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
  116. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +49 -15
  117. package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +45 -0
  118. package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +396 -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 +36 -9
  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 +6 -4
  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 +234 -12
  152. package/docs/BREAKING_CHANGES.md +129 -0
  153. package/docs/CODE_HIGHLIGHT.md +133 -0
  154. package/docs/COPY_OPTIONS.md +47 -3
  155. package/docs/ELEMENTS_STRUCTURE.md +52 -4
  156. package/docs/IMAGE_CACHING.md +30 -0
  157. package/docs/INPUT.md +108 -11
  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 +284 -75
  169. package/ios/EnrichedMarkdownText.h +7 -0
  170. package/ios/EnrichedMarkdownText.mm +101 -73
  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 +35 -0
  179. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +886 -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/ENRMClipboardCoordinator.h +45 -0
  190. package/ios/input/ENRMClipboardCoordinator.mm +120 -0
  191. package/ios/input/ENRMDetectorPipeline.h +2 -1
  192. package/ios/input/ENRMEditPipeline.h +76 -0
  193. package/ios/input/ENRMEditPipeline.mm +228 -0
  194. package/ios/input/ENRMEditSession.h +36 -0
  195. package/ios/input/ENRMEditSession.mm +63 -0
  196. package/ios/input/ENRMFormattingStore.h +17 -0
  197. package/ios/input/ENRMFormattingStore.mm +95 -105
  198. package/ios/input/ENRMInputBlockType.h +91 -0
  199. package/ios/input/ENRMInputBlockType.mm +5 -0
  200. package/ios/input/ENRMInputDecorationDrawer.h +18 -0
  201. package/ios/input/ENRMInputEventEmitter.h +56 -0
  202. package/ios/input/ENRMInputEventEmitter.mm +308 -0
  203. package/ios/input/ENRMInputFormatter.h +29 -69
  204. package/ios/input/ENRMInputFormatter.mm +216 -124
  205. package/ios/input/ENRMInputFormatterStyle.h +99 -0
  206. package/ios/input/ENRMInputFormatterStyle.mm +188 -0
  207. package/ios/input/ENRMInputLayoutManager.h +9 -0
  208. package/ios/input/ENRMInputLayoutManager.mm +30 -0
  209. package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
  210. package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
  211. package/ios/input/ENRMInputParser.h +5 -6
  212. package/ios/input/ENRMInputParser.mm +461 -178
  213. package/ios/input/ENRMInputRemend.mm +2 -2
  214. package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
  215. package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
  216. package/ios/input/ENRMInputTextView.mm +103 -8
  217. package/ios/input/ENRMInputTypingAttributesController.h +42 -0
  218. package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
  219. package/ios/input/ENRMLinkCoordinator.h +41 -0
  220. package/ios/input/ENRMLinkCoordinator.mm +89 -0
  221. package/ios/input/ENRMMarkdownSerializer.h +29 -5
  222. package/ios/input/ENRMMarkdownSerializer.mm +170 -48
  223. package/ios/input/ENRMMathAtom.h +26 -0
  224. package/ios/input/ENRMMathAtom.mm +12 -0
  225. package/ios/input/ENRMMentionCoordinator.h +45 -0
  226. package/ios/input/ENRMMentionCoordinator.mm +167 -0
  227. package/ios/input/ENRMRangeEditAdjustment.h +38 -0
  228. package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
  229. package/ios/input/ENRMRangeStoreUtils.h +39 -0
  230. package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
  231. package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
  232. package/ios/input/EnrichedMarkdownTextInput.h +7 -1
  233. package/ios/input/EnrichedMarkdownTextInput.mm +1089 -1023
  234. package/ios/input/InputStylePropsUtils.h +109 -68
  235. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
  236. package/ios/input/styles/ENRMBlockHandler.h +46 -0
  237. package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
  238. package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
  239. package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
  240. package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
  241. package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
  242. package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
  243. package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
  244. package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
  245. package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
  246. package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
  247. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
  248. package/ios/internals/MeasurementCache.h +33 -7
  249. package/ios/internals/ShadowMeasurementUtils.h +63 -58
  250. package/ios/math/ENRMMathChipController.h +74 -0
  251. package/ios/math/ENRMMathChipController.mm +476 -0
  252. package/ios/math/ENRMRaTeXBridge.swift +4 -1
  253. package/ios/parser/ENRMMarkdownParser.h +1 -8
  254. package/ios/parser/ENRMMarkdownParser.mm +2 -11
  255. package/ios/parser/MarkdownASTNode.h +2 -1
  256. package/ios/parser/MarkdownParserBridge.mm +4 -0
  257. package/ios/renderer/AttributedRenderer.m +20 -2
  258. package/ios/renderer/BaseRenderer.h +17 -2
  259. package/ios/renderer/BaseRenderer.m +30 -0
  260. package/ios/renderer/BlockquoteRenderer.h +1 -1
  261. package/ios/renderer/BlockquoteRenderer.m +144 -35
  262. package/ios/renderer/CodeBlockRenderer.h +1 -1
  263. package/ios/renderer/CodeBlockRenderer.m +27 -23
  264. package/ios/renderer/CodeRenderer.h +1 -1
  265. package/ios/renderer/CodeRenderer.m +3 -1
  266. package/ios/renderer/ENRMImageRenderer.h +1 -1
  267. package/ios/renderer/ENRMImageRenderer.m +5 -1
  268. package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
  269. package/ios/renderer/ENRMMathInlineRenderer.m +5 -1
  270. package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
  271. package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
  272. package/ios/renderer/EmphasisRenderer.h +1 -1
  273. package/ios/renderer/EmphasisRenderer.m +3 -1
  274. package/ios/renderer/HeadingRenderer.h +1 -1
  275. package/ios/renderer/HeadingRenderer.m +13 -6
  276. package/ios/renderer/HighlightRenderer.h +1 -1
  277. package/ios/renderer/HighlightRenderer.m +3 -1
  278. package/ios/renderer/LinkRenderer.h +1 -1
  279. package/ios/renderer/LinkRenderer.m +3 -1
  280. package/ios/renderer/ListItemRenderer.h +13 -1
  281. package/ios/renderer/ListItemRenderer.m +102 -44
  282. package/ios/renderer/ListRenderer.h +2 -2
  283. package/ios/renderer/ListRenderer.m +63 -25
  284. package/ios/renderer/ParagraphRenderer.h +1 -1
  285. package/ios/renderer/ParagraphRenderer.m +16 -8
  286. package/ios/renderer/RenderContext.h +10 -0
  287. package/ios/renderer/RenderContext.m +44 -0
  288. package/ios/renderer/RendererFactory.m +14 -0
  289. package/ios/renderer/StrikethroughRenderer.h +1 -1
  290. package/ios/renderer/StrikethroughRenderer.m +3 -1
  291. package/ios/renderer/StrongRenderer.h +1 -1
  292. package/ios/renderer/StrongRenderer.m +3 -1
  293. package/ios/renderer/SubscriptRenderer.h +1 -1
  294. package/ios/renderer/SubscriptRenderer.m +3 -1
  295. package/ios/renderer/SuperscriptRenderer.h +1 -1
  296. package/ios/renderer/SuperscriptRenderer.m +3 -1
  297. package/ios/renderer/TextRenderer.h +2 -2
  298. package/ios/renderer/TextRenderer.m +3 -1
  299. package/ios/renderer/ThematicBreakRenderer.h +1 -1
  300. package/ios/renderer/ThematicBreakRenderer.m +3 -1
  301. package/ios/renderer/UnderlineRenderer.h +1 -1
  302. package/ios/renderer/UnderlineRenderer.m +3 -1
  303. package/ios/styles/StyleConfig.h +22 -0
  304. package/ios/styles/StyleConfig.mm +132 -0
  305. package/ios/utils/BlockquoteBorder.h +6 -0
  306. package/ios/utils/BlockquoteBorder.m +249 -52
  307. package/ios/utils/CodeBlockBackground.m +16 -2
  308. package/ios/utils/ENRMAtomicSize.h +65 -0
  309. package/ios/utils/ENRMBlockMenu.h +57 -0
  310. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  311. package/ios/utils/ENRMCodeBlockContent.mm +79 -0
  312. package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
  313. package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
  314. package/ios/utils/ENRMFeatureFlags.h +7 -0
  315. package/ios/utils/ENRMImageDownloader.h +11 -1
  316. package/ios/utils/ENRMImageDownloader.m +60 -16
  317. package/ios/utils/ENRMLocalImageLoader.h +31 -0
  318. package/ios/utils/ENRMLocalImageLoader.m +68 -0
  319. package/ios/utils/ENRMMathFallback.h +26 -0
  320. package/ios/utils/ENRMMathFallback.m +18 -0
  321. package/ios/utils/ENRMTextViewSetup.h +35 -17
  322. package/ios/utils/EditMenuUtils.h +22 -5
  323. package/ios/utils/EditMenuUtils.m +53 -9
  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 +53 -0
  338. package/ios/views/ENRMCodeBlockContainerView.m +559 -0
  339. package/ios/views/ENRMMathContainerView.h +16 -0
  340. package/ios/views/ENRMMathContainerView.m +74 -19
  341. package/ios/views/TableContainerView.h +22 -0
  342. package/ios/views/TableContainerView.m +261 -175
  343. package/jest.d.ts +1 -0
  344. package/jest.js +5 -0
  345. package/lib/module/EnrichedMarkdownNativeComponent.ts +73 -0
  346. package/lib/module/EnrichedMarkdownTextInput.js +84 -5
  347. package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
  348. package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  349. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +74 -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 +37 -5
  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 +66 -0
  383. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
  384. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +94 -9
  385. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
  386. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +69 -5
  387. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
  388. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +66 -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 +104 -9
  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 +73 -0
  433. package/src/EnrichedMarkdownTextInput.tsx +159 -8
  434. package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  435. package/src/EnrichedMarkdownTextNativeComponent.ts +74 -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 +53 -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 +101 -9
  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,559 @@
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)setMenuOptions:(ENRMBlockMenuOptions)menuOptions
179
+ {
180
+ _menuOptions = menuOptions;
181
+ // Hiding the button leaves the header (and its height) untouched.
182
+ _copyButton.hidden = menuOptions.copyButtonHidden;
183
+ }
184
+
185
+ - (void)setPending:(BOOL)pending
186
+ {
187
+ if (_pending == pending) {
188
+ return;
189
+ }
190
+ _pending = pending;
191
+ // Header stays visible while streaming; only copying is held back.
192
+ _copyButton.enabled = !pending;
193
+ // The reconciler can reuse an unchanged block without re-applying the node, so
194
+ // re-derive here to pick up highlighting once the block closes.
195
+ [self rebuildAttributedCode];
196
+ #if !TARGET_OS_OSX
197
+ [self setNeedsLayout];
198
+ [self setNeedsDisplay];
199
+ [_codeContentView setNeedsDisplay];
200
+ #else
201
+ self.needsLayout = YES;
202
+ [self setNeedsDisplay:YES];
203
+ [_codeContentView setNeedsDisplay:YES];
204
+ #endif
205
+ }
206
+
207
+ - (instancetype)initWithConfig:(StyleConfig *)config
208
+ {
209
+ self = [super initWithFrame:CGRectZero];
210
+ if (self) {
211
+ _config = config;
212
+ _cachedCode = @"";
213
+ _fenceChar = @"`";
214
+ _headerFont = ENRMCodeBlockHeaderFont(config);
215
+ _headerLabelLineHeight = ENRMCodeBlockHeaderLabelLineHeight(_headerFont);
216
+ self.backgroundColor = [RCTUIColor clearColor];
217
+ [self setupScrollView];
218
+
219
+ #if !TARGET_OS_OSX
220
+ self.contentMode = UIViewContentModeRedraw;
221
+ self.isAccessibilityElement = YES;
222
+
223
+ UIContextMenuInteraction *contextMenu = [[UIContextMenuInteraction alloc] initWithDelegate:self];
224
+ [self addInteraction:contextMenu];
225
+
226
+ _copyButton = [UIButton buttonWithType:UIButtonTypeSystem];
227
+ UIImageSymbolConfiguration *symbolConfig =
228
+ [UIImageSymbolConfiguration configurationWithPointSize:[config codeBlockFont].pointSize * kENRMHeaderIconScale
229
+ weight:UIImageSymbolWeightRegular];
230
+ [_copyButton setImage:[UIImage systemImageNamed:@"doc.on.doc" withConfiguration:symbolConfig]
231
+ forState:UIControlStateNormal];
232
+ _copyButton.tintColor = [[config codeBlockColor] colorWithAlphaComponent:kENRMHeaderSecondaryAlpha];
233
+ [_copyButton addTarget:self action:@selector(copyCodeToPasteboard) forControlEvents:UIControlEventTouchUpInside];
234
+ [self addSubview:_copyButton];
235
+ #else
236
+ NSImageSymbolConfiguration *symbolConfig =
237
+ [NSImageSymbolConfiguration configurationWithPointSize:[config codeBlockFont].pointSize * kENRMHeaderIconScale
238
+ weight:NSFontWeightRegular];
239
+ NSImage *copyImage = [[NSImage imageWithSystemSymbolName:@"doc.on.doc"
240
+ accessibilityDescription:nil] imageWithSymbolConfiguration:symbolConfig];
241
+ _copyButton = [NSButton buttonWithImage:copyImage target:self action:@selector(copyCodeToPasteboard)];
242
+ _copyButton.bordered = NO;
243
+ _copyButton.contentTintColor = [[config codeBlockColor] colorWithAlphaComponent:kENRMHeaderSecondaryAlpha];
244
+ [self addSubview:_copyButton];
245
+ #endif
246
+ }
247
+ return self;
248
+ }
249
+
250
+ - (void)setupScrollView
251
+ {
252
+ _scrollView = [[RCTUIScrollView alloc] init];
253
+ _scrollView.showsVerticalScrollIndicator = NO;
254
+ _scrollView.showsHorizontalScrollIndicator = YES;
255
+ _codeContentView = [[ENRMCodeBlockContentView alloc] initWithFrame:CGRectZero];
256
+ BOOL darkBackground = ENRMColorIsDark([_config codeBlockBackgroundColor]);
257
+ #if !TARGET_OS_OSX
258
+ _scrollView.bounces = YES;
259
+ _scrollView.alwaysBounceHorizontal = NO;
260
+ _scrollView.backgroundColor = [UIColor clearColor];
261
+ _scrollView.isAccessibilityElement = NO;
262
+ _scrollView.accessibilityElementsHidden = YES;
263
+ _scrollView.indicatorStyle = darkBackground ? UIScrollViewIndicatorStyleWhite : UIScrollViewIndicatorStyleDefault;
264
+ _codeContentView.backgroundColor = [UIColor clearColor];
265
+ _codeContentView.contentMode = UIViewContentModeRedraw;
266
+ [_scrollView addSubview:_codeContentView];
267
+ [_codeContentView addInteraction:[[UIContextMenuInteraction alloc] initWithDelegate:self]];
268
+ #else
269
+ ((NSScrollView *)_scrollView).drawsBackground = NO;
270
+ ((NSScrollView *)_scrollView).scrollerKnobStyle =
271
+ darkBackground ? NSScrollerKnobStyleLight : NSScrollerKnobStyleDefault;
272
+ __weak ENRMCodeBlockContainerView *weakSelf = self;
273
+ NSMenu * (^menuProvider)(void) = ^{ return [weakSelf buildContextMenu]; };
274
+ _codeContentView.menuProvider = menuProvider;
275
+ [(NSScrollView *)_scrollView setDocumentView:_codeContentView];
276
+ #endif
277
+ [self addSubview:_scrollView];
278
+ }
279
+
280
+ - (void)layoutScrollArea
281
+ {
282
+ CGFloat borderW = ceil([_config codeBlockBorderWidth]);
283
+ CGFloat headerH = [self headerHeight];
284
+ CGFloat inset = [self contentInset];
285
+ CGRect frame = CGRectMake(borderW, headerH, MAX(self.bounds.size.width - borderW * 2, 0),
286
+ MAX(self.bounds.size.height - headerH - borderW, 0));
287
+ _scrollView.frame = frame;
288
+
289
+ CGFloat horizontalPad = MAX(inset - borderW, 0);
290
+ CGFloat contentWidth = MAX(_codeSize.width + horizontalPad * 2, frame.size.width);
291
+ _codeContentView.textOrigin = CGPointMake(horizontalPad, inset);
292
+ _codeContentView.frame = CGRectMake(0, 0, contentWidth, frame.size.height);
293
+ #if !TARGET_OS_OSX
294
+ _scrollView.contentSize = CGSizeMake(contentWidth, frame.size.height);
295
+ _scrollView.scrollEnabled = contentWidth > frame.size.width;
296
+ #endif
297
+ }
298
+
299
+ // Header is the top content inset plus one label line; the code text's own
300
+ // top inset then forms the single gap below the label.
301
+ - (CGFloat)headerHeight
302
+ {
303
+ return [self contentInset] + _headerLabelLineHeight;
304
+ }
305
+
306
+ - (void)layoutHeaderButton
307
+ {
308
+ CGFloat headerH = [self headerHeight];
309
+ CGFloat iconWidth = _copyButton.intrinsicContentSize.width;
310
+ if (iconWidth <= 0 || iconWidth > headerH) {
311
+ iconWidth = headerH;
312
+ }
313
+ CGFloat iconSlack = (headerH - iconWidth) / 2;
314
+ CGFloat buttonLeft = MAX(self.bounds.size.width - [self contentInset] - headerH + iconSlack, 0);
315
+ CGFloat labelCenterY = headerH - _headerLabelLineHeight / 2;
316
+ CGFloat buttonTop = MAX(labelCenterY - headerH / 2, 0);
317
+ _copyButton.frame = CGRectMake(buttonLeft, buttonTop, headerH, headerH);
318
+ }
319
+
320
+ #if !TARGET_OS_OSX
321
+ - (void)layoutSubviews
322
+ {
323
+ [super layoutSubviews];
324
+ [self layoutHeaderButton];
325
+ [self layoutScrollArea];
326
+ }
327
+ #else
328
+ - (void)layout
329
+ {
330
+ [super layout];
331
+ [self layoutHeaderButton];
332
+ [self layoutScrollArea];
333
+ }
334
+ #endif
335
+
336
+ #if TARGET_OS_OSX
337
+ - (BOOL)isFlipped
338
+ {
339
+ return YES;
340
+ }
341
+
342
+ - (void)setFrameSize:(NSSize)newSize
343
+ {
344
+ [super setFrameSize:newSize];
345
+ [self setNeedsDisplay:YES];
346
+ }
347
+ #endif
348
+
349
+ // Highlighting is deferred while pending, applied once the block closes.
350
+ - (void)rebuildAttributedCode
351
+ {
352
+ NSAttributedString *plainCode = [self plainAttributedCode];
353
+ NSAttributedString *highlighted =
354
+ _pending ? nil : ENRMHighlightedAttributedCode(plainCode, _cachedCode, _cachedLanguage, _config);
355
+ _attributedCode = highlighted ?: plainCode;
356
+ _codeSize = ENRMCodeBlockCodeSize(_attributedCode);
357
+ _codeContentView.attributedCode = _attributedCode;
358
+ }
359
+
360
+ - (void)applyCodeBlockNode:(MarkdownASTNode *)node
361
+ {
362
+ _cachedCode = ENRMCodeBlockExtractCode(node);
363
+ _fenceChar = ENRMCodeBlockFenceChar(node);
364
+
365
+ NSString *newLanguage = ENRMCodeBlockLanguage(node);
366
+ BOOL languageChanged = newLanguage != _cachedLanguage && ![newLanguage isEqualToString:_cachedLanguage];
367
+ if (languageChanged) {
368
+ _cachedLanguage = newLanguage;
369
+ _displayLanguage = ENRMCodeBlockDisplayLanguageName(newLanguage);
370
+ [self rebuildLanguageLabel];
371
+ }
372
+
373
+ [self rebuildAttributedCode];
374
+
375
+ #if !TARGET_OS_OSX
376
+ [self setNeedsLayout];
377
+ [self setNeedsDisplay];
378
+ [_codeContentView setNeedsDisplay];
379
+ #else
380
+ self.needsLayout = YES;
381
+ [self setNeedsDisplay:YES];
382
+ [_codeContentView setNeedsDisplay:YES];
383
+ #endif
384
+ }
385
+
386
+ - (void)rebuildLanguageLabel
387
+ {
388
+ if (_displayLanguage.length == 0) {
389
+ _languageLabel = nil;
390
+ _languageLabelSize = CGSizeZero;
391
+ return;
392
+ }
393
+ NSMutableDictionary *labelAttributes = [NSMutableDictionary dictionary];
394
+ labelAttributes[NSFontAttributeName] = _headerFont;
395
+ RCTUIColor *labelColor = [[_config codeBlockColor] colorWithAlphaComponent:kENRMHeaderSecondaryAlpha];
396
+ if (labelColor) {
397
+ labelAttributes[NSForegroundColorAttributeName] = labelColor;
398
+ }
399
+ _languageLabel = [[NSAttributedString alloc] initWithString:_displayLanguage attributes:labelAttributes];
400
+ _languageLabelSize = _languageLabel.size;
401
+ }
402
+
403
+ - (NSAttributedString *)plainAttributedCode
404
+ {
405
+ return ENRMCodeBlockPlainAttributedCode(_cachedCode, _config);
406
+ }
407
+
408
+ - (CGFloat)contentInset
409
+ {
410
+ return ENRMCodeBlockContentInset(_config);
411
+ }
412
+
413
+ - (CGFloat)measureHeight:(CGFloat)maxWidth
414
+ {
415
+ CGFloat inset = [self contentInset];
416
+ return _codeSize.height + inset * 2 + [self headerHeight];
417
+ }
418
+
419
+ + (CGFloat)measureHeightForCodeBlockNode:(MarkdownASTNode *)node config:(StyleConfig *)config
420
+ {
421
+ CGFloat inset = ENRMCodeBlockContentInset(config);
422
+ CGFloat headerH = inset + ENRMCodeBlockHeaderLabelLineHeight(ENRMCodeBlockHeaderFont(config));
423
+ NSAttributedString *code = ENRMCodeBlockPlainAttributedCode(ENRMCodeBlockExtractCode(node), config);
424
+ return ENRMCodeBlockCodeSize(code).height + inset * 2 + headerH;
425
+ }
426
+
427
+ - (void)drawRect:(CGRect)rect
428
+ {
429
+ CGFloat borderWidth = [_config codeBlockBorderWidth];
430
+ CGFloat radius = [_config codeBlockBorderRadius];
431
+ CGRect borderRect = CGRectInset(self.bounds, borderWidth / 2, borderWidth / 2);
432
+
433
+ #if !TARGET_OS_OSX
434
+ UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:borderRect cornerRadius:radius];
435
+ #else
436
+ NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:borderRect xRadius:radius yRadius:radius];
437
+ #endif
438
+
439
+ RCTUIColor *backgroundColor = [_config codeBlockBackgroundColor];
440
+ if (backgroundColor) {
441
+ [backgroundColor setFill];
442
+ [path fill];
443
+ }
444
+ if (borderWidth > 0) {
445
+ RCTUIColor *borderColor = [_config codeBlockBorderColor];
446
+ if (borderColor) {
447
+ path.lineWidth = borderWidth;
448
+ [borderColor setStroke];
449
+ [path stroke];
450
+ }
451
+ }
452
+
453
+ CGFloat inset = [self contentInset];
454
+ CGFloat headerH = [self headerHeight];
455
+
456
+ // Divider between the header and the code, centered in the gap the code
457
+ // text's top inset creates, so it adds no height of its own.
458
+ RCTUIColor *dividerColor = [[_config codeBlockColor] colorWithAlphaComponent:kENRMHeaderDividerAlpha];
459
+ if (dividerColor) {
460
+ CGRect dividerRect = CGRectMake(borderWidth, headerH + inset / 2, self.bounds.size.width - borderWidth * 2, 1);
461
+ [dividerColor setFill];
462
+ #if !TARGET_OS_OSX
463
+ [[UIBezierPath bezierPathWithRect:dividerRect] fill];
464
+ #else
465
+ [[NSBezierPath bezierPathWithRect:dividerRect] fill];
466
+ #endif
467
+ }
468
+
469
+ if (_languageLabel.length > 0) {
470
+ [_languageLabel drawAtPoint:CGPointMake(inset, headerH - _languageLabelSize.height)];
471
+ }
472
+ }
473
+
474
+ - (NSString *)fencedMarkdown
475
+ {
476
+ return ENRMCodeBlockFencedMarkdown(_cachedCode, _cachedLanguage, _fenceChar);
477
+ }
478
+
479
+ - (void)copyCodeToPasteboard
480
+ {
481
+ copyStringToPasteboard(_cachedCode);
482
+ if (self.onCopyPress) {
483
+ self.onCopyPress(_cachedCode ?: @"", _cachedLanguage ?: @"");
484
+ }
485
+ }
486
+
487
+ - (void)copyMarkdownToPasteboard
488
+ {
489
+ copyStringToPasteboard([self fencedMarkdown]);
490
+ }
491
+
492
+ #if !TARGET_OS_OSX
493
+ - (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction
494
+ configurationForMenuAtLocation:(CGPoint)location
495
+ {
496
+ // Returning nil is the UIKit-sanctioned way to suppress a context menu.
497
+ if (_pending || self.contextMenuHidden) {
498
+ return nil;
499
+ }
500
+ __weak __typeof(self) weakSelf = self;
501
+ return ENRMBlockContextMenuConfiguration(
502
+ self.menuOptions, self.copyLabel, self.copyAsMarkdownLabel, ^{ [weakSelf copyCodeToPasteboard]; },
503
+ ^{ [weakSelf copyMarkdownToPasteboard]; });
504
+ }
505
+ #endif
506
+
507
+ #if TARGET_OS_OSX
508
+ - (NSMenu *)buildContextMenu
509
+ {
510
+ // Both menuForEvent: paths return this directly, so nil fully suppresses the
511
+ // menu rather than restoring the AppKit default.
512
+ if (_pending || self.contextMenuHidden) {
513
+ return nil;
514
+ }
515
+ NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
516
+ [menu addItem:ENRMCreateMenuItem(self.copyLabel, ^{ [self copyCodeToPasteboard]; })];
517
+ [menu addItem:ENRMCreateMenuItem(self.copyAsMarkdownLabel, ^{ [self copyMarkdownToPasteboard]; })];
518
+ return menu;
519
+ }
520
+
521
+ - (NSMenu *)menuForEvent:(NSEvent *)event
522
+ {
523
+ return [self buildContextMenu];
524
+ }
525
+ #endif
526
+
527
+ - (NSString *)accessibilityLabel
528
+ {
529
+ return _cachedCode;
530
+ }
531
+
532
+ #if !TARGET_OS_OSX
533
+ - (UIAccessibilityTraits)accessibilityTraits
534
+ {
535
+ return UIAccessibilityTraitStaticText;
536
+ }
537
+
538
+ // The container is a single accessibility element, which hides the copy
539
+ // button subview from VoiceOver; expose the copy action explicitly instead.
540
+ - (NSArray<UIAccessibilityCustomAction *> *)accessibilityCustomActions
541
+ {
542
+ if (_pending || self.menuOptions.copyHidden || self.copyLabel.length == 0) {
543
+ return @[];
544
+ }
545
+ UIAccessibilityCustomAction *copyAction =
546
+ [[UIAccessibilityCustomAction alloc] initWithName:self.copyLabel
547
+ target:self
548
+ selector:@selector(performCopyAccessibilityAction:)];
549
+ return @[ copyAction ];
550
+ }
551
+
552
+ - (BOOL)performCopyAccessibilityAction:(UIAccessibilityCustomAction *)action
553
+ {
554
+ [self copyCodeToPasteboard];
555
+ return YES;
556
+ }
557
+ #endif
558
+
559
+ @end
@@ -1,4 +1,5 @@
1
1
  #pragma once
2
+ #import "ENRMBlockMenu.h"
2
3
  #import "ENRMUIKit.h"
3
4
  #import "StyleConfig.h"
4
5
 
@@ -14,6 +15,14 @@ NS_ASSUME_NONNULL_BEGIN
14
15
 
15
16
  - (CGFloat)measureHeight:(CGFloat)maxWidth;
16
17
 
18
+ /// View-free math-block height for shadow-node measurement (issue #550):
19
+ /// parses the LaTeX through the same RaTeX bridge `applyLatex:` uses and
20
+ /// applies the same padding math as `measureHeight:` — including the wrapped
21
+ /// source-fallback path when RaTeX cannot parse — without creating any view.
22
+ /// Runs on the calling thread. Like every member of this class, only
23
+ /// implemented when ENRICHED_MARKDOWN_MATH is on — guard call sites.
24
+ + (CGFloat)measureHeightForLatex:(NSString *)latex config:(StyleConfig *)config maxWidth:(CGFloat)maxWidth;
25
+
17
26
  @property (nonatomic, strong) StyleConfig *config;
18
27
  @property (nonatomic, copy, readonly) NSString *cachedLatex;
19
28
  @property (nonatomic, strong, nullable) ENRMAccessibilityLabels *accessibilityLabels;
@@ -23,6 +32,13 @@ NS_ASSUME_NONNULL_BEGIN
23
32
  @property (nonatomic, copy, nullable, getter=menuCopyLabel) NSString *copyLabel;
24
33
  @property (nonatomic, copy, nullable, getter=menuCopyAsMarkdownLabel) NSString *copyAsMarkdownLabel;
25
34
 
35
+ /// Suppresses the long-press copy menu on this block. Mirrors the
36
+ /// `contextMenuHidden` prop; selection and link handling are unaffected.
37
+ @property (nonatomic, assign) BOOL contextMenuHidden;
38
+
39
+ /// Copy / Copy as Markdown visibility and Copy format from `selectionMenuConfig`.
40
+ @property (nonatomic, assign) ENRMBlockMenuOptions menuOptions;
41
+
26
42
  @end
27
43
 
28
44
  NS_ASSUME_NONNULL_END