@fendent/react-native-enriched 0.5.2-fork.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 (278) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +343 -0
  3. package/ReactNativeEnriched.podspec +31 -0
  4. package/android/build.gradle +106 -0
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +197 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +72 -0
  7. package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/ComponentDescriptors.cpp +22 -0
  8. package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/ComponentDescriptors.h +24 -0
  9. package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/EventEmitters.cpp +434 -0
  10. package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/EventEmitters.h +391 -0
  11. package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/Props.cpp +173 -0
  12. package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/Props.h +833 -0
  13. package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/ShadowNodes.cpp +17 -0
  14. package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/ShadowNodes.h +23 -0
  15. package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/States.cpp +16 -0
  16. package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/States.h +20 -0
  17. package/android/gradle.properties +5 -0
  18. package/android/lint.gradle +70 -0
  19. package/android/src/main/AndroidManifest.xml +3 -0
  20. package/android/src/main/AndroidManifestNew.xml +2 -0
  21. package/android/src/main/java/com/swmansion/enriched/ReactNativeEnrichedPackage.kt +20 -0
  22. package/android/src/main/java/com/swmansion/enriched/common/AsyncDrawable.kt +126 -0
  23. package/android/src/main/java/com/swmansion/enriched/common/CheckboxDrawable.kt +81 -0
  24. package/android/src/main/java/com/swmansion/enriched/common/EnrichedConstants.kt +11 -0
  25. package/android/src/main/java/com/swmansion/enriched/common/EnrichedStyle.kt +57 -0
  26. package/android/src/main/java/com/swmansion/enriched/common/ForceRedrawSpan.kt +14 -0
  27. package/android/src/main/java/com/swmansion/enriched/common/GumboNormalizer.kt +5 -0
  28. package/android/src/main/java/com/swmansion/enriched/common/MentionStyle.kt +7 -0
  29. package/android/src/main/java/com/swmansion/enriched/common/ResourceManager.kt +26 -0
  30. package/android/src/main/java/com/swmansion/enriched/common/parser/EnrichedParser.java +956 -0
  31. package/android/src/main/java/com/swmansion/enriched/common/parser/EnrichedSpanFactory.kt +79 -0
  32. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedBlockQuoteSpan.kt +53 -0
  33. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedBoldSpan.kt +12 -0
  34. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedCheckboxListSpan.kt +92 -0
  35. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedCodeBlockSpan.kt +81 -0
  36. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH1Span.kt +20 -0
  37. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH2Span.kt +20 -0
  38. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH3Span.kt +20 -0
  39. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH4Span.kt +21 -0
  40. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH5Span.kt +20 -0
  41. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH6Span.kt +20 -0
  42. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedImageSpan.kt +184 -0
  43. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedInlineCodeSpan.kt +24 -0
  44. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedItalicSpan.kt +12 -0
  45. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedLinkSpan.kt +29 -0
  46. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedMentionSpan.kt +35 -0
  47. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedOrderedListSpan.kt +79 -0
  48. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedStrikeThroughSpan.kt +11 -0
  49. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedUnderlineSpan.kt +11 -0
  50. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedUnorderedListSpan.kt +62 -0
  51. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedBlockSpan.kt +5 -0
  52. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedHeadingSpan.kt +3 -0
  53. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedInlineSpan.kt +3 -0
  54. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedParagraphSpan.kt +5 -0
  55. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedSpan.kt +3 -0
  56. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedZeroWidthSpaceSpan.kt +4 -0
  57. package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputConnectionWrapper.kt +140 -0
  58. package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputSpannableFactory.kt +83 -0
  59. package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputView.kt +1120 -0
  60. package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputViewLayoutManager.kt +27 -0
  61. package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputViewManager.kt +478 -0
  62. package/android/src/main/java/com/swmansion/enriched/textinput/MeasurementStore.kt +225 -0
  63. package/android/src/main/java/com/swmansion/enriched/textinput/events/MentionHandler.kt +55 -0
  64. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnChangeHtmlEvent.kt +27 -0
  65. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnChangeSelectionEvent.kt +30 -0
  66. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnChangeStateEvent.kt +21 -0
  67. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnChangeTextEvent.kt +30 -0
  68. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnContextMenuItemPressEvent.kt +35 -0
  69. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnInputBlurEvent.kt +25 -0
  70. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnInputFocusEvent.kt +25 -0
  71. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnInputKeyPressEvent.kt +27 -0
  72. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnLinkDetectedEvent.kt +32 -0
  73. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnMentionDetectedEvent.kt +30 -0
  74. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnMentionEvent.kt +34 -0
  75. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnPasteImagesEvent.kt +47 -0
  76. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnRequestHtmlResultEvent.kt +32 -0
  77. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnSubmitEditingEvent.kt +29 -0
  78. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputBlockQuoteSpan.kt +14 -0
  79. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputBoldSpan.kt +14 -0
  80. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputCheckboxListSpan.kt +15 -0
  81. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputCodeBlockSpan.kt +14 -0
  82. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH1Span.kt +14 -0
  83. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH2Span.kt +14 -0
  84. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH3Span.kt +14 -0
  85. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH4Span.kt +14 -0
  86. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH5Span.kt +14 -0
  87. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH6Span.kt +14 -0
  88. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputImageSpan.kt +36 -0
  89. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputInlineCodeSpan.kt +14 -0
  90. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputItalicSpan.kt +14 -0
  91. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputLinkSpan.kt +16 -0
  92. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputMentionSpan.kt +18 -0
  93. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputOrderedListSpan.kt +21 -0
  94. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputStrikeThroughSpan.kt +14 -0
  95. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputUnderlineSpan.kt +14 -0
  96. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputUnorderedListSpan.kt +14 -0
  97. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedLineHeightSpan.kt +44 -0
  98. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedSpans.kt +241 -0
  99. package/android/src/main/java/com/swmansion/enriched/textinput/spans/interfaces/EnrichedInputSpan.kt +10 -0
  100. package/android/src/main/java/com/swmansion/enriched/textinput/styles/HtmlStyle.kt +372 -0
  101. package/android/src/main/java/com/swmansion/enriched/textinput/styles/InlineStyles.kt +164 -0
  102. package/android/src/main/java/com/swmansion/enriched/textinput/styles/ListStyles.kt +263 -0
  103. package/android/src/main/java/com/swmansion/enriched/textinput/styles/ParagraphStyles.kt +434 -0
  104. package/android/src/main/java/com/swmansion/enriched/textinput/styles/ParametrizedStyles.kt +394 -0
  105. package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedEditableFactory.kt +17 -0
  106. package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedSelection.kt +320 -0
  107. package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedSpanState.kt +310 -0
  108. package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedSpannable.kt +106 -0
  109. package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedSpannableStringBuilder.kt +24 -0
  110. package/android/src/main/java/com/swmansion/enriched/textinput/utils/RichContentReceiver.kt +127 -0
  111. package/android/src/main/java/com/swmansion/enriched/textinput/utils/Utils.kt +106 -0
  112. package/android/src/main/java/com/swmansion/enriched/textinput/watchers/EnrichedSpanWatcher.kt +107 -0
  113. package/android/src/main/java/com/swmansion/enriched/textinput/watchers/EnrichedTextWatcher.kt +74 -0
  114. package/android/src/main/new_arch/CMakeLists.txt +62 -0
  115. package/android/src/main/new_arch/GumboNormalizerJni.cpp +14 -0
  116. package/android/src/main/new_arch/ReactNativeEnrichedSpec.cpp +11 -0
  117. package/android/src/main/new_arch/ReactNativeEnrichedSpec.h +15 -0
  118. package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputComponentDescriptor.h +35 -0
  119. package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputMeasurementManager.cpp +53 -0
  120. package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputMeasurementManager.h +25 -0
  121. package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputShadowNode.cpp +35 -0
  122. package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputShadowNode.h +53 -0
  123. package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputState.cpp +9 -0
  124. package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputState.h +24 -0
  125. package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/conversions.h +27 -0
  126. package/android/src/main/res/drawable/broken_image.xml +10 -0
  127. package/cpp/CMakeLists.txt +50 -0
  128. package/cpp/GumboParser/GumboParser.h +34043 -0
  129. package/cpp/README.md +59 -0
  130. package/cpp/parser/GumboNormalizer.c +915 -0
  131. package/cpp/parser/GumboParser.cpp +16 -0
  132. package/cpp/parser/GumboParser.hpp +23 -0
  133. package/cpp/tests/GumboParserTest.cpp +457 -0
  134. package/ios/EnrichedTextInputView.h +53 -0
  135. package/ios/EnrichedTextInputView.mm +2360 -0
  136. package/ios/EnrichedTextInputViewManager.mm +13 -0
  137. package/ios/attributesManager/AttributesManager.h +17 -0
  138. package/ios/attributesManager/AttributesManager.mm +195 -0
  139. package/ios/config/InputConfig.h +104 -0
  140. package/ios/config/InputConfig.mm +664 -0
  141. package/ios/extensions/ColorExtension.h +7 -0
  142. package/ios/extensions/ColorExtension.mm +38 -0
  143. package/ios/extensions/FontExtension.h +11 -0
  144. package/ios/extensions/FontExtension.mm +72 -0
  145. package/ios/extensions/ImageExtension.h +34 -0
  146. package/ios/extensions/ImageExtension.mm +165 -0
  147. package/ios/extensions/LayoutManagerExtension.h +6 -0
  148. package/ios/extensions/LayoutManagerExtension.mm +443 -0
  149. package/ios/extensions/StringExtension.h +15 -0
  150. package/ios/extensions/StringExtension.mm +69 -0
  151. package/ios/generated/ReactNativeEnrichedSpec/ComponentDescriptors.cpp +22 -0
  152. package/ios/generated/ReactNativeEnrichedSpec/ComponentDescriptors.h +24 -0
  153. package/ios/generated/ReactNativeEnrichedSpec/EventEmitters.cpp +434 -0
  154. package/ios/generated/ReactNativeEnrichedSpec/EventEmitters.h +391 -0
  155. package/ios/generated/ReactNativeEnrichedSpec/Props.cpp +173 -0
  156. package/ios/generated/ReactNativeEnrichedSpec/Props.h +833 -0
  157. package/ios/generated/ReactNativeEnrichedSpec/RCTComponentViewHelpers.h +582 -0
  158. package/ios/generated/ReactNativeEnrichedSpec/ShadowNodes.cpp +17 -0
  159. package/ios/generated/ReactNativeEnrichedSpec/ShadowNodes.h +23 -0
  160. package/ios/generated/ReactNativeEnrichedSpec/States.cpp +16 -0
  161. package/ios/generated/ReactNativeEnrichedSpec/States.h +20 -0
  162. package/ios/inputParser/InputParser.h +11 -0
  163. package/ios/inputParser/InputParser.mm +1463 -0
  164. package/ios/inputTextView/InputTextView.h +6 -0
  165. package/ios/inputTextView/InputTextView.mm +285 -0
  166. package/ios/interfaces/AttributeEntry.h +9 -0
  167. package/ios/interfaces/AttributeEntry.mm +4 -0
  168. package/ios/interfaces/BaseStyleProtocol.h +17 -0
  169. package/ios/interfaces/ImageAttachment.h +11 -0
  170. package/ios/interfaces/ImageAttachment.mm +107 -0
  171. package/ios/interfaces/ImageData.h +10 -0
  172. package/ios/interfaces/ImageData.mm +4 -0
  173. package/ios/interfaces/LinkData.h +11 -0
  174. package/ios/interfaces/LinkData.mm +29 -0
  175. package/ios/interfaces/LinkRegexConfig.h +19 -0
  176. package/ios/interfaces/LinkRegexConfig.mm +37 -0
  177. package/ios/interfaces/MediaAttachment.h +23 -0
  178. package/ios/interfaces/MediaAttachment.mm +31 -0
  179. package/ios/interfaces/MentionParams.h +8 -0
  180. package/ios/interfaces/MentionParams.mm +4 -0
  181. package/ios/interfaces/MentionStyleProps.h +13 -0
  182. package/ios/interfaces/MentionStyleProps.mm +63 -0
  183. package/ios/interfaces/StyleBase.h +36 -0
  184. package/ios/interfaces/StyleBase.mm +256 -0
  185. package/ios/interfaces/StyleHeaders.h +102 -0
  186. package/ios/interfaces/StylePair.h +9 -0
  187. package/ios/interfaces/StylePair.mm +4 -0
  188. package/ios/interfaces/StyleTypeEnum.h +26 -0
  189. package/ios/interfaces/TextDecorationLineEnum.h +6 -0
  190. package/ios/interfaces/TextDecorationLineEnum.mm +4 -0
  191. package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +19 -0
  192. package/ios/internals/EnrichedTextInputViewShadowNode.h +44 -0
  193. package/ios/internals/EnrichedTextInputViewShadowNode.mm +103 -0
  194. package/ios/internals/EnrichedTextInputViewState.cpp +10 -0
  195. package/ios/internals/EnrichedTextInputViewState.h +22 -0
  196. package/ios/styles/BlockQuoteStyle.mm +55 -0
  197. package/ios/styles/BoldStyle.mm +37 -0
  198. package/ios/styles/CheckboxListStyle.mm +153 -0
  199. package/ios/styles/CodeBlockStyle.mm +49 -0
  200. package/ios/styles/H1Style.mm +20 -0
  201. package/ios/styles/H2Style.mm +20 -0
  202. package/ios/styles/H3Style.mm +20 -0
  203. package/ios/styles/H4Style.mm +20 -0
  204. package/ios/styles/H5Style.mm +20 -0
  205. package/ios/styles/H6Style.mm +20 -0
  206. package/ios/styles/HeadingStyleBase.mm +65 -0
  207. package/ios/styles/ImageStyle.mm +146 -0
  208. package/ios/styles/InlineCodeStyle.mm +65 -0
  209. package/ios/styles/ItalicStyle.mm +37 -0
  210. package/ios/styles/LinkStyle.mm +532 -0
  211. package/ios/styles/MentionStyle.mm +538 -0
  212. package/ios/styles/OrderedListStyle.mm +86 -0
  213. package/ios/styles/StrikethroughStyle.mm +25 -0
  214. package/ios/styles/UnderlineStyle.mm +24 -0
  215. package/ios/styles/UnorderedListStyle.mm +86 -0
  216. package/ios/utils/CheckboxHitTestUtils.h +10 -0
  217. package/ios/utils/CheckboxHitTestUtils.mm +122 -0
  218. package/ios/utils/DotReplacementUtils.h +10 -0
  219. package/ios/utils/DotReplacementUtils.mm +68 -0
  220. package/ios/utils/KeyboardUtils.h +7 -0
  221. package/ios/utils/KeyboardUtils.mm +31 -0
  222. package/ios/utils/OccurenceUtils.h +44 -0
  223. package/ios/utils/OccurenceUtils.mm +179 -0
  224. package/ios/utils/ParagraphAttributesUtils.h +15 -0
  225. package/ios/utils/ParagraphAttributesUtils.mm +257 -0
  226. package/ios/utils/RangeUtils.h +12 -0
  227. package/ios/utils/RangeUtils.mm +183 -0
  228. package/ios/utils/TextBlockTapGestureRecognizer.h +17 -0
  229. package/ios/utils/TextBlockTapGestureRecognizer.mm +56 -0
  230. package/ios/utils/TextInsertionUtils.h +17 -0
  231. package/ios/utils/TextInsertionUtils.mm +64 -0
  232. package/ios/utils/WordsUtils.h +7 -0
  233. package/ios/utils/WordsUtils.mm +98 -0
  234. package/ios/utils/ZeroWidthSpaceUtils.h +9 -0
  235. package/ios/utils/ZeroWidthSpaceUtils.mm +270 -0
  236. package/lib/module/index.js +4 -0
  237. package/lib/module/index.js.map +1 -0
  238. package/lib/module/native/EnrichedTextInput.js +304 -0
  239. package/lib/module/native/EnrichedTextInput.js.map +1 -0
  240. package/lib/module/package.json +1 -0
  241. package/lib/module/spec/EnrichedTextInputNativeComponent.ts +517 -0
  242. package/lib/module/types.js +4 -0
  243. package/lib/module/types.js.map +1 -0
  244. package/lib/module/utils/EnrichedTextInputDefaultProps.js +12 -0
  245. package/lib/module/utils/EnrichedTextInputDefaultProps.js.map +1 -0
  246. package/lib/module/utils/normalizeHtmlStyle.js +155 -0
  247. package/lib/module/utils/normalizeHtmlStyle.js.map +1 -0
  248. package/lib/module/utils/nullthrows.js +9 -0
  249. package/lib/module/utils/nullthrows.js.map +1 -0
  250. package/lib/module/utils/regexParser.js +46 -0
  251. package/lib/module/utils/regexParser.js.map +1 -0
  252. package/lib/typescript/package.json +1 -0
  253. package/lib/typescript/src/index.d.ts +3 -0
  254. package/lib/typescript/src/index.d.ts.map +1 -0
  255. package/lib/typescript/src/native/EnrichedTextInput.d.ts +3 -0
  256. package/lib/typescript/src/native/EnrichedTextInput.d.ts.map +1 -0
  257. package/lib/typescript/src/spec/EnrichedTextInputNativeComponent.d.ts +397 -0
  258. package/lib/typescript/src/spec/EnrichedTextInputNativeComponent.d.ts.map +1 -0
  259. package/lib/typescript/src/types.d.ts +447 -0
  260. package/lib/typescript/src/types.d.ts.map +1 -0
  261. package/lib/typescript/src/utils/EnrichedTextInputDefaultProps.d.ts +10 -0
  262. package/lib/typescript/src/utils/EnrichedTextInputDefaultProps.d.ts.map +1 -0
  263. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts +4 -0
  264. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts.map +1 -0
  265. package/lib/typescript/src/utils/nullthrows.d.ts +2 -0
  266. package/lib/typescript/src/utils/nullthrows.d.ts.map +1 -0
  267. package/lib/typescript/src/utils/regexParser.d.ts +3 -0
  268. package/lib/typescript/src/utils/regexParser.d.ts.map +1 -0
  269. package/package.json +226 -0
  270. package/react-native.config.js +13 -0
  271. package/src/index.tsx +20 -0
  272. package/src/native/EnrichedTextInput.tsx +370 -0
  273. package/src/spec/EnrichedTextInputNativeComponent.ts +517 -0
  274. package/src/types.ts +499 -0
  275. package/src/utils/EnrichedTextInputDefaultProps.ts +9 -0
  276. package/src/utils/normalizeHtmlStyle.ts +199 -0
  277. package/src/utils/nullthrows.ts +7 -0
  278. package/src/utils/regexParser.ts +56 -0
