@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,320 @@
1
+ package com.swmansion.enriched.textinput.utils
2
+
3
+ import android.text.Editable
4
+ import android.text.Spannable
5
+ import com.facebook.react.bridge.ReactContext
6
+ import com.facebook.react.uimanager.UIManagerHelper
7
+ import com.swmansion.enriched.common.EnrichedConstants
8
+ import com.swmansion.enriched.textinput.EnrichedTextInputView
9
+ import com.swmansion.enriched.textinput.events.OnChangeSelectionEvent
10
+ import com.swmansion.enriched.textinput.events.OnLinkDetectedEvent
11
+ import com.swmansion.enriched.textinput.events.OnMentionDetectedEvent
12
+ import com.swmansion.enriched.textinput.spans.EnrichedInputLinkSpan
13
+ import com.swmansion.enriched.textinput.spans.EnrichedInputMentionSpan
14
+ import com.swmansion.enriched.textinput.spans.EnrichedSpans
15
+ import org.json.JSONObject
16
+
17
+ class EnrichedSelection(
18
+ private val view: EnrichedTextInputView,
19
+ ) {
20
+ var start: Int = 0
21
+ var end: Int = 0
22
+
23
+ private var previousLinkDetectedEvent: MutableMap<String, String> = mutableMapOf("text" to "", "url" to "")
24
+ private var previousMentionDetectedEvent: MutableMap<String, String> = mutableMapOf("text" to "", "payload" to "")
25
+
26
+ fun onSelection(
27
+ selStart: Int,
28
+ selEnd: Int,
29
+ ) {
30
+ var shouldValidateStyles = false
31
+ var newStart = start
32
+ var newEnd = end
33
+
34
+ if (selStart != -1 && selStart != newStart) {
35
+ newStart = selStart
36
+ shouldValidateStyles = true
37
+ }
38
+
39
+ if (selEnd != -1 && selEnd != newEnd) {
40
+ newEnd = selEnd
41
+ shouldValidateStyles = true
42
+ }
43
+
44
+ val textLength = view.text?.length ?: 0
45
+ val finalStart = newStart.coerceAtMost(newEnd).coerceAtLeast(0).coerceAtMost(textLength)
46
+ val finalEnd = newEnd.coerceAtLeast(newStart).coerceAtLeast(0).coerceAtMost(textLength)
47
+
48
+ if (isZeroWidthSelection(finalStart, finalEnd) && !view.isDuringTransaction) {
49
+ view.setSelection(finalStart + 1)
50
+ shouldValidateStyles = false
51
+ }
52
+
53
+ if (!shouldValidateStyles) return
54
+
55
+ start = finalStart
56
+ end = finalEnd
57
+ validateStyles()
58
+ emitSelectionChangeEvent(view.text, finalStart, finalEnd)
59
+ }
60
+
61
+ private fun isZeroWidthSelection(
62
+ start: Int,
63
+ end: Int,
64
+ ): Boolean {
65
+ val text = view.text ?: return false
66
+
67
+ if (start != end) {
68
+ return text.substring(start, end) == EnrichedConstants.ZWS_STRING
69
+ }
70
+
71
+ val isNewLine = if (start > 0) text.substring(start - 1, start) == "\n" else true
72
+ val isNextCharacterZeroWidth =
73
+ if (start < text.length) {
74
+ text.substring(start, start + 1) == EnrichedConstants.ZWS_STRING
75
+ } else {
76
+ false
77
+ }
78
+
79
+ return isNewLine && isNextCharacterZeroWidth
80
+ }
81
+
82
+ fun validateStyles() {
83
+ val state = view.spanState ?: return
84
+
85
+ // We don't validate inline styles when removing many characters at once
86
+ // We don't want to remove styles on auto-correction
87
+ // If user removes many characters at once, we want to keep the styles config
88
+ if (!view.isRemovingMany) {
89
+ for ((style, config) in EnrichedSpans.inlineSpans) {
90
+ state.setStart(style, getInlineStyleStart(config.clazz))
91
+ }
92
+ } else {
93
+ view.isRemovingMany = false
94
+ }
95
+
96
+ for ((style, config) in EnrichedSpans.paragraphSpans) {
97
+ state.setStart(style, getParagraphStyleStart(config.clazz))
98
+ }
99
+
100
+ for ((style, config) in EnrichedSpans.listSpans) {
101
+ state.setStart(style, getListStyleStart(config.clazz))
102
+ }
103
+
104
+ for ((style, config) in EnrichedSpans.parametrizedStyles) {
105
+ state.setStart(style, getParametrizedStyleStart(config.clazz))
106
+ }
107
+ }
108
+
109
+ fun getInlineSelection(): Pair<Int, Int> {
110
+ val finalStart = start.coerceAtMost(end).coerceAtLeast(0)
111
+ val finalEnd = end.coerceAtLeast(start).coerceAtLeast(0)
112
+
113
+ return Pair(finalStart, finalEnd)
114
+ }
115
+
116
+ private fun <T> getInlineStyleStart(type: Class<T>): Int? {
117
+ val (start, end) = getInlineSelection()
118
+ val spannable = view.text as Spannable
119
+ val spans = spannable.getSpans(start, end, type)
120
+ var styleStart: Int? = null
121
+
122
+ for (span in spans) {
123
+ val spanStart = spannable.getSpanStart(span)
124
+ val spanEnd = spannable.getSpanEnd(span)
125
+
126
+ if (start == end && start == spanStart) {
127
+ styleStart = null
128
+ } else if (start >= spanStart && end <= spanEnd) {
129
+ styleStart = spanStart
130
+ }
131
+ }
132
+
133
+ return styleStart
134
+ }
135
+
136
+ fun getParagraphSelection(): Pair<Int, Int> {
137
+ val (currentStart, currentEnd) = getInlineSelection()
138
+ val spannable = view.text as Spannable
139
+ return spannable.getParagraphBounds(currentStart, currentEnd)
140
+ }
141
+
142
+ private fun <T> getParagraphStyleStart(type: Class<T>): Int? {
143
+ val (start, end) = getParagraphSelection()
144
+ val spannable = view.text as Spannable
145
+ val spans = spannable.getSpans(start, end, type)
146
+ var styleStart: Int? = null
147
+
148
+ for (span in spans) {
149
+ val spanStart = spannable.getSpanStart(span)
150
+ val spanEnd = spannable.getSpanEnd(span)
151
+
152
+ if (start >= spanStart && end <= spanEnd) {
153
+ styleStart = spanStart
154
+ break
155
+ }
156
+ }
157
+
158
+ return styleStart
159
+ }
160
+
161
+ private fun <T> getListStyleStart(type: Class<T>): Int? {
162
+ val (start, end) = getParagraphSelection()
163
+ val spannable = view.text as Spannable
164
+ var styleStart: Int? = null
165
+
166
+ var paragraphStart = start
167
+ val paragraphs = spannable.substring(start, end).split("\n")
168
+ pi@ for (paragraph in paragraphs) {
169
+ val paragraphEnd = paragraphStart + paragraph.length
170
+ val spans = spannable.getSpans(paragraphStart, paragraphEnd, type)
171
+
172
+ for (span in spans) {
173
+ val spanStart = spannable.getSpanStart(span)
174
+ val spanEnd = spannable.getSpanEnd(span)
175
+
176
+ if (spanStart == paragraphStart && spanEnd == paragraphEnd) {
177
+ styleStart = spanStart
178
+ paragraphStart = paragraphEnd + 1
179
+ continue@pi
180
+ }
181
+ }
182
+
183
+ styleStart = null
184
+ break
185
+ }
186
+
187
+ return styleStart
188
+ }
189
+
190
+ private fun <T> getParametrizedStyleStart(type: Class<T>): Int? {
191
+ val (start, end) = getInlineSelection()
192
+ val spannable = view.text as Spannable
193
+ val spans = spannable.getSpans(start, end, type)
194
+ val isLinkType = type == EnrichedInputLinkSpan::class.java
195
+ val isMentionType = type == EnrichedInputMentionSpan::class.java
196
+
197
+ if (isLinkType && spans.isEmpty()) {
198
+ emitLinkDetectedEvent(spannable, null, start, end)
199
+ return null
200
+ }
201
+
202
+ if (isMentionType && spans.isEmpty()) {
203
+ emitMentionDetectedEvent(spannable, null, start, end)
204
+ return null
205
+ }
206
+
207
+ for (span in spans) {
208
+ val spanStart = spannable.getSpanStart(span)
209
+ val spanEnd = spannable.getSpanEnd(span)
210
+
211
+ if (start >= spanStart && end <= spanEnd) {
212
+ if (isLinkType && span is EnrichedInputLinkSpan) {
213
+ emitLinkDetectedEvent(spannable, span, spanStart, spanEnd)
214
+ } else if (isMentionType && span is EnrichedInputMentionSpan) {
215
+ emitMentionDetectedEvent(spannable, span, spanStart, spanEnd)
216
+ }
217
+
218
+ return spanStart
219
+ }
220
+ }
221
+
222
+ return null
223
+ }
224
+
225
+ private fun emitSelectionChangeEvent(
226
+ editable: Editable?,
227
+ start: Int,
228
+ end: Int,
229
+ ) {
230
+ if (editable == null) return
231
+
232
+ val context = view.context as ReactContext
233
+ val surfaceId = UIManagerHelper.getSurfaceId(context)
234
+ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
235
+
236
+ val visibleStart = start - editable.zwsCountBefore(start)
237
+ val visibleEnd = end - editable.zwsCountBefore(end)
238
+ val text = editable.substring(start, end).replace(EnrichedConstants.ZWS_STRING, "")
239
+ dispatcher?.dispatchEvent(
240
+ OnChangeSelectionEvent(
241
+ surfaceId,
242
+ view.id,
243
+ text,
244
+ visibleStart,
245
+ visibleEnd,
246
+ view.experimentalSynchronousEvents,
247
+ ),
248
+ )
249
+ }
250
+
251
+ private fun emitLinkDetectedEvent(
252
+ spannable: Spannable,
253
+ span: EnrichedInputLinkSpan?,
254
+ start: Int,
255
+ end: Int,
256
+ ) {
257
+ val text = spannable.substring(start, end).replace(EnrichedConstants.ZWS_STRING, "")
258
+ val url = span?.getUrl() ?: ""
259
+
260
+ // Prevents emitting unnecessary events
261
+ if (text == previousLinkDetectedEvent["text"] && url == previousLinkDetectedEvent["url"]) return
262
+
263
+ previousLinkDetectedEvent.put("text", text)
264
+ previousLinkDetectedEvent.put("url", url)
265
+
266
+ val visibleStart = start - spannable.zwsCountBefore(start)
267
+ val visibleEnd = end - spannable.zwsCountBefore(end)
268
+
269
+ val context = view.context as ReactContext
270
+ val surfaceId = UIManagerHelper.getSurfaceId(context)
271
+ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
272
+ dispatcher?.dispatchEvent(
273
+ OnLinkDetectedEvent(
274
+ surfaceId,
275
+ view.id,
276
+ text,
277
+ url,
278
+ visibleStart,
279
+ visibleEnd,
280
+ view.experimentalSynchronousEvents,
281
+ ),
282
+ )
283
+ }
284
+
285
+ private fun emitMentionDetectedEvent(
286
+ spannable: Spannable,
287
+ span: EnrichedInputMentionSpan?,
288
+ start: Int,
289
+ end: Int,
290
+ ) {
291
+ val text = spannable.substring(start, end)
292
+ val attributes = span?.getAttributes() ?: emptyMap()
293
+ val indicator = span?.getIndicator() ?: ""
294
+ val payload = JSONObject(attributes).toString()
295
+
296
+ val previousText = previousMentionDetectedEvent["text"] ?: ""
297
+ val previousPayload = previousMentionDetectedEvent["payload"] ?: ""
298
+ val previousIndicator = previousMentionDetectedEvent["indicator"] ?: ""
299
+
300
+ if (text == previousText && payload == previousPayload && indicator == previousIndicator) return
301
+
302
+ previousMentionDetectedEvent.put("text", text)
303
+ previousMentionDetectedEvent.put("payload", payload)
304
+ previousMentionDetectedEvent.put("indicator", indicator)
305
+
306
+ val context = view.context as ReactContext
307
+ val surfaceId = UIManagerHelper.getSurfaceId(context)
308
+ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
309
+ dispatcher?.dispatchEvent(
310
+ OnMentionDetectedEvent(
311
+ surfaceId,
312
+ view.id,
313
+ text,
314
+ indicator,
315
+ payload,
316
+ view.experimentalSynchronousEvents,
317
+ ),
318
+ )
319
+ }
320
+ }
@@ -0,0 +1,310 @@
1
+ package com.swmansion.enriched.textinput.utils
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.ReactContext
5
+ import com.facebook.react.bridge.WritableMap
6
+ import com.facebook.react.uimanager.UIManagerHelper
7
+ import com.facebook.react.uimanager.events.EventDispatcher
8
+ import com.swmansion.enriched.textinput.EnrichedTextInputView
9
+ import com.swmansion.enriched.textinput.events.OnChangeStateEvent
10
+ import com.swmansion.enriched.textinput.spans.EnrichedSpans
11
+
12
+ class EnrichedSpanState(
13
+ private val view: EnrichedTextInputView,
14
+ ) {
15
+ private var previousPayload: WritableMap? = null
16
+
17
+ var boldStart: Int? = null
18
+ private set
19
+ var italicStart: Int? = null
20
+ private set
21
+ var underlineStart: Int? = null
22
+ private set
23
+ var strikethroughStart: Int? = null
24
+ private set
25
+ var inlineCodeStart: Int? = null
26
+ private set
27
+ var h1Start: Int? = null
28
+ private set
29
+ var h2Start: Int? = null
30
+ private set
31
+ var h3Start: Int? = null
32
+ private set
33
+ var h4Start: Int? = null
34
+ private set
35
+ var h5Start: Int? = null
36
+ private set
37
+ var h6Start: Int? = null
38
+ private set
39
+ var codeBlockStart: Int? = null
40
+ private set
41
+ var blockQuoteStart: Int? = null
42
+ private set
43
+ var orderedListStart: Int? = null
44
+ private set
45
+ var unorderedListStart: Int? = null
46
+ private set
47
+ var checkboxListStart: Int? = null
48
+ private set
49
+ var linkStart: Int? = null
50
+ private set
51
+ var imageStart: Int? = null
52
+ private set
53
+ var mentionStart: Int? = null
54
+ private set
55
+
56
+ fun setBoldStart(start: Int?) {
57
+ this.boldStart = start
58
+ emitStateChangeEvent()
59
+ }
60
+
61
+ fun setItalicStart(start: Int?) {
62
+ this.italicStart = start
63
+ emitStateChangeEvent()
64
+ }
65
+
66
+ fun setUnderlineStart(start: Int?) {
67
+ this.underlineStart = start
68
+ emitStateChangeEvent()
69
+ }
70
+
71
+ fun setStrikethroughStart(start: Int?) {
72
+ this.strikethroughStart = start
73
+ emitStateChangeEvent()
74
+ }
75
+
76
+ fun setInlineCodeStart(start: Int?) {
77
+ this.inlineCodeStart = start
78
+ emitStateChangeEvent()
79
+ }
80
+
81
+ fun setH1Start(start: Int?) {
82
+ this.h1Start = start
83
+ emitStateChangeEvent()
84
+ }
85
+
86
+ fun setH2Start(start: Int?) {
87
+ this.h2Start = start
88
+ emitStateChangeEvent()
89
+ }
90
+
91
+ fun setH3Start(start: Int?) {
92
+ this.h3Start = start
93
+ emitStateChangeEvent()
94
+ }
95
+
96
+ fun setH4Start(start: Int?) {
97
+ this.h4Start = start
98
+ emitStateChangeEvent()
99
+ }
100
+
101
+ fun setH5Start(start: Int?) {
102
+ this.h5Start = start
103
+ emitStateChangeEvent()
104
+ }
105
+
106
+ fun setH6Start(start: Int?) {
107
+ this.h6Start = start
108
+ emitStateChangeEvent()
109
+ }
110
+
111
+ fun setCodeBlockStart(start: Int?) {
112
+ this.codeBlockStart = start
113
+ emitStateChangeEvent()
114
+ }
115
+
116
+ fun setBlockQuoteStart(start: Int?) {
117
+ this.blockQuoteStart = start
118
+ emitStateChangeEvent()
119
+ }
120
+
121
+ fun setOrderedListStart(start: Int?) {
122
+ this.orderedListStart = start
123
+ emitStateChangeEvent()
124
+ }
125
+
126
+ fun setUnorderedListStart(start: Int?) {
127
+ this.unorderedListStart = start
128
+ emitStateChangeEvent()
129
+ }
130
+
131
+ fun setCheckboxListStart(start: Int?) {
132
+ this.checkboxListStart = start
133
+ emitStateChangeEvent()
134
+ }
135
+
136
+ fun setLinkStart(start: Int?) {
137
+ this.linkStart = start
138
+ emitStateChangeEvent()
139
+ }
140
+
141
+ fun setImageStart(start: Int?) {
142
+ this.imageStart = start
143
+ emitStateChangeEvent()
144
+ }
145
+
146
+ fun setMentionStart(start: Int?) {
147
+ this.mentionStart = start
148
+ emitStateChangeEvent()
149
+ }
150
+
151
+ fun getStart(name: String): Int? {
152
+ val start =
153
+ when (name) {
154
+ EnrichedSpans.BOLD -> boldStart
155
+ EnrichedSpans.ITALIC -> italicStart
156
+ EnrichedSpans.UNDERLINE -> underlineStart
157
+ EnrichedSpans.STRIKETHROUGH -> strikethroughStart
158
+ EnrichedSpans.INLINE_CODE -> inlineCodeStart
159
+ EnrichedSpans.H1 -> h1Start
160
+ EnrichedSpans.H2 -> h2Start
161
+ EnrichedSpans.H3 -> h3Start
162
+ EnrichedSpans.H4 -> h4Start
163
+ EnrichedSpans.H5 -> h5Start
164
+ EnrichedSpans.H6 -> h6Start
165
+ EnrichedSpans.CODE_BLOCK -> codeBlockStart
166
+ EnrichedSpans.BLOCK_QUOTE -> blockQuoteStart
167
+ EnrichedSpans.ORDERED_LIST -> orderedListStart
168
+ EnrichedSpans.UNORDERED_LIST -> unorderedListStart
169
+ EnrichedSpans.CHECKBOX_LIST -> checkboxListStart
170
+ EnrichedSpans.LINK -> linkStart
171
+ EnrichedSpans.IMAGE -> imageStart
172
+ EnrichedSpans.MENTION -> mentionStart
173
+ else -> null
174
+ }
175
+
176
+ return start
177
+ }
178
+
179
+ fun setStart(
180
+ name: String,
181
+ start: Int?,
182
+ ) {
183
+ when (name) {
184
+ EnrichedSpans.BOLD -> setBoldStart(start)
185
+ EnrichedSpans.ITALIC -> setItalicStart(start)
186
+ EnrichedSpans.UNDERLINE -> setUnderlineStart(start)
187
+ EnrichedSpans.STRIKETHROUGH -> setStrikethroughStart(start)
188
+ EnrichedSpans.INLINE_CODE -> setInlineCodeStart(start)
189
+ EnrichedSpans.H1 -> setH1Start(start)
190
+ EnrichedSpans.H2 -> setH2Start(start)
191
+ EnrichedSpans.H3 -> setH3Start(start)
192
+ EnrichedSpans.H4 -> setH4Start(start)
193
+ EnrichedSpans.H5 -> setH5Start(start)
194
+ EnrichedSpans.H6 -> setH6Start(start)
195
+ EnrichedSpans.CODE_BLOCK -> setCodeBlockStart(start)
196
+ EnrichedSpans.BLOCK_QUOTE -> setBlockQuoteStart(start)
197
+ EnrichedSpans.ORDERED_LIST -> setOrderedListStart(start)
198
+ EnrichedSpans.UNORDERED_LIST -> setUnorderedListStart(start)
199
+ EnrichedSpans.CHECKBOX_LIST -> setCheckboxListStart(start)
200
+ EnrichedSpans.LINK -> setLinkStart(start)
201
+ EnrichedSpans.IMAGE -> setImageStart(start)
202
+ EnrichedSpans.MENTION -> setMentionStart(start)
203
+ }
204
+ }
205
+
206
+ fun getStyleStatePayload(): WritableMap {
207
+ val activeStyles =
208
+ listOfNotNull(
209
+ if (boldStart != null) EnrichedSpans.BOLD else null,
210
+ if (italicStart != null) EnrichedSpans.ITALIC else null,
211
+ if (underlineStart != null) EnrichedSpans.UNDERLINE else null,
212
+ if (strikethroughStart != null) EnrichedSpans.STRIKETHROUGH else null,
213
+ if (inlineCodeStart != null) EnrichedSpans.INLINE_CODE else null,
214
+ if (h1Start != null) EnrichedSpans.H1 else null,
215
+ if (h2Start != null) EnrichedSpans.H2 else null,
216
+ if (h3Start != null) EnrichedSpans.H3 else null,
217
+ if (h4Start != null) EnrichedSpans.H4 else null,
218
+ if (h5Start != null) EnrichedSpans.H5 else null,
219
+ if (h6Start != null) EnrichedSpans.H6 else null,
220
+ if (codeBlockStart != null) EnrichedSpans.CODE_BLOCK else null,
221
+ if (blockQuoteStart != null) EnrichedSpans.BLOCK_QUOTE else null,
222
+ if (orderedListStart != null) EnrichedSpans.ORDERED_LIST else null,
223
+ if (unorderedListStart != null) EnrichedSpans.UNORDERED_LIST else null,
224
+ if (checkboxListStart != null) EnrichedSpans.CHECKBOX_LIST else null,
225
+ if (linkStart != null) EnrichedSpans.LINK else null,
226
+ if (imageStart != null) EnrichedSpans.IMAGE else null,
227
+ if (mentionStart != null) EnrichedSpans.MENTION else null,
228
+ )
229
+ val payload = Arguments.createMap()
230
+ payload.putMap("bold", getStyleState(activeStyles, EnrichedSpans.BOLD))
231
+ payload.putMap("italic", getStyleState(activeStyles, EnrichedSpans.ITALIC))
232
+ payload.putMap("underline", getStyleState(activeStyles, EnrichedSpans.UNDERLINE))
233
+ payload.putMap("strikeThrough", getStyleState(activeStyles, EnrichedSpans.STRIKETHROUGH))
234
+ payload.putMap("inlineCode", getStyleState(activeStyles, EnrichedSpans.INLINE_CODE))
235
+ payload.putMap("h1", getStyleState(activeStyles, EnrichedSpans.H1))
236
+ payload.putMap("h2", getStyleState(activeStyles, EnrichedSpans.H2))
237
+ payload.putMap("h3", getStyleState(activeStyles, EnrichedSpans.H3))
238
+ payload.putMap("h4", getStyleState(activeStyles, EnrichedSpans.H4))
239
+ payload.putMap("h5", getStyleState(activeStyles, EnrichedSpans.H5))
240
+ payload.putMap("h6", getStyleState(activeStyles, EnrichedSpans.H6))
241
+ payload.putMap("codeBlock", getStyleState(activeStyles, EnrichedSpans.CODE_BLOCK))
242
+ payload.putMap("blockQuote", getStyleState(activeStyles, EnrichedSpans.BLOCK_QUOTE))
243
+ payload.putMap("orderedList", getStyleState(activeStyles, EnrichedSpans.ORDERED_LIST))
244
+ payload.putMap("unorderedList", getStyleState(activeStyles, EnrichedSpans.UNORDERED_LIST))
245
+ payload.putMap("link", getStyleState(activeStyles, EnrichedSpans.LINK))
246
+ payload.putMap("image", getStyleState(activeStyles, EnrichedSpans.IMAGE))
247
+ payload.putMap("mention", getStyleState(activeStyles, EnrichedSpans.MENTION))
248
+ payload.putMap("checkboxList", getStyleState(activeStyles, EnrichedSpans.CHECKBOX_LIST))
249
+
250
+ return payload
251
+ }
252
+
253
+ private fun emitStateChangeEvent() {
254
+ val context = view.context as ReactContext
255
+ val surfaceId = UIManagerHelper.getSurfaceId(context)
256
+ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
257
+
258
+ dispatchPayload(dispatcher, surfaceId)
259
+ }
260
+
261
+ private fun dispatchPayload(
262
+ dispatcher: EventDispatcher?,
263
+ surfaceId: Int,
264
+ ) {
265
+ val payload = getStyleStatePayload()
266
+
267
+ // Do not emit event if payload is the same
268
+ if (previousPayload == payload) {
269
+ return
270
+ }
271
+
272
+ previousPayload =
273
+ Arguments.createMap().apply {
274
+ merge(payload)
275
+ }
276
+ dispatcher?.dispatchEvent(
277
+ OnChangeStateEvent(
278
+ surfaceId,
279
+ view.id,
280
+ payload,
281
+ view.experimentalSynchronousEvents,
282
+ ),
283
+ )
284
+ }
285
+
286
+ private fun getStyleState(
287
+ activeStyles: List<String>,
288
+ type: String,
289
+ ): WritableMap {
290
+ val mergingConfig = EnrichedSpans.getMergingConfigForStyle(type, view.htmlStyle)
291
+ val blockingList = mergingConfig?.blockingStyles
292
+ val conflictingList = mergingConfig?.conflictingStyles
293
+
294
+ val state = Arguments.createMap()
295
+
296
+ state.putBoolean("isActive", activeStyles.contains(type))
297
+
298
+ val isBlocking = blockingList?.any { activeStyles.contains(it) } ?: false
299
+ state.putBoolean("isBlocking", isBlocking)
300
+
301
+ val isConflicting = conflictingList?.any { activeStyles.contains(it) } ?: false
302
+ state.putBoolean("isConflicting", isConflicting)
303
+
304
+ return state
305
+ }
306
+
307
+ companion object {
308
+ const val NAME = "ReactNativeEnrichedView"
309
+ }
310
+ }