@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,394 @@
1
+ package com.swmansion.enriched.textinput.styles
2
+
3
+ import android.text.Editable
4
+ import android.text.Spannable
5
+ import android.text.SpannableStringBuilder
6
+ import android.text.Spanned
7
+ import com.swmansion.enriched.common.EnrichedConstants
8
+ import com.swmansion.enriched.textinput.EnrichedTextInputView
9
+ import com.swmansion.enriched.textinput.spans.EnrichedInputImageSpan
10
+ import com.swmansion.enriched.textinput.spans.EnrichedInputLinkSpan
11
+ import com.swmansion.enriched.textinput.spans.EnrichedInputMentionSpan
12
+ import com.swmansion.enriched.textinput.spans.EnrichedSpans
13
+ import com.swmansion.enriched.textinput.utils.getSafeSpanBoundaries
14
+ import com.swmansion.enriched.textinput.utils.removeZWS
15
+
16
+ class ParametrizedStyles(
17
+ private val view: EnrichedTextInputView,
18
+ ) {
19
+ private var mentionStart: Int? = null
20
+ private var isSettingLinkSpan = false
21
+
22
+ var mentionIndicators: Array<String> = emptyArray<String>()
23
+
24
+ fun <T> removeSpansForRange(
25
+ spannable: Spannable,
26
+ start: Int,
27
+ end: Int,
28
+ clazz: Class<T>,
29
+ ): Boolean {
30
+ val ssb = spannable as SpannableStringBuilder
31
+ val spans = ssb.getSpans(start, end, clazz)
32
+ if (spans.isEmpty()) return false
33
+
34
+ ssb.removeZWS(start, end)
35
+
36
+ for (span in spans) {
37
+ ssb.removeSpan(span)
38
+ }
39
+
40
+ return true
41
+ }
42
+
43
+ fun setLinkSpan(
44
+ start: Int,
45
+ end: Int,
46
+ text: String,
47
+ url: String,
48
+ ) {
49
+ isSettingLinkSpan = true
50
+
51
+ val spannable = view.text as SpannableStringBuilder
52
+ val spans = spannable.getSpans(start, end, EnrichedInputLinkSpan::class.java)
53
+ for (span in spans) {
54
+ spannable.removeSpan(span)
55
+ }
56
+
57
+ if (start == end) {
58
+ spannable.insert(start, text)
59
+ } else {
60
+ spannable.replace(start, end, text)
61
+ }
62
+
63
+ val spanEnd = start + text.length
64
+ val span = EnrichedInputLinkSpan(url, view.htmlStyle, true)
65
+ val (safeStart, safeEnd) = spannable.getSafeSpanBoundaries(start, spanEnd)
66
+ spannable.setSpan(span, safeStart, safeEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
67
+
68
+ view.selection?.validateStyles()
69
+ isSettingLinkSpan = false
70
+ }
71
+
72
+ fun removeLinkSpans(
73
+ start: Int,
74
+ end: Int,
75
+ ) {
76
+ val spannable = view.text as SpannableStringBuilder
77
+ val textLength = spannable.length
78
+ val clampedStart = minOf(start, end).coerceIn(0, textLength)
79
+ val clampedEnd = maxOf(start, end).coerceIn(0, textLength)
80
+
81
+ val spans = spannable.getSpans(clampedStart, clampedEnd, EnrichedInputLinkSpan::class.java)
82
+ for (span in spans) {
83
+ spannable.removeSpan(span)
84
+ }
85
+ view.selection?.validateStyles()
86
+ }
87
+
88
+ fun afterTextChanged(
89
+ s: Editable,
90
+ startCursorPosition: Int,
91
+ endCursorPosition: Int,
92
+ ) {
93
+ afterTextChangedLinks(startCursorPosition, endCursorPosition)
94
+ afterTextChangedMentions(s, startCursorPosition)
95
+ }
96
+
97
+ fun detectLinksInRange(
98
+ spannable: Spannable,
99
+ start: Int,
100
+ end: Int,
101
+ ) {
102
+ val regex = view.linkRegex ?: return
103
+ val textLength = spannable.length
104
+ val safeStart = minOf(start, end).coerceIn(0, textLength)
105
+ val safeEnd = maxOf(start, end).coerceIn(0, textLength)
106
+ if (safeStart >= safeEnd) return
107
+
108
+ val contextText = spannable.subSequence(safeStart, safeEnd).toString()
109
+
110
+ val spans = spannable.getSpans(safeStart, safeEnd, EnrichedInputLinkSpan::class.java)
111
+ for (span in spans) {
112
+ if (span.getIsManual()) continue
113
+ spannable.removeSpan(span)
114
+ }
115
+
116
+ val wordsRegex = Regex("\\S+")
117
+ for (wordMatch in wordsRegex.findAll(contextText)) {
118
+ var word = wordMatch.value
119
+ var wordStart = wordMatch.range.first
120
+
121
+ // Do not include zero-width space in link detection
122
+ if (word.startsWith(EnrichedConstants.ZWS_STRING)) {
123
+ word = word.substring(1)
124
+ wordStart += 1
125
+ }
126
+
127
+ // Loop over words and detect links
128
+ val matcher = regex.matcher(word)
129
+ while (matcher.find()) {
130
+ val linkStart = matcher.start()
131
+ val linkEnd = matcher.end()
132
+
133
+ val spanStart = start + wordStart + linkStart
134
+ val spanEnd = start + wordStart + linkEnd
135
+
136
+ val (safeStart, safeEnd) = spannable.getSafeSpanBoundaries(spanStart, spanEnd)
137
+
138
+ // Do not overwrite a manual link span with an auto-detected one
139
+ val overlappingManual =
140
+ spannable
141
+ .getSpans(safeStart, safeEnd, EnrichedInputLinkSpan::class.java)
142
+ .any { it.getIsManual() }
143
+ if (overlappingManual) continue
144
+
145
+ val span = EnrichedInputLinkSpan(matcher.group(), view.htmlStyle)
146
+ spannable.setSpan(
147
+ span,
148
+ safeStart,
149
+ safeEnd,
150
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE,
151
+ )
152
+ }
153
+ }
154
+ }
155
+
156
+ private fun getWordAtIndex(
157
+ s: CharSequence,
158
+ index: Int,
159
+ ): TextRange? {
160
+ if (index < 0) return null
161
+
162
+ var start = index
163
+ var end = index
164
+
165
+ while (start > 0 && !Character.isWhitespace(s[start - 1])) {
166
+ start--
167
+ }
168
+
169
+ while (end < s.length && !Character.isWhitespace(s[end])) {
170
+ end++
171
+ }
172
+
173
+ val result = s.subSequence(start, end).toString()
174
+
175
+ return TextRange(result, start, end)
176
+ }
177
+
178
+ // After editing text we want to automatically detect links in the affected range
179
+ // Affected range is range + previous word + next word
180
+ private fun getLinksAffectedRange(
181
+ s: CharSequence,
182
+ start: Int,
183
+ end: Int,
184
+ ): IntRange {
185
+ var actualStart = start
186
+ var actualEnd = end
187
+
188
+ // Expand backward to find the start of the first affected word
189
+ while (actualStart > 0 && !Character.isWhitespace(s[actualStart - 1])) {
190
+ actualStart--
191
+ }
192
+
193
+ // Expand forward to find the end of the last affected word
194
+ while (actualEnd < s.length && !Character.isWhitespace(s[actualEnd])) {
195
+ actualEnd++
196
+ }
197
+
198
+ return actualStart..actualEnd
199
+ }
200
+
201
+ private fun canLinkBeApplied(): Boolean {
202
+ val mergingConfig = EnrichedSpans.getMergingConfigForStyle(EnrichedSpans.LINK, view.htmlStyle) ?: return true
203
+ val conflictingStyles = mergingConfig.conflictingStyles
204
+ val blockingStyles = mergingConfig.blockingStyles
205
+
206
+ for (style in blockingStyles) {
207
+ if (view.spanState?.getStart(style) != null) return false
208
+ }
209
+
210
+ for (style in conflictingStyles) {
211
+ if (view.spanState?.getStart(style) != null) return false
212
+ }
213
+
214
+ return true
215
+ }
216
+
217
+ private fun afterTextChangedLinks(
218
+ editStart: Int,
219
+ editEnd: Int,
220
+ ) {
221
+ // Do not detect link if it's applied manually
222
+ if (isSettingLinkSpan || !canLinkBeApplied()) return
223
+
224
+ val spannable = view.text as? Spannable ?: return
225
+ val affectedRange = getLinksAffectedRange(spannable, editStart, editEnd)
226
+ detectLinksInRange(spannable, affectedRange.first, affectedRange.last)
227
+ }
228
+
229
+ private fun afterTextChangedMentions(
230
+ s: CharSequence,
231
+ endCursorPosition: Int,
232
+ ) {
233
+ val mentionHandler = view.mentionHandler ?: return
234
+ val currentWord = getWordAtIndex(s, endCursorPosition) ?: return
235
+ val spannable = view.text as Spannable
236
+
237
+ val indicatorsPattern = mentionIndicators.joinToString("|") { Regex.escape(it) }
238
+ val mentionIndicatorRegex = Regex("^($indicatorsPattern)")
239
+ val mentionRegex = Regex("^($indicatorsPattern)\\w*")
240
+
241
+ var indicator: String
242
+ var finalStart: Int
243
+ val finalEnd = currentWord.end
244
+
245
+ // No mention in the current word, check previous one
246
+ if (!mentionRegex.matches(currentWord.text)) {
247
+ val previousWord = getWordAtIndex(spannable, currentWord.start - 1)
248
+
249
+ // No previous word -> no mention to be detected
250
+ if (previousWord == null) {
251
+ mentionHandler.endMention()
252
+ return
253
+ }
254
+
255
+ // Previous word is not a mention -> end mention
256
+ if (!mentionRegex.matches(previousWord.text)) {
257
+ mentionHandler.endMention()
258
+ return
259
+ }
260
+
261
+ // Previous word is a mention -> use it
262
+ finalStart = previousWord.start
263
+ indicator = mentionIndicatorRegex.find(previousWord.text)?.value ?: ""
264
+ } else {
265
+ // Current word is a mention -> use it
266
+ finalStart = currentWord.start
267
+ indicator = mentionIndicatorRegex.find(currentWord.text)?.value ?: ""
268
+ }
269
+
270
+ // Mirror iOS conflicting-styles behaviour: check the full candidate range for
271
+ // a finalized mention span. If the span's stored text still matches what is in
272
+ // the buffer the mention is intact — block the event (covers HTML-loaded
273
+ // mentions and typing adjacent to a freshly-selected mention).
274
+ // If the span is stale (user edited inside it), remove it and record mentionStart
275
+ // so setMentionSpan can replace text correctly when the user picks a new mention.
276
+ val rangeSpans = spannable.getSpans(finalStart, finalEnd, EnrichedInputMentionSpan::class.java)
277
+ for (span in rangeSpans) {
278
+ val spanStart = spannable.getSpanStart(span)
279
+ val spanEnd = spannable.getSpanEnd(span)
280
+ val currentSpanText = spannable.subSequence(spanStart, spanEnd).toString()
281
+ if (currentSpanText == span.getText()) {
282
+ mentionHandler.endMention()
283
+ return
284
+ }
285
+ spannable.removeSpan(span)
286
+ mentionStart = spanStart
287
+ }
288
+
289
+ // Extract text without indicator
290
+ val text = spannable.subSequence(finalStart, finalEnd).toString().replaceFirst(indicator, "")
291
+
292
+ // Means we are starting mention
293
+ if (text.isEmpty()) {
294
+ mentionStart = finalStart
295
+ }
296
+
297
+ mentionHandler.onMention(indicator, text)
298
+ }
299
+
300
+ fun setImageSpan(
301
+ src: String,
302
+ width: Float,
303
+ height: Float,
304
+ ) {
305
+ if (view.selection == null) return
306
+ val spannable = view.text as SpannableStringBuilder
307
+ val (start, originalEnd) = view.selection.getInlineSelection()
308
+
309
+ if (start == originalEnd) {
310
+ spannable.insert(start, EnrichedConstants.ORC_STRING)
311
+ } else {
312
+ val spans = spannable.getSpans(start, originalEnd, EnrichedInputImageSpan::class.java)
313
+ for (s in spans) {
314
+ spannable.removeSpan(s)
315
+ }
316
+
317
+ spannable.replace(start, originalEnd, EnrichedConstants.ORC_STRING)
318
+ }
319
+
320
+ val (imageStart, imageEnd) = spannable.getSafeSpanBoundaries(start, start + 1)
321
+ val span = EnrichedInputImageSpan.createEnrichedImageSpan(src, width.toInt(), height.toInt())
322
+ span.observeAsyncDrawableLoaded(view.text)
323
+
324
+ spannable.setSpan(span, imageStart, imageEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
325
+ }
326
+
327
+ fun startMention(indicator: String) {
328
+ val selection = view.selection ?: return
329
+
330
+ val spannable = view.text as SpannableStringBuilder
331
+ val (start, end) = selection.getInlineSelection()
332
+
333
+ if (start == end) {
334
+ spannable.insert(start, indicator)
335
+ } else {
336
+ spannable.replace(start, end, indicator)
337
+ }
338
+ }
339
+
340
+ fun setMentionSpan(
341
+ indicator: String,
342
+ text: String,
343
+ attributes: Map<String, String>,
344
+ ) {
345
+ val selection = view.selection ?: return
346
+
347
+ val spannable = view.text as SpannableStringBuilder
348
+ val (selectionStart, selectionEnd) = selection.getInlineSelection()
349
+ val spans = spannable.getSpans(selectionStart, selectionEnd, EnrichedInputMentionSpan::class.java)
350
+
351
+ for (span in spans) {
352
+ spannable.removeSpan(span)
353
+ }
354
+
355
+ val start = mentionStart ?: return
356
+
357
+ view.runAsATransaction {
358
+ spannable.replace(start, selectionEnd, text)
359
+
360
+ val span = EnrichedInputMentionSpan(text, indicator, attributes, view.htmlStyle)
361
+ val spanEnd = start + text.length
362
+ val (safeStart, safeEnd) = spannable.getSafeSpanBoundaries(start, spanEnd)
363
+ spannable.setSpan(span, safeStart, safeEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
364
+
365
+ val hasSpaceAtTheEnd = spannable.length > safeEnd && spannable[safeEnd] == ' '
366
+ if (!hasSpaceAtTheEnd) {
367
+ spannable.insert(safeEnd, " ")
368
+ }
369
+ }
370
+
371
+ view.mentionHandler?.reset()
372
+ view.selection.validateStyles()
373
+ }
374
+
375
+ fun getStyleRange(): Pair<Int, Int> = view.selection?.getInlineSelection() ?: Pair(0, 0)
376
+
377
+ fun removeStyle(
378
+ name: String,
379
+ start: Int,
380
+ end: Int,
381
+ ): Boolean {
382
+ val config = EnrichedSpans.parametrizedStyles[name] ?: return false
383
+ val spannable = view.text as Spannable
384
+ return removeSpansForRange(spannable, start, end, config.clazz)
385
+ }
386
+
387
+ companion object {
388
+ data class TextRange(
389
+ val text: String,
390
+ val start: Int,
391
+ val end: Int,
392
+ )
393
+ }
394
+ }
@@ -0,0 +1,17 @@
1
+ package com.swmansion.enriched.textinput.utils
2
+
3
+ import android.text.Editable
4
+ import android.text.Spannable
5
+ import android.text.SpannableStringBuilder
6
+ import com.swmansion.enriched.textinput.watchers.EnrichedSpanWatcher
7
+
8
+ class EnrichedEditableFactory(
9
+ private val watcher: EnrichedSpanWatcher,
10
+ ) : Editable.Factory() {
11
+ override fun newEditable(source: CharSequence): Editable {
12
+ val s = source as? SpannableStringBuilder ?: SpannableStringBuilder(source)
13
+ s.removeSpan(watcher)
14
+ s.setSpan(watcher, 0, s.length, Spannable.SPAN_INCLUSIVE_INCLUSIVE)
15
+ return s
16
+ }
17
+ }