@@ -0,0 +1,106 @@
1
+ package com.swmansion.enriched.textinput.utils
2
+
3
+ import android.text.Spannable
4
+ import android.text.SpannableString
5
+ import android.text.SpannableStringBuilder
6
+ import com.swmansion.enriched.common.spans.interfaces.EnrichedBlockSpan
7
+ import com.swmansion.enriched.common.spans.interfaces.EnrichedParagraphSpan
8
+
9
+ fun Spannable.getSafeSpanBoundaries(
10
+ start: Int,
11
+ end: Int,
12
+ ): Pair<Int, Int> {
13
+ val safeStart = start.coerceAtMost(end).coerceAtLeast(0)
14
+ val safeEnd = end.coerceAtLeast(start).coerceAtMost(this.length)
15
+
16
+ return Pair(safeStart, safeEnd)
17
+ }
18
+
19
+ fun Spannable.getParagraphBounds(
20
+ start: Int,
21
+ end: Int,
22
+ ): Pair<Int, Int> {
23
+ var startPosition = start.coerceAtLeast(0).coerceAtMost(this.length)
24
+ var endPosition = end.coerceAtLeast(0).coerceAtMost(this.length)
25
+
26
+ // Find the start of the paragraph
27
+ while (startPosition > 0 && this[startPosition - 1] != '\n') {
28
+ startPosition--
29
+ }
30
+
31
+ // Find the end of the paragraph
32
+ while (endPosition < this.length && this[endPosition] != '\n') {
33
+ endPosition++
34
+ }
35
+
36
+ if (startPosition >= endPosition) {
37
+ // If the start position is equal or greater than the end position, return the same position
38
+ startPosition = endPosition
39
+ }
40
+
41
+ return Pair(startPosition, endPosition)
42
+ }
43
+
44
+ fun Spannable.getParagraphBounds(index: Int): Pair<Int, Int> = this.getParagraphBounds(index, index)
45
+
46
+ fun Spannable.mergeSpannables(
47
+ start: Int,
48
+ end: Int,
49
+ string: String,
50
+ ): Spannable = this.mergeSpannables(start, end, SpannableString(string))
51
+
52
+ fun Spannable.mergeSpannables(
53
+ start: Int,
54
+ end: Int,
55
+ spannable: Spannable,
56
+ ): Spannable {
57
+ var finalStart = start
58
+ var finalEnd = end
59
+
60
+ val builder = SpannableStringBuilder(this)
61
+ val startBlockSpans = spannable.getSpans(0, 0, EnrichedBlockSpan::class.java)
62
+ val startParagraphSpans = spannable.getSpans(0, 0, EnrichedParagraphSpan::class.java)
63
+ val endBlockSpans = spannable.getSpans(this.length, this.length, EnrichedBlockSpan::class.java)
64
+ val endParagraphSpans = spannable.getSpans(this.length, this.length, EnrichedParagraphSpan::class.java)
65
+ val (paragraphStart, paragraphEnd) = this.getParagraphBounds(start, end)
66
+ val isNewLineStart = startBlockSpans.isNotEmpty() || startParagraphSpans.isNotEmpty()
67
+ val isNewLineEnd = endBlockSpans.isNotEmpty() || endParagraphSpans.isNotEmpty()
68
+
69
+ val pastedHasOwnStyles =
70
+ spannable.getSpans(0, spannable.length, EnrichedBlockSpan::class.java).isNotEmpty() ||
71
+ spannable.getSpans(0, spannable.length, EnrichedParagraphSpan::class.java).isNotEmpty()
72
+
73
+ if (isNewLineStart && start != paragraphStart) {
74
+ builder.insert(start, "\n")
75
+ finalStart = start + 1
76
+ finalEnd = end + 1
77
+ }
78
+
79
+ if (isNewLineEnd && end != paragraphEnd) {
80
+ builder.insert(finalEnd, "\n")
81
+ }
82
+
83
+ builder.replace(finalStart, finalEnd, spannable)
84
+
85
+ // Manually extend existing paragraph/block spans to cover the pasted text.
86
+ if (!pastedHasOwnStyles) {
87
+ val pasteEnd = finalStart + spannable.length
88
+
89
+ val affectedParagraphSpans = builder.getSpans(finalStart, finalStart, EnrichedParagraphSpan::class.java)
90
+ val affectedBlockSpans = builder.getSpans(finalStart, finalStart, EnrichedBlockSpan::class.java)
91
+ val affectedSpans = affectedBlockSpans.toList() + affectedParagraphSpans.toList()
92
+
93
+ for (span in affectedSpans) {
94
+ val spanStart = builder.getSpanStart(span)
95
+ val spanEnd = builder.getSpanEnd(span)
96
+ if (spanStart == -1 || spanEnd >= pasteEnd) continue
97
+
98
+ val (_, newParagraphEnd) = builder.getParagraphBounds(spanStart, pasteEnd)
99
+ val flags = builder.getSpanFlags(span)
100
+ builder.removeSpan(span)
101
+ builder.setSpan(span, spanStart, newParagraphEnd, flags)
102
+ }
103
+ }
104
+
105
+ return builder
106
+ }
@@ -0,0 +1,24 @@
1
+ package com.swmansion.enriched.textinput.utils
2
+
3
+ import android.text.SpannableStringBuilder
4
+ import com.swmansion.enriched.common.EnrichedConstants
5
+
6
+ fun CharSequence.zwsCountBefore(index: Int): Int {
7
+ var count = 0
8
+ for (i in 0 until index) {
9
+ if (this[i] == EnrichedConstants.ZWS) count++
10
+ }
11
+ return count
12
+ }
13
+
14
+ // Removes zero-width spaces from the given range in the SpannableStringBuilder without affecting spans
15
+ fun SpannableStringBuilder.removeZWS(
16
+ start: Int,
17
+ end: Int,
18
+ ) {
19
+ for (i in (end - 1) downTo start) {
20
+ if (this[i] == EnrichedConstants.ZWS) {
21
+ delete(i, i + 1)
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,127 @@
1
+ package com.swmansion.enriched.textinput.utils
2
+
3
+ import android.content.ClipData
4
+ import android.content.Context
5
+ import android.graphics.BitmapFactory
6
+ import android.net.Uri
7
+ import android.os.Handler
8
+ import android.os.Looper
9
+ import android.util.Log
10
+ import android.view.View
11
+ import android.webkit.MimeTypeMap
12
+ import androidx.core.view.ContentInfoCompat
13
+ import androidx.core.view.OnReceiveContentListener
14
+ import com.facebook.react.bridge.ReactContext
15
+ import com.facebook.react.uimanager.UIManagerHelper
16
+ import com.swmansion.enriched.textinput.EnrichedTextInputView
17
+ import com.swmansion.enriched.textinput.events.OnPasteImagesEvent
18
+ import java.io.File
19
+ import java.io.FileOutputStream
20
+ import kotlin.io.copyTo
21
+
22
+ class RichContentReceiver(
23
+ private val view: EnrichedTextInputView,
24
+ private val context: ReactContext,
25
+ ) : OnReceiveContentListener {
26
+ override fun onReceiveContent(
27
+ view: View,
28
+ contentInfo: ContentInfoCompat,
29
+ ): ContentInfoCompat? {
30
+ val split = contentInfo.partition { item: ClipData.Item -> item.uri != null }
31
+ val uriContent = split.first
32
+ val remaining = split.second
33
+
34
+ if (uriContent != null) {
35
+ processClipDataInBackground(uriContent.clip)
36
+ }
37
+
38
+ if (remaining != null && remaining.clip.itemCount > 0) {
39
+ val item = remaining.clip.getItemAt(0)
40
+
41
+ this.view.handleTextPaste(item)
42
+ }
43
+
44
+ return null
45
+ }
46
+
47
+ private fun processClipDataInBackground(clip: ClipData) {
48
+ Thread {
49
+ val results = mutableListOf<OnPasteImagesEvent.Companion.PastedImage>()
50
+
51
+ for (i in 0 until clip.itemCount) {
52
+ val item = clip.getItemAt(i)
53
+ val uri = item.uri ?: continue
54
+ val mimeType = getMimeTypeFromUri(uri) ?: continue
55
+
56
+ if (mimeType.startsWith("image/")) {
57
+ val result = saveUriToTempFile(context, uri, mimeType)
58
+ if (result != null) {
59
+ results.add(result)
60
+ }
61
+ }
62
+ }
63
+
64
+ if (results.isNotEmpty()) {
65
+ Handler(Looper.getMainLooper()).post {
66
+ emitOnPasteImageEvent(results)
67
+ }
68
+ }
69
+ }.start()
70
+ }
71
+
72
+ private fun emitOnPasteImageEvent(images: List<OnPasteImagesEvent.Companion.PastedImage>) {
73
+ val surfaceId = UIManagerHelper.getSurfaceId(context)
74
+ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
75
+ dispatcher?.dispatchEvent(OnPasteImagesEvent(surfaceId, view.id, images, false))
76
+ }
77
+
78
+ private fun saveUriToTempFile(
79
+ context: Context,
80
+ uri: Uri,
81
+ mimeType: String,
82
+ ): OnPasteImagesEvent.Companion.PastedImage? {
83
+ return try {
84
+ val resolver = context.contentResolver
85
+ val ext = MimeTypeMap.getFileExtensionFromUrl(uri.toString())
86
+ val file = File.createTempFile("temp", ".$ext", context.cacheDir)
87
+
88
+ // Copy Stream
89
+ resolver.openInputStream(uri).use { input ->
90
+ if (input == null) return null
91
+ FileOutputStream(file).use { output ->
92
+ input.copyTo(output)
93
+ }
94
+ }
95
+
96
+ // Decode Dimensions
97
+ val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
98
+ BitmapFactory.decodeFile(file.absolutePath, options)
99
+
100
+ OnPasteImagesEvent.Companion.PastedImage(
101
+ uri = "file://${file.absolutePath}",
102
+ type = mimeType,
103
+ width = options.outWidth.toDouble(),
104
+ height = options.outHeight.toDouble(),
105
+ )
106
+ } catch (e: Exception) {
107
+ Log.e("RichContentReceiver", "Failed to save URI: $uri", e)
108
+ null
109
+ }
110
+ }
111
+
112
+ private fun getMimeTypeFromUri(uri: Uri): String? {
113
+ var mimeType = context.contentResolver.getType(uri)
114
+
115
+ if (mimeType == null) {
116
+ val extension = MimeTypeMap.getFileExtensionFromUrl(uri.toString())
117
+
118
+ mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
119
+ }
120
+
121
+ return mimeType
122
+ }
123
+
124
+ companion object {
125
+ val MIME_TYPES = arrayOf("image/*", "text/*")
126
+ }
127
+ }
@@ -0,0 +1,106 @@
1
+ package com.swmansion.enriched.textinput.utils
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.text.Selection
5
+ import android.text.Spannable
6
+ import android.text.Spanned
7
+ import android.util.Log
8
+ import android.view.MotionEvent
9
+ import android.widget.TextView
10
+ import com.swmansion.enriched.textinput.spans.EnrichedInputCheckboxListSpan
11
+ import org.json.JSONObject
12
+
13
+ fun jsonStringToStringMap(json: String): Map<String, String> {
14
+ val result = mutableMapOf<String, String>()
15
+ try {
16
+ val jsonObject = JSONObject(json)
17
+ for (key in jsonObject.keys()) {
18
+ val value = jsonObject.opt(key)
19
+ if (value is String) {
20
+ result[key] = value
21
+ }
22
+ }
23
+ } catch (e: Exception) {
24
+ Log.w("ReactNativeEnrichedView", "Failed to parse JSON string to Map: $json", e)
25
+ }
26
+
27
+ return result
28
+ }
29
+
30
+ // Sets a touch listener on TextView which is responsible for detecting touches on checkbox icons
31
+ // We don't use ClickableSpan because it works fine only when LinkMovementMethod is set on TextView
32
+ // Which breaks text selection and other features
33
+ @SuppressLint("ClickableViewAccessibility")
34
+ fun TextView.setCheckboxClickListener() {
35
+ var isDownOnCheckbox = false
36
+
37
+ setOnTouchListener { v, event ->
38
+ val tv = v as TextView
39
+ val layout = tv.layout ?: return@setOnTouchListener false
40
+ val spannable = tv.text as? Spanned ?: return@setOnTouchListener false
41
+
42
+ // Get touch coordinates relative to the text content
43
+ val x = event.x.toInt() - tv.totalPaddingLeft + tv.scrollX
44
+ val y = event.y.toInt() - tv.totalPaddingTop + tv.scrollY
45
+
46
+ // Identify the line and whether it's the first line of the span
47
+ val line = layout.getLineForVertical(y)
48
+ val lineStart = layout.getLineStart(line)
49
+
50
+ // Find spans for specific line
51
+ val spans = spannable.getSpans(lineStart, lineStart, EnrichedInputCheckboxListSpan::class.java)
52
+ if (spans.isEmpty()) return@setOnTouchListener false
53
+
54
+ // There should be only one span per line as we don't support nested lists
55
+ val span = spans[0]
56
+ val isFirstLine = spannable.getSpanStart(span) == lineStart
57
+ val marginWidth = span.getLeadingMargin(true)
58
+
59
+ // Check if touch is on checkbox icon area (which is in the leading margin on the first line)
60
+ val isInHotZone = isFirstLine && x in 0..marginWidth
61
+
62
+ when (event.action) {
63
+ MotionEvent.ACTION_DOWN -> {
64
+ if (isInHotZone) {
65
+ isDownOnCheckbox = true
66
+ return@setOnTouchListener true
67
+ }
68
+ }
69
+
70
+ MotionEvent.ACTION_UP -> {
71
+ if (isDownOnCheckbox && isInHotZone) {
72
+ val spannable = tv.text as? Spannable
73
+ if (spannable != null) {
74
+ val start = spannable.getSpanStart(span)
75
+ val end = spannable.getSpanEnd(span)
76
+ val flags = spannable.getSpanFlags(span)
77
+ span.isChecked = !span.isChecked
78
+
79
+ // Reapply span so changes are visible without need to redraw entire TextView
80
+ spannable.removeSpan(span)
81
+ spannable.setSpan(span, start, end, flags)
82
+
83
+ // For focused input, ensure cursor is active for affected paragraph
84
+ if (tv.isFocused) {
85
+ val currentCursor = Selection.getSelectionEnd(spannable)
86
+ if (currentCursor < start || currentCursor > end) {
87
+ Selection.setSelection(spannable, end)
88
+ }
89
+ }
90
+ }
91
+
92
+ isDownOnCheckbox = false
93
+ return@setOnTouchListener true
94
+ }
95
+ isDownOnCheckbox = false
96
+ }
97
+
98
+ MotionEvent.ACTION_CANCEL -> {
99
+ isDownOnCheckbox = false
100
+ }
101
+ }
102
+
103
+ // Let TextView handle other touches (e.g., for selection)
104
+ false
105
+ }
106
+ }
@@ -0,0 +1,107 @@
1
+ package com.swmansion.enriched.textinput.watchers
2
+
3
+ import android.text.SpanWatcher
4
+ import android.text.Spannable
5
+ import android.text.style.ParagraphStyle
6
+ import com.facebook.react.bridge.ReactContext
7
+ import com.facebook.react.uimanager.UIManagerHelper
8
+ import com.swmansion.enriched.common.parser.EnrichedParser
9
+ import com.swmansion.enriched.common.spans.interfaces.EnrichedHeadingSpan
10
+ import com.swmansion.enriched.textinput.EnrichedTextInputView
11
+ import com.swmansion.enriched.textinput.events.OnChangeHtmlEvent
12
+ import com.swmansion.enriched.textinput.spans.EnrichedInputOrderedListSpan
13
+ import com.swmansion.enriched.textinput.spans.interfaces.EnrichedInputSpan
14
+ import com.swmansion.enriched.textinput.utils.getSafeSpanBoundaries
15
+
16
+ class EnrichedSpanWatcher(
17
+ private val view: EnrichedTextInputView,
18
+ ) : SpanWatcher {
19
+ private var previousHtml: String? = null
20
+
21
+ override fun onSpanAdded(
22
+ text: Spannable,
23
+ what: Any,
24
+ start: Int,
25
+ end: Int,
26
+ ) {
27
+ updateNextLineLayout(what, text, end)
28
+ updateUnorderedListSpans(what, text, end)
29
+ emitEvent(text, what)
30
+ }
31
+
32
+ override fun onSpanRemoved(
33
+ text: Spannable,
34
+ what: Any,
35
+ start: Int,
36
+ end: Int,
37
+ ) {
38
+ updateNextLineLayout(what, text, end)
39
+ updateUnorderedListSpans(what, text, end)
40
+ emitEvent(text, what)
41
+ }
42
+
43
+ override fun onSpanChanged(
44
+ text: Spannable,
45
+ what: Any,
46
+ ostart: Int,
47
+ oend: Int,
48
+ nstart: Int,
49
+ nend: Int,
50
+ ) {
51
+ // Do nothing for now
52
+ }
53
+
54
+ private fun updateUnorderedListSpans(
55
+ what: Any,
56
+ text: Spannable,
57
+ end: Int,
58
+ ) {
59
+ if (what is EnrichedInputOrderedListSpan) {
60
+ view.listStyles?.updateOrderedListIndexes(text, end)
61
+ }
62
+ }
63
+
64
+ // After adding/removing heading span, we have to manually set empty paragraph span to the following text
65
+ // This allows us to update the layout (as it's not updated automatically - looks like an Android issue)
66
+ private fun updateNextLineLayout(
67
+ what: Any,
68
+ text: Spannable,
69
+ end: Int,
70
+ ) {
71
+ class EmptySpan : ParagraphStyle
72
+
73
+ if (what is EnrichedHeadingSpan) {
74
+ val finalStart = (end + 1)
75
+ val finalEnd = text.length
76
+ val (safeStart, safeEnd) = text.getSafeSpanBoundaries(finalStart, finalEnd)
77
+ text.setSpan(EmptySpan(), safeStart, safeEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
78
+ }
79
+ }
80
+
81
+ fun emitEvent(
82
+ s: Spannable,
83
+ what: Any?,
84
+ ) {
85
+ // Do not parse spannable and emit event if onChangeHtml is not provided
86
+ if (!view.shouldEmitHtml) return
87
+
88
+ // Emit event only if we change one of ours spans
89
+ if (what != null && what !is EnrichedInputSpan) return
90
+
91
+ val html = EnrichedParser.toHtml(s)
92
+ if (html == previousHtml) return
93
+
94
+ previousHtml = html
95
+ val context = view.context as ReactContext
96
+ val surfaceId = UIManagerHelper.getSurfaceId(context)
97
+ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
98
+ dispatcher?.dispatchEvent(
99
+ OnChangeHtmlEvent(
100
+ surfaceId,
101
+ view.id,
102
+ html,
103
+ view.experimentalSynchronousEvents,
104
+ ),
105
+ )
106
+ }
107
+ }
@@ -0,0 +1,74 @@
1
+ package com.swmansion.enriched.textinput.watchers
2
+
3
+ import android.text.Editable
4
+ import android.text.TextWatcher
5
+ import com.facebook.react.bridge.ReactContext
6
+ import com.facebook.react.uimanager.UIManagerHelper
7
+ import com.swmansion.enriched.textinput.EnrichedTextInputView
8
+ import com.swmansion.enriched.textinput.events.OnChangeTextEvent
9
+
10
+ class EnrichedTextWatcher(
11
+ private val view: EnrichedTextInputView,
12
+ ) : TextWatcher {
13
+ private var endCursorPosition: Int = 0
14
+ private var startCursorPosition: Int = 0
15
+ private var previousTextLength: Int = 0
16
+
17
+ override fun beforeTextChanged(
18
+ s: CharSequence?,
19
+ start: Int,
20
+ count: Int,
21
+ after: Int,
22
+ ) {
23
+ previousTextLength = s?.length ?: 0
24
+ }
25
+
26
+ override fun onTextChanged(
27
+ s: CharSequence?,
28
+ start: Int,
29
+ before: Int,
30
+ count: Int,
31
+ ) {
32
+ startCursorPosition = start
33
+ endCursorPosition = start + count
34
+ view.layoutManager.invalidateLayout()
35
+ view.isRemovingMany = !view.isDuringTransaction && before > count + 1
36
+ }
37
+
38
+ override fun afterTextChanged(s: Editable?) {
39
+ if (s == null) return
40
+ emitEvents(s)
41
+
42
+ if (view.isDuringTransaction) return
43
+ applyStyles(s)
44
+ }
45
+
46
+ private fun applyStyles(s: Editable) {
47
+ view.inlineStyles?.afterTextChanged(s, endCursorPosition)
48
+ view.paragraphStyles?.afterTextChanged(s, endCursorPosition, previousTextLength)
49
+ view.listStyles?.afterTextChanged(s, endCursorPosition, previousTextLength)
50
+ view.parametrizedStyles?.afterTextChanged(s, startCursorPosition, endCursorPosition)
51
+ }
52
+
53
+ private fun emitChangeText(editable: Editable) {
54
+ if (!view.shouldEmitOnChangeText) {
55
+ return
56
+ }
57
+ val context = view.context as ReactContext
58
+ val surfaceId = UIManagerHelper.getSurfaceId(context)
59
+ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
60
+ dispatcher?.dispatchEvent(
61
+ OnChangeTextEvent(
62
+ surfaceId,
63
+ view.id,
64
+ editable,
65
+ view.experimentalSynchronousEvents,
66
+ ),
67
+ )
68
+ }
69
+
70
+ private fun emitEvents(s: Editable) {
71
+ emitChangeText(s)
72
+ view.spanWatcher?.emitEvent(s, null)
73
+ }
74
+ }
@@ -0,0 +1,62 @@
1
+ cmake_minimum_required(VERSION 3.13)
2
+ set(CMAKE_VERBOSE_MAKEFILE on)
3
+
4
+ set(LIB_LITERAL ReactNativeEnrichedSpec)
5
+ set(LIB_TARGET_NAME react_codegen_${LIB_LITERAL})
6
+
7
+ set(LIB_ANDROID_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
8
+ set(LIB_ANDROID_GENERATED_JNI_DIR ${LIB_ANDROID_DIR}/generated/jni)
9
+ set(LIB_ANDROID_GENERATED_COMPONENTS_DIR ${LIB_ANDROID_GENERATED_JNI_DIR}/react/renderer/components/${LIB_LITERAL})
10
+
11
+ set(LIB_CPP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../cpp)
12
+
13
+ file(GLOB LIB_MODULE_SRCS CONFIGURE_DEPENDS *.cpp react/renderer/components/${LIB_LITERAL}/*.cpp)
14
+ file(GLOB LIB_CODEGEN_SRCS CONFIGURE_DEPENDS ${LIB_ANDROID_GENERATED_COMPONENTS_DIR}/*.cpp)
15
+ file(GLOB LIB_CPP_SRCS CONFIGURE_DEPENDS ${LIB_CPP_DIR}/parser/GumboParser.cpp ${LIB_CPP_DIR}/parser/GumboNormalizer.c)
16
+
17
+ set_source_files_properties(${LIB_CPP_DIR}/parser/GumboNormalizer.c PROPERTIES LANGUAGE C COMPILE_FLAGS "-std=c99")
18
+
19
+ if(NOT DEFINED REACT_NATIVE_MINOR_VERSION)
20
+ set(REACT_NATIVE_MINOR_VERSION ${ReactAndroid_VERSION_MINOR})
21
+ endif()
22
+
23
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}")
24
+
25
+ add_library(
26
+ ${LIB_TARGET_NAME}
27
+ SHARED
28
+ ${LIB_MODULE_SRCS}
29
+ ${LIB_CUSTOM_SRCS}
30
+ ${LIB_CODEGEN_SRCS}
31
+ ${LIB_CPP_SRCS}
32
+ )
33
+
34
+ target_include_directories(
35
+ ${LIB_TARGET_NAME}
36
+ PUBLIC
37
+ .
38
+ ./react/renderer/components/${LIB_LITERAL}
39
+ ${LIB_ANDROID_GENERATED_JNI_DIR}
40
+ ${LIB_ANDROID_GENERATED_COMPONENTS_DIR}
41
+ ${LIB_CPP_DIR}
42
+ ${LIB_CPP_DIR}/parser
43
+ ${LIB_CPP_DIR}/GumboParser
44
+ )
45
+
46
+ find_package(fbjni REQUIRED CONFIG)
47
+ find_package(ReactAndroid REQUIRED CONFIG)
48
+
49
+ target_link_libraries(
50
+ ${LIB_TARGET_NAME}
51
+ fbjni::fbjni
52
+ ReactAndroid::jsi
53
+ ReactAndroid::reactnative
54
+ )
55
+
56
+ target_compile_reactnative_options(${LIB_TARGET_NAME} PRIVATE)
57
+
58
+ target_include_directories(
59
+ ${CMAKE_PROJECT_NAME}
60
+ PUBLIC
61
+ ${CMAKE_CURRENT_SOURCE_DIR}
62
+ )
@@ -0,0 +1,14 @@
1
+ #include "GumboParser.hpp"
2
+ #include <jni.h>
3
+ #include <string>
4
+
5
+ extern "C" JNIEXPORT jstring JNICALL
6
+ Java_com_swmansion_enriched_common_GumboNormalizer_normalizeHtml(
7
+ JNIEnv *env, jclass /*cls*/, jstring htmlJString) {
8
+ const char *htmlChars = env->GetStringUTFChars(htmlJString, nullptr);
9
+ std::string result = GumboParser::normalizeHtml(htmlChars);
10
+ env->ReleaseStringUTFChars(htmlJString, htmlChars);
11
+ if (result.empty())
12
+ return nullptr;
13
+ return env->NewStringUTF(result.c_str());
14
+ }
@@ -0,0 +1,11 @@
1
+ #include "ReactNativeEnrichedSpec.h"
2
+
3
+ namespace facebook::react {
4
+
5
+ std::shared_ptr<TurboModule> ReactNativeEnrichedSpec_ModuleProvider(
6
+ const std::string &moduleName, const JavaTurboModule::InitParams &params) {
7
+
8
+ return nullptr;
9
+ }
10
+
11
+ } // namespace facebook::react
@@ -0,0 +1,15 @@
1
+ #pragma once
2
+
3
+ #include <ReactCommon/JavaTurboModule.h>
4
+ #include <ReactCommon/TurboModule.h>
5
+ #include <jsi/jsi.h>
6
+
7
+ #include <react/renderer/components/ReactNativeEnrichedSpec/EnrichedTextInputComponentDescriptor.h>
8
+
9
+ namespace facebook::react {
10
+
11
+ JSI_EXPORT
12
+ std::shared_ptr<TurboModule> ReactNativeEnrichedSpec_ModuleProvider(
13
+ const std::string &moduleName, const JavaTurboModule::InitParams &params);
14
+
15
+ } // namespace facebook::react
@@ -0,0 +1,35 @@
1
+ #pragma once
2
+
3
+ #include "EnrichedTextInputMeasurementManager.h"
4
+ #include "EnrichedTextInputShadowNode.h"
5
+
6
+ #include <react/renderer/core/ConcreteComponentDescriptor.h>
7
+
8
+ namespace facebook::react {
9
+
10
+ class EnrichedTextInputComponentDescriptor final
11
+ : public ConcreteComponentDescriptor<EnrichedTextInputShadowNode> {
12
+ public:
13
+ EnrichedTextInputComponentDescriptor(
14
+ const ComponentDescriptorParameters &parameters)
15
+ : ConcreteComponentDescriptor(parameters),
16
+ measurementsManager_(
17
+ std::make_shared<EnrichedTextInputMeasurementManager>(
18
+ contextContainer_)) {}
19
+
20
+ void adopt(ShadowNode &shadowNode) const override {
21
+ ConcreteComponentDescriptor::adopt(shadowNode);
22
+ auto &editorShadowNode =
23
+ static_cast<EnrichedTextInputShadowNode &>(shadowNode);
24
+
25
+ // `EnrichedTextInputShadowNode` uses
26
+ // `EnrichedTextInputMeasurementManager` to provide measurements to Yoga.
27
+ editorShadowNode.setMeasurementsManager(measurementsManager_);
28
+ }
29
+
30
+ private:
31
+ const std::shared_ptr<EnrichedTextInputMeasurementManager>
32
+ measurementsManager_;
33
+ };
34
+
35
+ } // namespace facebook::react