@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,65 @@
1
+ #import "ColorExtension.h"
2
+ #import "EnrichedTextInputView.h"
3
+ #import "FontExtension.h"
4
+ #import "RangeUtils.h"
5
+ #import "StyleHeaders.h"
6
+
7
+ @implementation InlineCodeStyle
8
+
9
+ + (StyleType)getType {
10
+ return InlineCode;
11
+ }
12
+
13
+ - (NSString *)getKey {
14
+ return @"EnrichedInlineCode";
15
+ }
16
+
17
+ - (BOOL)isParagraph {
18
+ return NO;
19
+ }
20
+
21
+ - (void)applyStyling:(NSRange)range {
22
+ // we don't want to apply inline code to newline characters, it looks bad
23
+ NSArray *nonNewlineRanges =
24
+ [RangeUtils getNonNewlineRangesIn:self.input->textView range:range];
25
+
26
+ for (NSValue *value in nonNewlineRanges) {
27
+ NSRange subRange = [value rangeValue];
28
+
29
+ [self.input->textView.textStorage
30
+ addAttribute:NSBackgroundColorAttributeName
31
+ value:[[self.input->config inlineCodeBgColor]
32
+ colorWithAlphaIfNotTransparent:0.4]
33
+ range:subRange];
34
+ [self.input->textView.textStorage
35
+ addAttribute:NSForegroundColorAttributeName
36
+ value:[self.input->config inlineCodeFgColor]
37
+ range:subRange];
38
+ [self.input->textView.textStorage
39
+ addAttribute:NSUnderlineColorAttributeName
40
+ value:[self.input->config inlineCodeFgColor]
41
+ range:subRange];
42
+ [self.input->textView.textStorage
43
+ addAttribute:NSStrikethroughColorAttributeName
44
+ value:[self.input->config inlineCodeFgColor]
45
+ range:subRange];
46
+ [self.input->textView.textStorage
47
+ enumerateAttribute:NSFontAttributeName
48
+ inRange:subRange
49
+ options:0
50
+ usingBlock:^(id _Nullable value, NSRange fontRange,
51
+ BOOL *_Nonnull stop) {
52
+ UIFont *font = (UIFont *)value;
53
+ if (font != nullptr) {
54
+ UIFont *newFont = [[[self.input->config monospacedFont]
55
+ withFontTraits:font] setSize:font.pointSize];
56
+ [self.input->textView.textStorage
57
+ addAttribute:NSFontAttributeName
58
+ value:newFont
59
+ range:fontRange];
60
+ }
61
+ }];
62
+ }
63
+ }
64
+
65
+ @end
@@ -0,0 +1,37 @@
1
+ #import "EnrichedTextInputView.h"
2
+ #import "FontExtension.h"
3
+ #import "StyleHeaders.h"
4
+
5
+ @implementation ItalicStyle : StyleBase
6
+
7
+ + (StyleType)getType {
8
+ return Italic;
9
+ }
10
+
11
+ - (NSString *)getKey {
12
+ return @"EnrichedItalic";
13
+ }
14
+
15
+ - (BOOL)isParagraph {
16
+ return NO;
17
+ }
18
+
19
+ - (void)applyStyling:(NSRange)range {
20
+ [self.input->textView.textStorage
21
+ enumerateAttribute:NSFontAttributeName
22
+ inRange:range
23
+ options:0
24
+ usingBlock:^(id _Nullable value, NSRange range,
25
+ BOOL *_Nonnull stop) {
26
+ UIFont *font = (UIFont *)value;
27
+ if (font != nullptr) {
28
+ UIFont *newFont = [font setItalic];
29
+ [self.input->textView.textStorage
30
+ addAttribute:NSFontAttributeName
31
+ value:newFont
32
+ range:range];
33
+ }
34
+ }];
35
+ }
36
+
37
+ @end
@@ -0,0 +1,532 @@
1
+ #import "AttributeEntry.h"
2
+ #import "EnrichedTextInputView.h"
3
+ #import "LinkData.h"
4
+ #import "OccurenceUtils.h"
5
+ #import "StyleHeaders.h"
6
+ #import "TextInsertionUtils.h"
7
+ #import "UIView+React.h"
8
+ #import "WordsUtils.h"
9
+
10
+ static NSString *const ManualLinkAttributeName = @"EnrichedManualLink";
11
+ static NSString *const AutomaticLinkAttributeName = @"EnrichedAutomaticLink";
12
+
13
+ @implementation LinkStyle
14
+
15
+ + (StyleType)getType {
16
+ return Link;
17
+ }
18
+
19
+ - (NSString *)getKey {
20
+ return ManualLinkAttributeName;
21
+ }
22
+
23
+ - (BOOL)isParagraph {
24
+ return NO;
25
+ }
26
+
27
+ - (void)applyStyling:(NSRange)range {
28
+ LinkData *data = [self getLinkDataAt:range.location];
29
+ if (data == nullptr || data.url == nullptr) {
30
+ return;
31
+ }
32
+
33
+ NSMutableDictionary *newAttrs = [[NSMutableDictionary alloc] init];
34
+ newAttrs[NSForegroundColorAttributeName] = [self.input->config linkColor];
35
+ newAttrs[NSUnderlineColorAttributeName] = [self.input->config linkColor];
36
+ newAttrs[NSStrikethroughColorAttributeName] = [self.input->config linkColor];
37
+ if ([self.input->config linkDecorationLine] == DecorationUnderline) {
38
+ newAttrs[NSUnderlineStyleAttributeName] = @(NSUnderlineStyleSingle);
39
+ }
40
+ [self.input->textView.textStorage addAttributes:newAttrs range:range];
41
+ }
42
+
43
+ - (void)reapplyFromStylePair:(StylePair *)pair {
44
+ NSRange range = [pair.rangeValue rangeValue];
45
+ LinkData *linkData = (LinkData *)pair.styleValue;
46
+
47
+ if (linkData == nullptr) {
48
+ return;
49
+ }
50
+
51
+ [self applyLinkMetaWithData:linkData range:range];
52
+ }
53
+
54
+ // we don't want the link to be extended, thus returning nullptr here.
55
+ - (AttributeEntry *)getEntryIfPresent:(NSRange)range {
56
+ return nullptr;
57
+ }
58
+
59
+ - (void)toggle:(NSRange)range {
60
+ // no-op for links
61
+ }
62
+
63
+ // we have to make sure all links in the range get fully removed here
64
+ - (void)remove:(NSRange)range withDirtyRange:(BOOL)withDirtyRange {
65
+ NSArray<StylePair *> *links = [self all:range];
66
+ [self.input->textView.textStorage beginEditing];
67
+ for (StylePair *pair in links) {
68
+ NSRange linkRange =
69
+ [self getFullLinkRangeAt:[pair.rangeValue rangeValue].location];
70
+ [self.input->textView.textStorage removeAttribute:ManualLinkAttributeName
71
+ range:linkRange];
72
+ [self.input->textView.textStorage removeAttribute:AutomaticLinkAttributeName
73
+ range:linkRange];
74
+ if (withDirtyRange) {
75
+ [self.input->attributesManager addDirtyRange:linkRange];
76
+ }
77
+ }
78
+ [self.input->textView.textStorage endEditing];
79
+ [self removeLinkMetaFromTypingAttributes];
80
+ }
81
+
82
+ // used for conflicts, we have to remove the whole link
83
+ - (void)removeTyping {
84
+ NSRange linkRange =
85
+ [self getFullLinkRangeAt:self.input->textView.selectedRange.location];
86
+ if (linkRange.length > 0) {
87
+ [self.input->textView.textStorage beginEditing];
88
+ [self.input->textView.textStorage removeAttribute:ManualLinkAttributeName
89
+ range:linkRange];
90
+ [self.input->textView.textStorage removeAttribute:AutomaticLinkAttributeName
91
+ range:linkRange];
92
+ [self.input->textView.textStorage endEditing];
93
+ [self.input->attributesManager addDirtyRange:linkRange];
94
+ }
95
+ [self removeLinkMetaFromTypingAttributes];
96
+ }
97
+
98
+ - (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
99
+ LinkData *linkData = (LinkData *)value;
100
+ return linkData != nullptr;
101
+ }
102
+
103
+ - (BOOL)detect:(NSRange)range {
104
+ if (range.length >= 1) {
105
+ BOOL onlyLinks = [OccurenceUtils
106
+ detectMultiple:@[ ManualLinkAttributeName, AutomaticLinkAttributeName ]
107
+ withInput:self.input
108
+ inRange:range
109
+ withCondition:^BOOL(id _Nullable value, NSRange subrange) {
110
+ return [self styleCondition:value range:subrange];
111
+ }];
112
+ return onlyLinks ? [self isSingleLinkIn:range] : NO;
113
+ }
114
+ return [self getLinkDataAt:range.location] != nullptr;
115
+ }
116
+
117
+ - (BOOL)any:(NSRange)range {
118
+ return [OccurenceUtils
119
+ anyMultiple:@[ ManualLinkAttributeName, AutomaticLinkAttributeName ]
120
+ withInput:self.input
121
+ inRange:range
122
+ withCondition:^BOOL(id _Nullable value, NSRange subrange) {
123
+ return [self styleCondition:value range:subrange];
124
+ }];
125
+ }
126
+
127
+ - (NSArray<StylePair *> *)all:(NSRange)range {
128
+ return [OccurenceUtils
129
+ allMultiple:@[ ManualLinkAttributeName, AutomaticLinkAttributeName ]
130
+ withInput:self.input
131
+ inRange:range
132
+ withCondition:^BOOL(id _Nullable value, NSRange subrange) {
133
+ return [self styleCondition:value range:subrange];
134
+ }];
135
+ }
136
+
137
+ - (void)applyLinkMetaWithData:(LinkData *)linkData range:(NSRange)range {
138
+ if (range.length == 0 || linkData.url == nullptr) {
139
+ return;
140
+ }
141
+ NSString *key =
142
+ linkData.isManual ? ManualLinkAttributeName : AutomaticLinkAttributeName;
143
+ [self.input->textView.textStorage addAttribute:key
144
+ value:[linkData copy]
145
+ range:range];
146
+ }
147
+
148
+ - (void)removeLinkMetaFromTypingAttributes {
149
+ NSMutableDictionary *newTypingAttrs =
150
+ [self.input->textView.typingAttributes mutableCopy];
151
+ [newTypingAttrs removeObjectForKey:ManualLinkAttributeName];
152
+ [newTypingAttrs removeObjectForKey:AutomaticLinkAttributeName];
153
+ self.input->textView.typingAttributes = newTypingAttrs;
154
+
155
+ [self.input->attributesManager
156
+ didRemoveTypingAttribute:ManualLinkAttributeName];
157
+ [self.input->attributesManager
158
+ didRemoveTypingAttribute:AutomaticLinkAttributeName];
159
+ }
160
+
161
+ - (void)addLink:(LinkData *)linkData
162
+ range:(NSRange)range
163
+ withSelection:(BOOL)withSelection {
164
+ NSString *currentText =
165
+ [self.input->textView.textStorage.string substringWithRange:range];
166
+
167
+ NSString *key =
168
+ linkData.isManual ? ManualLinkAttributeName : AutomaticLinkAttributeName;
169
+ NSDictionary *metaAttrs = @{key : [linkData copy]};
170
+
171
+ NSRange dirtyRange = NSMakeRange(0, 0);
172
+
173
+ if (range.length == 0) {
174
+ // insert link
175
+ [TextInsertionUtils insertText:linkData.text
176
+ at:range.location
177
+ additionalAttributes:metaAttrs
178
+ input:self.input
179
+ withSelection:withSelection];
180
+ dirtyRange = NSMakeRange(range.location, linkData.text.length);
181
+ } else if ([currentText isEqualToString:linkData.text]) {
182
+ [self applyLinkMetaWithData:linkData range:range];
183
+ dirtyRange = range;
184
+ // TextInsertionUtils take care of the selection but here we have to
185
+ // manually set it behind the link ONLY with manual links, automatic ones
186
+ // don't need the selection fix
187
+ if (linkData.isManual && withSelection) {
188
+ [self.input->textView reactFocus];
189
+ self.input->textView.selectedRange =
190
+ NSMakeRange(range.location + linkData.text.length, 0);
191
+ }
192
+ } else {
193
+ // replace text with link
194
+ [TextInsertionUtils replaceText:linkData.text
195
+ at:range
196
+ additionalAttributes:metaAttrs
197
+ input:self.input
198
+ withSelection:withSelection];
199
+ dirtyRange = NSMakeRange(range.location, linkData.text.length);
200
+ }
201
+
202
+ // add new dirty range
203
+ [self.input->attributesManager addDirtyRange:dirtyRange];
204
+
205
+ // mandatory connected links check
206
+ NSDictionary *currentWord =
207
+ [WordsUtils getCurrentWord:self.input->textView.textStorage.string
208
+ range:self.input->textView.selectedRange];
209
+ if (currentWord != nullptr) {
210
+ // get word properties
211
+ NSString *wordText = (NSString *)[currentWord objectForKey:@"word"];
212
+ NSValue *wordRangeValue = (NSValue *)[currentWord objectForKey:@"range"];
213
+ if (wordText != nullptr && wordRangeValue != nullptr) {
214
+ [self removeConnectedLinksIfNeeded:wordText
215
+ range:[wordRangeValue rangeValue]];
216
+ }
217
+ }
218
+ }
219
+
220
+ // get exact link data at the given location if it exists
221
+ - (LinkData *)getLinkDataAt:(NSUInteger)location {
222
+ NSRange manualLinkRange = NSMakeRange(0, 0);
223
+ NSRange automaticLinkRange = NSMakeRange(0, 0);
224
+ NSRange inputRange = NSMakeRange(0, self.input->textView.textStorage.length);
225
+
226
+ // don't search at the very end of input
227
+ NSUInteger searchLocation = location;
228
+ if (searchLocation == self.input->textView.textStorage.length) {
229
+ return nullptr;
230
+ }
231
+
232
+ LinkData *manualData =
233
+ [self.input->textView.textStorage attribute:ManualLinkAttributeName
234
+ atIndex:searchLocation
235
+ longestEffectiveRange:&manualLinkRange
236
+ inRange:inputRange];
237
+ LinkData *automaticData =
238
+ [self.input->textView.textStorage attribute:AutomaticLinkAttributeName
239
+ atIndex:searchLocation
240
+ longestEffectiveRange:&automaticLinkRange
241
+ inRange:inputRange];
242
+
243
+ if ((manualData == nullptr && automaticData == nullptr) ||
244
+ (manualLinkRange.length == 0 && automaticLinkRange.length == 0)) {
245
+ return nullptr;
246
+ }
247
+
248
+ return manualData == nullptr ? automaticData : manualData;
249
+ }
250
+
251
+ // returns full range of a link at some location
252
+ - (NSRange)getFullLinkRangeAt:(NSUInteger)location {
253
+ NSRange manualLinkRange = NSMakeRange(0, 0);
254
+ NSRange automaticLinkRange = NSMakeRange(0, 0);
255
+ NSRange inputRange = NSMakeRange(0, self.input->textView.textStorage.length);
256
+
257
+ // get the previous index if possible when at the very end of input
258
+ NSUInteger searchLocation = location;
259
+ if (searchLocation == self.input->textView.textStorage.length) {
260
+ if (searchLocation == 0) {
261
+ return NSMakeRange(0, 0);
262
+ }
263
+ searchLocation = searchLocation - 1;
264
+ }
265
+
266
+ LinkData *manualData =
267
+ [self.input->textView.textStorage attribute:ManualLinkAttributeName
268
+ atIndex:searchLocation
269
+ longestEffectiveRange:&manualLinkRange
270
+ inRange:inputRange];
271
+ LinkData *automaticData =
272
+ [self.input->textView.textStorage attribute:AutomaticLinkAttributeName
273
+ atIndex:searchLocation
274
+ longestEffectiveRange:&automaticLinkRange
275
+ inRange:inputRange];
276
+
277
+ return manualData == nullptr
278
+ ? automaticData == nullptr ? NSMakeRange(0, 0) : automaticLinkRange
279
+ : manualLinkRange;
280
+ }
281
+
282
+ // handles detecting and removing automatic links
283
+ - (void)handleAutomaticLinks:(NSString *)word inRange:(NSRange)wordRange {
284
+ LinkRegexConfig *linkRegexConfig = [self.input->config linkRegexConfig];
285
+
286
+ // no automatic links with isDisabled
287
+ if (linkRegexConfig.isDisabled) {
288
+ return;
289
+ }
290
+
291
+ InlineCodeStyle *inlineCodeStyle =
292
+ [self.input->stylesDict objectForKey:@([InlineCodeStyle getType])];
293
+ MentionStyle *mentionStyle =
294
+ [self.input->stylesDict objectForKey:@([MentionStyle getType])];
295
+ CodeBlockStyle *codeBlockStyle =
296
+ [self.input->stylesDict objectForKey:@([CodeBlockStyle getType])];
297
+
298
+ // we don't recognize links along mentions, inline code or codeblocks
299
+ if (mentionStyle != nullptr && [mentionStyle any:wordRange]) {
300
+ return;
301
+ }
302
+ if (inlineCodeStyle != nullptr && [inlineCodeStyle any:wordRange]) {
303
+ return;
304
+ }
305
+ if (codeBlockStyle != nullptr && [codeBlockStyle any:wordRange]) {
306
+ return;
307
+ }
308
+
309
+ // remove connected different links
310
+ [self removeConnectedLinksIfNeeded:word range:wordRange];
311
+
312
+ // we don't recognize automatic links along manual ones
313
+ __block BOOL manualLinkPresent = NO;
314
+ [self.input->textView.textStorage
315
+ enumerateAttribute:ManualLinkAttributeName
316
+ inRange:wordRange
317
+ options:0
318
+ usingBlock:^(id value, NSRange subrange, BOOL *stop) {
319
+ if ([self styleCondition:value range:subrange]) {
320
+ manualLinkPresent = YES;
321
+ *stop = YES;
322
+ }
323
+ }];
324
+ if (manualLinkPresent) {
325
+ return;
326
+ }
327
+
328
+ // all conditions are met; try matching the word to a proper regex
329
+
330
+ NSString *regexPassedUrl = nullptr;
331
+ NSRange matchingRange = NSMakeRange(0, word.length);
332
+
333
+ if (linkRegexConfig.isDefault) {
334
+ // use default regex
335
+ regexPassedUrl = [self tryMatchingDefaultLinkRegex:word
336
+ matchRange:matchingRange];
337
+ } else {
338
+ // use user defined regex if it exists
339
+ NSRegularExpression *userRegex = [self.input->config parsedLinkRegex];
340
+
341
+ if (userRegex == nullptr) {
342
+ // fallback to default regex
343
+ regexPassedUrl = [self tryMatchingDefaultLinkRegex:word
344
+ matchRange:matchingRange];
345
+ } else if ([userRegex numberOfMatchesInString:word
346
+ options:0
347
+ range:matchingRange]) {
348
+ regexPassedUrl = word;
349
+ }
350
+ }
351
+
352
+ if (regexPassedUrl != nullptr) {
353
+ // add style only if needed
354
+ BOOL addStyle = YES;
355
+ if ([self detect:wordRange]) {
356
+ LinkData *currentData = [self getLinkDataAt:wordRange.location];
357
+ if (currentData != nullptr && currentData.url != nullptr &&
358
+ [currentData.url isEqualToString:regexPassedUrl]) {
359
+ addStyle = NO;
360
+ }
361
+ }
362
+ if (addStyle) {
363
+ LinkData *newData = [[LinkData alloc] init];
364
+ newData.text = word;
365
+ newData.url = regexPassedUrl;
366
+ newData.isManual = NO;
367
+
368
+ [self addLink:newData range:wordRange withSelection:NO];
369
+
370
+ // emit onLinkDetected if style was added
371
+ [self.input emitOnLinkDetectedEvent:newData range:wordRange];
372
+ }
373
+ } else if ([self any:wordRange]) {
374
+ // there was some automatic link (because anyOccurence is true and we are
375
+ // sure there are no manual links) still, it didn't pass any regex - needs
376
+ // to be removed
377
+ [self remove:wordRange withDirtyRange:YES];
378
+ }
379
+ }
380
+
381
+ - (NSString *)tryMatchingDefaultLinkRegex:(NSString *)word
382
+ matchRange:(NSRange)range {
383
+ if ([[LinkStyle fullRegex] numberOfMatchesInString:word
384
+ options:0
385
+ range:range] ||
386
+ [[LinkStyle wwwRegex] numberOfMatchesInString:word
387
+ options:0
388
+ range:range] ||
389
+ [[LinkStyle bareRegex] numberOfMatchesInString:word
390
+ options:0
391
+ range:range]) {
392
+ return word;
393
+ }
394
+
395
+ return nullptr;
396
+ }
397
+
398
+ // handles refreshing manual links
399
+ - (void)handleManualLinks:(NSString *)word inRange:(NSRange)wordRange {
400
+ // look for manual links within the word
401
+ __block LinkData *manualLinkMinValue = nullptr;
402
+ __block LinkData *manualLinkMaxValue = nullptr;
403
+ __block NSInteger manualLinkMinIdx = -1;
404
+ __block NSInteger manualLinkMaxIdx = -1;
405
+
406
+ [self.input->textView.textStorage
407
+ enumerateAttribute:ManualLinkAttributeName
408
+ inRange:wordRange
409
+ options:0
410
+ usingBlock:^(id value, NSRange range, BOOL *stop) {
411
+ LinkData *linkDataValue = (LinkData *)value;
412
+ if (linkDataValue != nullptr) {
413
+ NSInteger linkMin = range.location;
414
+ NSInteger linkMax = range.location + range.length - 1;
415
+ if (manualLinkMinIdx == -1 || linkMin < manualLinkMinIdx) {
416
+ manualLinkMinIdx = linkMin;
417
+ manualLinkMinValue = linkDataValue;
418
+ }
419
+ if (manualLinkMaxIdx == -1 || linkMax > manualLinkMaxIdx) {
420
+ manualLinkMaxIdx = linkMax;
421
+ manualLinkMaxValue = linkDataValue;
422
+ }
423
+ }
424
+ }];
425
+
426
+ // no manual links
427
+ if (manualLinkMinIdx == -1 || manualLinkMaxIdx == -1) {
428
+ return;
429
+ }
430
+
431
+ // heuristic for refreshing manual links:
432
+ // we update the Manual attribute between the bounds of existing ones
433
+ // we do that only if the bounds point to the same url
434
+ // this way manual link gets "extended" only if some characters were added
435
+ // inside it
436
+ if ([manualLinkMinValue isEqualToLinkData:manualLinkMaxValue]) {
437
+ NSRange newRange =
438
+ NSMakeRange(manualLinkMinIdx, manualLinkMaxIdx - manualLinkMinIdx + 1);
439
+ [self applyLinkMetaWithData:manualLinkMinValue range:newRange];
440
+ [self.input->attributesManager addDirtyRange:newRange];
441
+ }
442
+ }
443
+
444
+ // MARK: - Private non-standard methods
445
+
446
+ // determines whether a given range contains only links pointing to one url
447
+ // assumes the whole range is links only already
448
+ - (BOOL)isSingleLinkIn:(NSRange)range {
449
+ return [self all:range].count == 1;
450
+ }
451
+
452
+ - (void)removeConnectedLinksIfNeeded:(NSString *)word range:(NSRange)wordRange {
453
+ BOOL anyAutomatic =
454
+ [OccurenceUtils any:AutomaticLinkAttributeName
455
+ withInput:self.input
456
+ inRange:wordRange
457
+ withCondition:^BOOL(id _Nullable value, NSRange subrange) {
458
+ return [self styleCondition:value range:subrange];
459
+ }];
460
+ BOOL anyManual =
461
+ [OccurenceUtils any:ManualLinkAttributeName
462
+ withInput:self.input
463
+ inRange:wordRange
464
+ withCondition:^BOOL(id _Nullable value, NSRange subrange) {
465
+ return [self styleCondition:value range:subrange];
466
+ }];
467
+
468
+ // both manual and automatic links are somewhere - delete!
469
+ if (anyAutomatic && anyManual) {
470
+ [self remove:wordRange withDirtyRange:YES];
471
+ }
472
+
473
+ // we are now sure there is only one type of link there - and make sure it
474
+ // covers the whole word
475
+ BOOL onlyLinks = [OccurenceUtils
476
+ detectMultiple:@[ ManualLinkAttributeName, AutomaticLinkAttributeName ]
477
+ withInput:self.input
478
+ inRange:wordRange
479
+ withCondition:^BOOL(id _Nullable value, NSRange r) {
480
+ return [self styleCondition:value range:r];
481
+ }];
482
+
483
+ // only one link might be present!
484
+ if (onlyLinks && ![self isSingleLinkIn:wordRange]) {
485
+ [self remove:wordRange withDirtyRange:YES];
486
+ }
487
+ }
488
+
489
+ + (NSRegularExpression *)fullRegex {
490
+ static NSRegularExpression *regex;
491
+ static dispatch_once_t onceToken;
492
+ dispatch_once(&onceToken, ^{
493
+ regex =
494
+ [NSRegularExpression regularExpressionWithPattern:
495
+ @"http(s)?:\\/\\/"
496
+ @"www\\.[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-"
497
+ @"z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"
498
+ options:0
499
+ error:nullptr];
500
+ });
501
+ return regex;
502
+ }
503
+
504
+ + (NSRegularExpression *)wwwRegex {
505
+ static NSRegularExpression *regex;
506
+ static dispatch_once_t onceToken;
507
+ dispatch_once(&onceToken, ^{
508
+ regex =
509
+ [NSRegularExpression regularExpressionWithPattern:
510
+ @"www\\.[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-"
511
+ @"z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"
512
+ options:0
513
+ error:nullptr];
514
+ });
515
+ return regex;
516
+ }
517
+
518
+ + (NSRegularExpression *)bareRegex {
519
+ static NSRegularExpression *regex;
520
+ static dispatch_once_t onceToken;
521
+ dispatch_once(&onceToken, ^{
522
+ regex =
523
+ [NSRegularExpression regularExpressionWithPattern:
524
+ @"[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-z]{2,"
525
+ @"6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"
526
+ options:0
527
+ error:nullptr];
528
+ });
529
+ return regex;
530
+ }
531
+
532
+ @end