react-native-enriched 0.2.1 → 0.4.0

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 (263) hide show
  1. package/README.md +21 -16
  2. package/android/build.gradle +77 -72
  3. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +21 -0
  4. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +7 -0
  5. package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ComponentDescriptors.cpp +1 -1
  6. package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ComponentDescriptors.h +1 -1
  7. package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/EventEmitters.cpp +276 -0
  8. package/android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec/EventEmitters.h +239 -0
  9. package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/Props.cpp +10 -0
  10. package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/Props.h +251 -0
  11. package/android/gradle.properties +5 -5
  12. package/android/lint.gradle +70 -0
  13. package/android/src/main/java/com/swmansion/enriched/{EnrichedTextInputViewPackage.kt → ReactNativeEnrichedPackage.kt} +4 -5
  14. package/android/src/main/java/com/swmansion/enriched/{utils → common}/AsyncDrawable.kt +50 -15
  15. package/android/src/main/java/com/swmansion/enriched/common/CheckboxDrawable.kt +81 -0
  16. package/android/src/main/java/com/swmansion/enriched/common/EnrichedConstants.kt +11 -0
  17. package/android/src/main/java/com/swmansion/enriched/common/EnrichedStyle.kt +57 -0
  18. package/android/src/main/java/com/swmansion/enriched/{spans/utils → common}/ForceRedrawSpan.kt +3 -2
  19. package/android/src/main/java/com/swmansion/enriched/common/MentionStyle.kt +7 -0
  20. package/android/src/main/java/com/swmansion/enriched/{utils → common}/ResourceManager.kt +1 -1
  21. package/android/src/main/java/com/swmansion/enriched/{utils → common/parser}/EnrichedParser.java +228 -160
  22. package/android/src/main/java/com/swmansion/enriched/common/parser/EnrichedSpanFactory.kt +79 -0
  23. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedBlockQuoteSpan.kt +53 -0
  24. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedBoldSpan.kt +12 -0
  25. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedCheckboxListSpan.kt +91 -0
  26. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/EnrichedCodeBlockSpan.kt +12 -14
  27. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH1Span.kt +20 -0
  28. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH2Span.kt +20 -0
  29. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH3Span.kt +20 -0
  30. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH4Span.kt +21 -0
  31. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH5Span.kt +20 -0
  32. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH6Span.kt +20 -0
  33. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/EnrichedImageSpan.kt +68 -51
  34. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedInlineCodeSpan.kt +24 -0
  35. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedItalicSpan.kt +12 -0
  36. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedLinkSpan.kt +26 -0
  37. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedMentionSpan.kt +35 -0
  38. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/EnrichedOrderedListSpan.kt +21 -29
  39. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedStrikeThroughSpan.kt +11 -0
  40. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedUnderlineSpan.kt +11 -0
  41. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/EnrichedUnorderedListSpan.kt +13 -17
  42. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedBlockSpan.kt +5 -0
  43. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedHeadingSpan.kt +3 -0
  44. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedInlineSpan.kt +3 -0
  45. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedParagraphSpan.kt +5 -0
  46. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedSpan.kt +3 -0
  47. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/interfaces/EnrichedZeroWidthSpaceSpan.kt +2 -3
  48. package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputConnectionWrapper.kt +140 -0
  49. package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputSpannableFactory.kt +83 -0
  50. package/android/src/main/java/com/swmansion/enriched/{EnrichedTextInputView.kt → textinput/EnrichedTextInputView.kt} +322 -157
  51. package/android/src/main/java/com/swmansion/enriched/{EnrichedTextInputViewLayoutManager.kt → textinput/EnrichedTextInputViewLayoutManager.kt} +4 -2
  52. package/android/src/main/java/com/swmansion/enriched/{EnrichedTextInputViewManager.kt → textinput/EnrichedTextInputViewManager.kt} +182 -66
  53. package/android/src/main/java/com/swmansion/enriched/{MeasurementStore.kt → textinput/MeasurementStore.kt} +75 -25
  54. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/MentionHandler.kt +22 -12
  55. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnChangeHtmlEvent.kt +27 -0
  56. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnChangeSelectionEvent.kt +11 -10
  57. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnChangeStateEvent.kt +21 -0
  58. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnChangeTextEvent.kt +30 -0
  59. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnInputBlurEvent.kt +25 -0
  60. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnInputFocusEvent.kt +25 -0
  61. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnInputKeyPressEvent.kt +27 -0
  62. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnLinkDetectedEvent.kt +32 -0
  63. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnMentionDetectedEvent.kt +11 -10
  64. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnMentionEvent.kt +10 -9
  65. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnPasteImagesEvent.kt +47 -0
  66. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnRequestHtmlResultEvent.kt +2 -3
  67. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputBlockQuoteSpan.kt +14 -0
  68. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputBoldSpan.kt +14 -0
  69. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputCheckboxListSpan.kt +15 -0
  70. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputCodeBlockSpan.kt +14 -0
  71. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH1Span.kt +14 -0
  72. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH2Span.kt +14 -0
  73. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH3Span.kt +14 -0
  74. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH4Span.kt +14 -0
  75. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH5Span.kt +14 -0
  76. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH6Span.kt +14 -0
  77. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputImageSpan.kt +36 -0
  78. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputInlineCodeSpan.kt +14 -0
  79. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputItalicSpan.kt +14 -0
  80. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputLinkSpan.kt +15 -0
  81. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputMentionSpan.kt +18 -0
  82. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputOrderedListSpan.kt +21 -0
  83. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputStrikeThroughSpan.kt +14 -0
  84. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputUnderlineSpan.kt +14 -0
  85. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputUnorderedListSpan.kt +14 -0
  86. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedSpans.kt +241 -0
  87. package/android/src/main/java/com/swmansion/enriched/textinput/spans/interfaces/EnrichedInputSpan.kt +10 -0
  88. package/android/src/main/java/com/swmansion/enriched/{styles → textinput/styles}/HtmlStyle.kt +129 -57
  89. package/android/src/main/java/com/swmansion/enriched/{styles → textinput/styles}/InlineStyles.kt +30 -13
  90. package/android/src/main/java/com/swmansion/enriched/textinput/styles/ListStyles.kt +263 -0
  91. package/android/src/main/java/com/swmansion/enriched/{styles → textinput/styles}/ParagraphStyles.kt +94 -34
  92. package/android/src/main/java/com/swmansion/enriched/{styles → textinput/styles}/ParametrizedStyles.kt +143 -67
  93. package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedEditableFactory.kt +17 -0
  94. package/android/src/main/java/com/swmansion/enriched/{utils → textinput/utils}/EnrichedSelection.kt +84 -54
  95. package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedSpanState.kt +304 -0
  96. package/android/src/main/java/com/swmansion/enriched/{utils/Utils.kt → textinput/utils/EnrichedSpannable.kt} +22 -31
  97. package/android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedSpannableStringBuilder.kt +16 -0
  98. package/android/src/main/java/com/swmansion/enriched/textinput/utils/RichContentReceiver.kt +127 -0
  99. package/android/src/main/java/com/swmansion/enriched/textinput/utils/Utils.kt +106 -0
  100. package/android/src/main/java/com/swmansion/enriched/{watchers → textinput/watchers}/EnrichedSpanWatcher.kt +56 -24
  101. package/android/src/main/java/com/swmansion/enriched/{watchers → textinput/watchers}/EnrichedTextWatcher.kt +37 -14
  102. package/android/src/main/new_arch/CMakeLists.txt +7 -1
  103. package/android/src/main/new_arch/ReactNativeEnrichedSpec.cpp +11 -0
  104. package/android/src/main/new_arch/ReactNativeEnrichedSpec.h +15 -0
  105. package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputMeasurementManager.h +1 -1
  106. package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputShadowNode.h +2 -2
  107. package/android/src/main/new_arch/react/renderer/components/ReactNativeEnrichedSpec/conversions.h +46 -0
  108. package/ios/EnrichedTextInputView.h +2 -1
  109. package/ios/EnrichedTextInputView.mm +603 -60
  110. package/ios/config/InputConfig.h +28 -0
  111. package/ios/config/InputConfig.mm +237 -8
  112. package/ios/extensions/ImageExtension.h +35 -0
  113. package/ios/extensions/ImageExtension.mm +156 -0
  114. package/ios/{utils → extensions}/LayoutManagerExtension.mm +115 -95
  115. package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ComponentDescriptors.cpp +1 -1
  116. package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ComponentDescriptors.h +1 -1
  117. package/ios/generated/ReactNativeEnrichedSpec/EventEmitters.cpp +276 -0
  118. package/ios/generated/ReactNativeEnrichedSpec/EventEmitters.h +239 -0
  119. package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/Props.cpp +10 -0
  120. package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/Props.h +251 -0
  121. package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/RCTComponentViewHelpers.h +95 -0
  122. package/ios/inputParser/InputParser.mm +218 -18
  123. package/ios/inputTextView/InputTextView.mm +118 -0
  124. package/ios/{attachments → interfaces}/ImageAttachment.h +1 -0
  125. package/ios/interfaces/ImageAttachment.mm +46 -0
  126. package/ios/interfaces/LinkRegexConfig.h +19 -0
  127. package/ios/interfaces/LinkRegexConfig.mm +37 -0
  128. package/ios/{utils → interfaces}/MentionStyleProps.mm +2 -2
  129. package/ios/{utils → interfaces}/StyleHeaders.h +22 -1
  130. package/ios/{utils → interfaces}/StyleTypeEnum.h +4 -0
  131. package/ios/internals/EnrichedTextInputViewState.cpp +6 -6
  132. package/ios/styles/BlockQuoteStyle.mm +5 -5
  133. package/ios/styles/BoldStyle.mm +21 -6
  134. package/ios/styles/CheckboxListStyle.mm +321 -0
  135. package/ios/styles/CodeBlockStyle.mm +5 -5
  136. package/ios/styles/H1Style.mm +3 -0
  137. package/ios/styles/H2Style.mm +3 -0
  138. package/ios/styles/H3Style.mm +3 -0
  139. package/ios/styles/H4Style.mm +20 -0
  140. package/ios/styles/H5Style.mm +20 -0
  141. package/ios/styles/H6Style.mm +20 -0
  142. package/ios/styles/HeadingStyleBase.mm +161 -72
  143. package/ios/styles/ImageStyle.mm +5 -5
  144. package/ios/styles/InlineCodeStyle.mm +30 -19
  145. package/ios/styles/ItalicStyle.mm +5 -5
  146. package/ios/styles/LinkStyle.mm +98 -40
  147. package/ios/styles/MentionStyle.mm +4 -4
  148. package/ios/styles/OrderedListStyle.mm +5 -5
  149. package/ios/styles/StrikethroughStyle.mm +5 -5
  150. package/ios/styles/UnderlineStyle.mm +5 -5
  151. package/ios/styles/UnorderedListStyle.mm +5 -5
  152. package/ios/utils/CheckboxHitTestUtils.h +10 -0
  153. package/ios/utils/CheckboxHitTestUtils.mm +123 -0
  154. package/ios/utils/ParagraphAttributesUtils.h +4 -0
  155. package/ios/utils/ParagraphAttributesUtils.mm +142 -45
  156. package/ios/utils/ParagraphsUtils.mm +4 -4
  157. package/ios/utils/TextBlockTapGestureRecognizer.h +17 -0
  158. package/ios/utils/TextBlockTapGestureRecognizer.mm +56 -0
  159. package/ios/utils/ZeroWidthSpaceUtils.mm +14 -3
  160. package/lib/module/EnrichedTextInput.js +57 -11
  161. package/lib/module/EnrichedTextInput.js.map +1 -1
  162. package/lib/module/{EnrichedTextInputNativeComponent.ts → spec/EnrichedTextInputNativeComponent.ts} +175 -18
  163. package/lib/module/types.js +4 -0
  164. package/lib/module/types.js.map +1 -0
  165. package/lib/module/{normalizeHtmlStyle.js → utils/normalizeHtmlStyle.js} +18 -0
  166. package/lib/module/utils/normalizeHtmlStyle.js.map +1 -0
  167. package/lib/module/utils/nullthrows.js +9 -0
  168. package/lib/module/utils/nullthrows.js.map +1 -0
  169. package/lib/module/utils/regexParser.js +46 -0
  170. package/lib/module/utils/regexParser.js.map +1 -0
  171. package/lib/typescript/src/EnrichedTextInput.d.ts +20 -51
  172. package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
  173. package/lib/typescript/src/index.d.ts +2 -1
  174. package/lib/typescript/src/index.d.ts.map +1 -1
  175. package/lib/typescript/src/{EnrichedTextInputNativeComponent.d.ts → spec/EnrichedTextInputNativeComponent.d.ts} +154 -18
  176. package/lib/typescript/src/spec/EnrichedTextInputNativeComponent.d.ts.map +1 -0
  177. package/lib/typescript/src/types.d.ts +58 -0
  178. package/lib/typescript/src/types.d.ts.map +1 -0
  179. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts +4 -0
  180. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts.map +1 -0
  181. package/lib/typescript/src/utils/nullthrows.d.ts +2 -0
  182. package/lib/typescript/src/utils/nullthrows.d.ts.map +1 -0
  183. package/lib/typescript/src/utils/regexParser.d.ts +3 -0
  184. package/lib/typescript/src/utils/regexParser.d.ts.map +1 -0
  185. package/package.json +13 -9
  186. package/src/EnrichedTextInput.tsx +88 -63
  187. package/src/index.tsx +5 -1
  188. package/src/{EnrichedTextInputNativeComponent.ts → spec/EnrichedTextInputNativeComponent.ts} +175 -18
  189. package/src/types.ts +59 -0
  190. package/src/{normalizeHtmlStyle.ts → utils/normalizeHtmlStyle.ts} +20 -5
  191. package/src/utils/nullthrows.ts +7 -0
  192. package/src/utils/regexParser.ts +56 -0
  193. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +0 -128
  194. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +0 -102
  195. package/android/src/main/java/com/swmansion/enriched/events/OnChangeHtmlEvent.kt +0 -28
  196. package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateEvent.kt +0 -24
  197. package/android/src/main/java/com/swmansion/enriched/events/OnChangeTextEvent.kt +0 -30
  198. package/android/src/main/java/com/swmansion/enriched/events/OnInputBlurEvent.kt +0 -27
  199. package/android/src/main/java/com/swmansion/enriched/events/OnInputFocusEvent.kt +0 -27
  200. package/android/src/main/java/com/swmansion/enriched/events/OnLinkDetectedEvent.kt +0 -30
  201. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +0 -44
  202. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +0 -16
  203. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +0 -23
  204. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +0 -23
  205. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +0 -23
  206. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +0 -27
  207. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +0 -15
  208. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +0 -30
  209. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +0 -42
  210. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +0 -136
  211. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +0 -14
  212. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +0 -14
  213. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedBlockSpan.kt +0 -4
  214. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedHeadingSpan.kt +0 -4
  215. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedInlineSpan.kt +0 -4
  216. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedParagraphSpan.kt +0 -4
  217. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +0 -8
  218. package/android/src/main/java/com/swmansion/enriched/styles/ListStyles.kt +0 -172
  219. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpanState.kt +0 -204
  220. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +0 -22
  221. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +0 -26
  222. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/conversions.h +0 -26
  223. package/ios/attachments/ImageAttachment.mm +0 -34
  224. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +0 -128
  225. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +0 -102
  226. package/lib/module/normalizeHtmlStyle.js.map +0 -1
  227. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +0 -1
  228. package/lib/typescript/src/normalizeHtmlStyle.d.ts +0 -4
  229. package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +0 -1
  230. /package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ShadowNodes.cpp +0 -0
  231. /package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ShadowNodes.h +0 -0
  232. /package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/States.cpp +0 -0
  233. /package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/States.h +0 -0
  234. /package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputComponentDescriptor.h +0 -0
  235. /package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputMeasurementManager.cpp +0 -0
  236. /package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputShadowNode.cpp +0 -0
  237. /package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputState.cpp +0 -0
  238. /package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputState.h +0 -0
  239. /package/ios/{utils → extensions}/ColorExtension.h +0 -0
  240. /package/ios/{utils → extensions}/ColorExtension.mm +0 -0
  241. /package/ios/{utils → extensions}/FontExtension.h +0 -0
  242. /package/ios/{utils → extensions}/FontExtension.mm +0 -0
  243. /package/ios/{utils → extensions}/LayoutManagerExtension.h +0 -0
  244. /package/ios/{utils → extensions}/StringExtension.h +0 -0
  245. /package/ios/{utils → extensions}/StringExtension.mm +0 -0
  246. /package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ShadowNodes.cpp +0 -0
  247. /package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ShadowNodes.h +0 -0
  248. /package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/States.cpp +0 -0
  249. /package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/States.h +0 -0
  250. /package/ios/{utils → interfaces}/BaseStyleProtocol.h +0 -0
  251. /package/ios/{utils → interfaces}/ImageData.h +0 -0
  252. /package/ios/{utils → interfaces}/ImageData.mm +0 -0
  253. /package/ios/{utils → interfaces}/LinkData.h +0 -0
  254. /package/ios/{utils → interfaces}/LinkData.mm +0 -0
  255. /package/ios/{attachments → interfaces}/MediaAttachment.h +0 -0
  256. /package/ios/{attachments → interfaces}/MediaAttachment.mm +0 -0
  257. /package/ios/{utils → interfaces}/MentionParams.h +0 -0
  258. /package/ios/{utils → interfaces}/MentionParams.mm +0 -0
  259. /package/ios/{utils → interfaces}/MentionStyleProps.h +0 -0
  260. /package/ios/{utils → interfaces}/StylePair.h +0 -0
  261. /package/ios/{utils → interfaces}/StylePair.mm +0 -0
  262. /package/ios/{utils → interfaces}/TextDecorationLineEnum.h +0 -0
  263. /package/ios/{utils → interfaces}/TextDecorationLineEnum.mm +0 -0
@@ -1,4 +1,5 @@
1
1
  #pragma once
2
+ #import "LinkRegexConfig.h"
2
3
  #import "MentionStyleProps.h"
3
4
  #import "TextDecorationLineEnum.h"
4
5
  #import <UIKit/UIKit.h>
@@ -29,6 +30,18 @@
29
30
  - (void)setH3FontSize:(CGFloat)newValue;
30
31
  - (BOOL)h3Bold;
31
32
  - (void)setH3Bold:(BOOL)newValue;
33
+ - (CGFloat)h4FontSize;
34
+ - (void)setH4FontSize:(CGFloat)newValue;
35
+ - (BOOL)h4Bold;
36
+ - (void)setH4Bold:(BOOL)newValue;
37
+ - (CGFloat)h5FontSize;
38
+ - (void)setH5FontSize:(CGFloat)newValue;
39
+ - (BOOL)h5Bold;
40
+ - (void)setH5Bold:(BOOL)newValue;
41
+ - (CGFloat)h6FontSize;
42
+ - (void)setH6FontSize:(CGFloat)newValue;
43
+ - (BOOL)h6Bold;
44
+ - (void)setH6Bold:(BOOL)newValue;
32
45
  - (UIColor *)blockquoteBorderColor;
33
46
  - (void)setBlockquoteBorderColor:(UIColor *)newValue;
34
47
  - (CGFloat)blockquoteBorderWidth;
@@ -70,4 +83,19 @@
70
83
  - (void)setCodeBlockBgColor:(UIColor *)newValue;
71
84
  - (CGFloat)codeBlockBorderRadius;
72
85
  - (void)setCodeBlockBorderRadius:(CGFloat)newValue;
86
+ - (LinkRegexConfig *)linkRegexConfig;
87
+ - (void)setLinkRegexConfig:(LinkRegexConfig *)newValue;
88
+ - (NSRegularExpression *)parsedLinkRegex;
89
+ - (void)invalidateFonts;
90
+ - (NSNumber *)scaledPrimaryFontSize;
91
+ - (CGFloat)checkboxListBoxSize;
92
+ - (void)setCheckboxListBoxSize:(CGFloat)newValue;
93
+ - (CGFloat)checkboxListGapWidth;
94
+ - (void)setCheckboxListGapWidth:(CGFloat)newValue;
95
+ - (CGFloat)checkboxListMarginLeft;
96
+ - (void)setCheckboxListMarginLeft:(CGFloat)newValue;
97
+ - (UIColor *)checkboxListBoxColor;
98
+ - (void)setCheckboxListBoxColor:(UIColor *)newValue;
99
+ - (UIImage *)checkboxCheckedImage;
100
+ - (UIImage *)checkboxUncheckedImage;
73
101
  @end
@@ -17,6 +17,12 @@
17
17
  BOOL _h2Bold;
18
18
  CGFloat _h3FontSize;
19
19
  BOOL _h3Bold;
20
+ CGFloat _h4FontSize;
21
+ BOOL _h4Bold;
22
+ CGFloat _h5FontSize;
23
+ BOOL _h5Bold;
24
+ CGFloat _h6FontSize;
25
+ BOOL _h6Bold;
20
26
  UIColor *_blockquoteBorderColor;
21
27
  CGFloat _blockquoteBorderWidth;
22
28
  CGFloat _blockquoteGapWidth;
@@ -39,8 +45,14 @@
39
45
  UIColor *_codeBlockFgColor;
40
46
  CGFloat _codeBlockBorderRadius;
41
47
  UIColor *_codeBlockBgColor;
42
- CGFloat _imageWidth;
43
- CGFloat _imageHeight;
48
+ LinkRegexConfig *_linkRegexConfig;
49
+ NSRegularExpression *_parsedLinkRegex;
50
+ CGFloat _checkboxListBoxSize;
51
+ CGFloat _checkboxListGapWidth;
52
+ CGFloat _checkboxListMarginLeft;
53
+ UIColor *_checkboxListBoxColor;
54
+ UIImage *_checkboxCheckedImage;
55
+ UIImage *_checkboxUncheckedImage;
44
56
  }
45
57
 
46
58
  - (instancetype)init {
@@ -66,6 +78,12 @@
66
78
  copy->_h2Bold = _h2Bold;
67
79
  copy->_h3FontSize = _h3FontSize;
68
80
  copy->_h3Bold = _h3Bold;
81
+ copy->_h4FontSize = _h4FontSize;
82
+ copy->_h4Bold = _h4Bold;
83
+ copy->_h5FontSize = _h5FontSize;
84
+ copy->_h5Bold = _h5Bold;
85
+ copy->_h6FontSize = _h6FontSize;
86
+ copy->_h6Bold = _h6Bold;
69
87
  copy->_blockquoteBorderColor = [_blockquoteBorderColor copy];
70
88
  copy->_blockquoteBorderWidth = _blockquoteBorderWidth;
71
89
  copy->_blockquoteGapWidth = _blockquoteGapWidth;
@@ -87,6 +105,14 @@
87
105
  copy->_codeBlockFgColor = [_codeBlockFgColor copy];
88
106
  copy->_codeBlockBgColor = [_codeBlockBgColor copy];
89
107
  copy->_codeBlockBorderRadius = _codeBlockBorderRadius;
108
+ copy->_linkRegexConfig = [_linkRegexConfig copy];
109
+ copy->_parsedLinkRegex = [_parsedLinkRegex copy];
110
+ copy->_checkboxListBoxSize = _checkboxListBoxSize;
111
+ copy->_checkboxListGapWidth = _checkboxListGapWidth;
112
+ copy->_checkboxListMarginLeft = _checkboxListMarginLeft;
113
+ copy->_checkboxListBoxColor = [_checkboxListBoxColor copy];
114
+ copy->_checkboxCheckedImage = _checkboxCheckedImage;
115
+ copy->_checkboxUncheckedImage = _checkboxUncheckedImage;
90
116
  return copy;
91
117
  }
92
118
 
@@ -146,7 +172,7 @@
146
172
 
147
173
  _primaryFont = [RCTFont updateFont:nullptr
148
174
  withFamily:[self primaryFontFamily]
149
- size:[self primaryFontSize]
175
+ size:[self scaledPrimaryFontSize]
150
176
  weight:newFontWeight
151
177
  style:nullptr
152
178
  variant:nullptr
@@ -159,7 +185,7 @@
159
185
  if (_monospacedFontNeedsRecreation) {
160
186
  _monospacedFontNeedsRecreation = NO;
161
187
  _monospacedFont = [UIFont
162
- monospacedSystemFontOfSize:[[self primaryFontSize] floatValue]
188
+ monospacedSystemFontOfSize:[[self scaledPrimaryFontSize] floatValue]
163
189
  weight:[[self primaryFontWeight] floatValue]];
164
190
  }
165
191
  return _monospacedFont;
@@ -175,7 +201,7 @@
175
201
  }
176
202
 
177
203
  - (CGFloat)h1FontSize {
178
- return _h1FontSize;
204
+ return [[UIFontMetrics defaultMetrics] scaledValueForValue:_h1FontSize];
179
205
  }
180
206
 
181
207
  - (void)setH1FontSize:(CGFloat)newValue {
@@ -191,7 +217,7 @@
191
217
  }
192
218
 
193
219
  - (CGFloat)h2FontSize {
194
- return _h2FontSize;
220
+ return [[UIFontMetrics defaultMetrics] scaledValueForValue:_h2FontSize];
195
221
  }
196
222
 
197
223
  - (void)setH2FontSize:(CGFloat)newValue {
@@ -207,7 +233,7 @@
207
233
  }
208
234
 
209
235
  - (CGFloat)h3FontSize {
210
- return _h3FontSize;
236
+ return [[UIFontMetrics defaultMetrics] scaledValueForValue:_h3FontSize];
211
237
  }
212
238
 
213
239
  - (void)setH3FontSize:(CGFloat)newValue {
@@ -222,6 +248,54 @@
222
248
  _h3Bold = newValue;
223
249
  }
224
250
 
251
+ - (CGFloat)h4FontSize {
252
+ return [[UIFontMetrics defaultMetrics] scaledValueForValue:_h4FontSize];
253
+ }
254
+
255
+ - (void)setH4FontSize:(CGFloat)newValue {
256
+ _h4FontSize = newValue;
257
+ }
258
+
259
+ - (BOOL)h4Bold {
260
+ return _h4Bold;
261
+ }
262
+
263
+ - (void)setH4Bold:(BOOL)newValue {
264
+ _h4Bold = newValue;
265
+ }
266
+
267
+ - (CGFloat)h5FontSize {
268
+ return [[UIFontMetrics defaultMetrics] scaledValueForValue:_h5FontSize];
269
+ }
270
+
271
+ - (void)setH5FontSize:(CGFloat)newValue {
272
+ _h5FontSize = newValue;
273
+ }
274
+
275
+ - (BOOL)h5Bold {
276
+ return _h5Bold;
277
+ }
278
+
279
+ - (void)setH5Bold:(BOOL)newValue {
280
+ _h5Bold = newValue;
281
+ }
282
+
283
+ - (CGFloat)h6FontSize {
284
+ return [[UIFontMetrics defaultMetrics] scaledValueForValue:_h6FontSize];
285
+ }
286
+
287
+ - (void)setH6FontSize:(CGFloat)newValue {
288
+ _h6FontSize = newValue;
289
+ }
290
+
291
+ - (BOOL)h6Bold {
292
+ return _h6Bold;
293
+ }
294
+
295
+ - (void)setH6Bold:(BOOL)newValue {
296
+ _h6Bold = newValue;
297
+ }
298
+
225
299
  - (UIColor *)blockquoteBorderColor {
226
300
  return _blockquoteBorderColor;
227
301
  }
@@ -318,7 +392,7 @@
318
392
 
319
393
  _orderedListMarkerFont = [RCTFont updateFont:nullptr
320
394
  withFamily:[self primaryFontFamily]
321
- size:[self primaryFontSize]
395
+ size:[self scaledPrimaryFontSize]
322
396
  weight:newFontWeight
323
397
  style:nullptr
324
398
  variant:nullptr
@@ -417,4 +491,159 @@
417
491
  _codeBlockBorderRadius = newValue;
418
492
  }
419
493
 
494
+ - (LinkRegexConfig *)linkRegexConfig {
495
+ return _linkRegexConfig;
496
+ }
497
+
498
+ - (void)setLinkRegexConfig:(LinkRegexConfig *)newValue {
499
+ _linkRegexConfig = newValue;
500
+
501
+ // try initializing the native regular expression if it applies
502
+ if (_linkRegexConfig.isDefault || _linkRegexConfig.isDisabled) {
503
+ return;
504
+ }
505
+
506
+ NSError *regexInitError;
507
+ NSRegularExpressionOptions options =
508
+ (_linkRegexConfig.caseInsensitive ? NSRegularExpressionCaseInsensitive
509
+ : 0) |
510
+ (_linkRegexConfig.dotAll ? NSRegularExpressionDotMatchesLineSeparators
511
+ : 0);
512
+ NSRegularExpression *userRegex =
513
+ [NSRegularExpression regularExpressionWithPattern:_linkRegexConfig.pattern
514
+ options:options
515
+ error:&regexInitError];
516
+
517
+ if (regexInitError) {
518
+ RCTLogWarn(@"[EnrichedTextInput]: Couldn't parse the user-defined link "
519
+ @"regex, falling back to a default regex.");
520
+ _parsedLinkRegex = nullptr;
521
+ } else {
522
+ _parsedLinkRegex = userRegex;
523
+ }
524
+ }
525
+
526
+ - (NSRegularExpression *)parsedLinkRegex {
527
+ return _parsedLinkRegex;
528
+ }
529
+
530
+ - (void)invalidateFonts {
531
+ _primaryFontNeedsRecreation = YES;
532
+ _monospacedFontNeedsRecreation = YES;
533
+ _olMarkerFontNeedsRecreation = YES;
534
+ }
535
+
536
+ - (NSNumber *)scaledPrimaryFontSize {
537
+ CGFloat scaledSize = [[UIFontMetrics defaultMetrics]
538
+ scaledValueForValue:[[self primaryFontSize] floatValue]];
539
+ return @(scaledSize);
540
+ }
541
+
542
+ - (CGFloat)checkboxListBoxSize {
543
+ return _checkboxListBoxSize;
544
+ }
545
+
546
+ - (void)setCheckboxListBoxSize:(CGFloat)newValue {
547
+ if (_checkboxListBoxSize != newValue) {
548
+ _checkboxListBoxSize = newValue;
549
+ // Invalidate checkbox images because box size changed
550
+ _checkboxCheckedImage = nil;
551
+ _checkboxUncheckedImage = nil;
552
+ }
553
+ }
554
+
555
+ - (CGFloat)checkboxListGapWidth {
556
+ return _checkboxListGapWidth;
557
+ }
558
+
559
+ - (void)setCheckboxListGapWidth:(CGFloat)newValue {
560
+ _checkboxListGapWidth = newValue;
561
+ }
562
+
563
+ - (CGFloat)checkboxListMarginLeft {
564
+ return _checkboxListMarginLeft;
565
+ }
566
+
567
+ - (void)setCheckboxListMarginLeft:(CGFloat)newValue {
568
+ _checkboxListMarginLeft = newValue;
569
+ }
570
+
571
+ - (UIColor *)checkboxListBoxColor {
572
+ return _checkboxListBoxColor;
573
+ }
574
+
575
+ - (void)setCheckboxListBoxColor:(UIColor *)newValue {
576
+ if (_checkboxListBoxColor != newValue) {
577
+ _checkboxListBoxColor = newValue;
578
+ // Invalidate checkbox images because color changed
579
+ _checkboxCheckedImage = nil;
580
+ _checkboxUncheckedImage = nil;
581
+ }
582
+ }
583
+
584
+ - (UIImage *)checkboxCheckedImage {
585
+ if (!_checkboxCheckedImage) {
586
+ _checkboxCheckedImage = [self generateCheckboxImage:YES];
587
+ }
588
+ return _checkboxCheckedImage;
589
+ }
590
+
591
+ - (UIImage *)checkboxUncheckedImage {
592
+ if (!_checkboxUncheckedImage) {
593
+ _checkboxUncheckedImage = [self generateCheckboxImage:NO];
594
+ }
595
+ return _checkboxUncheckedImage;
596
+ }
597
+
598
+ - (UIImage *)generateCheckboxImage:(BOOL)isChecked {
599
+ CGFloat boxSize = self.checkboxListBoxSize;
600
+ UIColor *boxColor = self.checkboxListBoxColor ?: [UIColor blackColor];
601
+
602
+ UIGraphicsBeginImageContextWithOptions(CGSizeMake(boxSize, boxSize), NO, 0.0);
603
+ CGRect localRect = CGRectMake(0, 0, boxSize, boxSize);
604
+ CGFloat cornerRadius = boxSize * 0.15f;
605
+ CGFloat strokeWidth = boxSize * 0.1f;
606
+ CGRect insetRect =
607
+ CGRectInset(localRect, strokeWidth / 2.0, strokeWidth / 2.0);
608
+
609
+ // Draw Box
610
+ UIBezierPath *boxPath = [UIBezierPath bezierPathWithRoundedRect:insetRect
611
+ cornerRadius:cornerRadius];
612
+ [boxPath setLineWidth:strokeWidth];
613
+
614
+ if (isChecked) {
615
+ [[boxColor colorWithAlphaComponent:1.0] setFill];
616
+ [boxPath fill];
617
+ [[boxColor colorWithAlphaComponent:1.0] setStroke];
618
+ [boxPath stroke];
619
+
620
+ // Draw Checkmark
621
+ UIBezierPath *checkPath = [UIBezierPath bezierPath];
622
+ CGFloat startX = insetRect.origin.x + insetRect.size.width * 0.25;
623
+ CGFloat startY = insetRect.origin.y + insetRect.size.height * 0.5;
624
+ CGFloat midX = insetRect.origin.x + insetRect.size.width * 0.45;
625
+ CGFloat midY = insetRect.origin.y + insetRect.size.height * 0.65;
626
+ CGFloat endX = insetRect.origin.x + insetRect.size.width * 0.75;
627
+ CGFloat endY = insetRect.origin.y + insetRect.size.height * 0.35;
628
+
629
+ [checkPath moveToPoint:CGPointMake(startX, startY)];
630
+ [checkPath addLineToPoint:CGPointMake(midX, midY)];
631
+ [checkPath addLineToPoint:CGPointMake(endX, endY)];
632
+
633
+ [checkPath setLineWidth:strokeWidth * 1.5];
634
+ [[UIColor whiteColor] setStroke];
635
+ [checkPath setLineCapStyle:kCGLineCapRound];
636
+ [checkPath setLineJoinStyle:kCGLineJoinRound];
637
+ [checkPath stroke];
638
+ } else {
639
+ [[boxColor colorWithAlphaComponent:1.0] setStroke];
640
+ [boxPath stroke];
641
+ }
642
+
643
+ UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
644
+ UIGraphicsEndImageContext();
645
+
646
+ return result;
647
+ }
648
+
420
649
  @end
@@ -0,0 +1,35 @@
1
+ #import <UIKit/UIKit.h>
2
+
3
+ /**
4
+ UIImage (animatedGIF)
5
+
6
+ This category adds class methods to `UIImage` to create an animated
7
+ `UIImage` from an animated GIF.
8
+ */
9
+ @interface UIImage (ImageExtension)
10
+
11
+ /*
12
+ UIImage *animation = [UIImage animatedImageWithAnimatedGIFData:theData];
13
+
14
+ I interpret `theData` as a GIF. I create an animated `UIImage` using the
15
+ source images in the GIF.
16
+
17
+ The GIF stores a separate duration for each frame, in units of centiseconds
18
+ (hundredths of a second). However, a `UIImage` only has a single, total
19
+ `duration` property, which is a floating-point number.
20
+
21
+ To handle this mismatch, I add each source image (from the GIF) to
22
+ `animation` a varying number of times to match the ratios between the frame
23
+ durations in the GIF.
24
+
25
+ For example, suppose the GIF contains three frames. Frame 0 has duration 3.
26
+ Frame 1 has duration 9. Frame 2 has duration 15. I divide each duration by
27
+ the greatest common denominator of all the durations, which is 3, and add
28
+ each frame the resulting number of times. Thus `animation` will contain
29
+ frame 0 3/3 = 1 time, then frame 1 9/3 = 3 times, then frame 2 15/3 = 5
30
+ times. I set `animation.duration` to (3+9+15)/100 = 0.27 seconds.
31
+ */
32
+ + (UIImage *_Nullable)animatedImageWithAnimatedGIFData:
33
+ (NSData *_Nonnull)theData;
34
+
35
+ @end
@@ -0,0 +1,156 @@
1
+ #import "ImageExtension.h"
2
+ #import <ImageIO/ImageIO.h>
3
+ #include <cmath>
4
+ #include <vector>
5
+
6
+ #if __has_feature(objc_arc)
7
+ #define toCF (__bridge CFTypeRef)
8
+ #define fromCF (__bridge id)
9
+ #else
10
+ #define toCF (CFTypeRef)
11
+ #define fromCF (id)
12
+ #endif
13
+
14
+ // implementation from:
15
+ // https://github.com/mayoff/uiimage-from-animated-gif/blob/master/uiimage-from-animated-gif/UIImage%2BanimatedGIF.m
16
+ @implementation UIImage (ImageExtension)
17
+
18
+ static int delayCentisecondsForImageAtIndex(CGImageSourceRef const source,
19
+ size_t const i) {
20
+ int delayCentiseconds = 1;
21
+ CFDictionaryRef const properties =
22
+ CGImageSourceCopyPropertiesAtIndex(source, i, NULL);
23
+ if (properties) {
24
+ CFDictionaryRef const gifProperties = (CFDictionaryRef)CFDictionaryGetValue(
25
+ properties, kCGImagePropertyGIFDictionary);
26
+ if (gifProperties) {
27
+ NSNumber *number = fromCF CFDictionaryGetValue(
28
+ gifProperties, kCGImagePropertyGIFUnclampedDelayTime);
29
+ if (number == NULL || [number doubleValue] == 0) {
30
+ number = fromCF CFDictionaryGetValue(gifProperties,
31
+ kCGImagePropertyGIFDelayTime);
32
+ }
33
+ if ([number doubleValue] > 0) {
34
+ // Even though the GIF stores the delay as an integer number of
35
+ // centiseconds, ImageIO “helpfully” converts that to seconds for us.
36
+ delayCentiseconds = (int)lrint([number doubleValue] * 100);
37
+ }
38
+ }
39
+ CFRelease(properties);
40
+ }
41
+ return delayCentiseconds;
42
+ }
43
+
44
+ // Changed to use std::vector references instead of C-arrays
45
+ static void createImagesAndDelays(CGImageSourceRef source, size_t count,
46
+ std::vector<CGImageRef> &imagesOut,
47
+ std::vector<int> &delayCentisecondsOut) {
48
+ for (size_t i = 0; i < count; ++i) {
49
+ imagesOut[i] = CGImageSourceCreateImageAtIndex(source, i, NULL);
50
+ delayCentisecondsOut[i] = delayCentisecondsForImageAtIndex(source, i);
51
+ }
52
+ }
53
+
54
+ static int sum(const std::vector<int> &values) {
55
+ int theSum = 0;
56
+ for (int value : values) {
57
+ theSum += value;
58
+ }
59
+ return theSum;
60
+ }
61
+
62
+ static int pairGCD(int a, int b) {
63
+ if (a < b)
64
+ return pairGCD(b, a);
65
+ while (true) {
66
+ int const r = a % b;
67
+ if (r == 0)
68
+ return b;
69
+ a = b;
70
+ b = r;
71
+ }
72
+ }
73
+
74
+ static int vectorGCD(const std::vector<int> &values) {
75
+ if (values.empty())
76
+ return 1;
77
+
78
+ int gcd = values[0];
79
+ for (size_t i = 1; i < values.size(); ++i) {
80
+ // Note that after I process the first few elements of the vector, `gcd`
81
+ // will probably be smaller than any remaining element. By passing the
82
+ // smaller value as the second argument to `pairGCD`, I avoid making it swap
83
+ // the arguments.
84
+ gcd = pairGCD(values[i], gcd);
85
+ }
86
+ return gcd;
87
+ }
88
+
89
+ static NSArray *frameArray(const std::vector<CGImageRef> &images,
90
+ const std::vector<int> &delayCentiseconds,
91
+ int const totalDurationCentiseconds) {
92
+ int const gcd = vectorGCD(delayCentiseconds);
93
+ size_t const frameCount = totalDurationCentiseconds / gcd;
94
+
95
+ // Replaced VLA with NSMutableArray for safety and OBJ-C++ compatibility
96
+ NSMutableArray *frames = [NSMutableArray arrayWithCapacity:frameCount];
97
+
98
+ for (size_t i = 0; i < images.size(); ++i) {
99
+ UIImage *const frame = [UIImage imageWithCGImage:images[i]];
100
+ for (size_t j = delayCentiseconds[i] / gcd; j > 0; --j) {
101
+ [frames addObject:frame];
102
+ }
103
+ }
104
+ return frames;
105
+ }
106
+
107
+ static void releaseImages(const std::vector<CGImageRef> &images) {
108
+ for (CGImageRef image : images) {
109
+ if (image)
110
+ CGImageRelease(image);
111
+ }
112
+ }
113
+
114
+ static UIImage *
115
+ animatedImageWithAnimatedGIFImageSource(CGImageSourceRef const source) {
116
+ size_t const count = CGImageSourceGetCount(source);
117
+ if (count == 0) {
118
+ return nil;
119
+ }
120
+
121
+ // Replaced VLAs (variable length arrays) with std::vector
122
+ std::vector<CGImageRef> images(count);
123
+ std::vector<int> delayCentiseconds(count); // in centiseconds
124
+
125
+ createImagesAndDelays(source, count, images, delayCentiseconds);
126
+
127
+ int const totalDurationCentiseconds = sum(delayCentiseconds);
128
+ NSArray *const frames =
129
+ frameArray(images, delayCentiseconds, totalDurationCentiseconds);
130
+
131
+ UIImage *const animation = [UIImage
132
+ animatedImageWithImages:frames
133
+ duration:(NSTimeInterval)totalDurationCentiseconds /
134
+ 100.0];
135
+
136
+ releaseImages(images);
137
+ return animation;
138
+ }
139
+
140
+ static UIImage *animatedImageWithAnimatedGIFReleasingImageSource(
141
+ CGImageSourceRef CF_RELEASES_ARGUMENT source) {
142
+ if (source) {
143
+ UIImage *const image = animatedImageWithAnimatedGIFImageSource(source);
144
+ CFRelease(source);
145
+ return image;
146
+ } else {
147
+ return nil;
148
+ }
149
+ }
150
+
151
+ + (UIImage *)animatedImageWithAnimatedGIFData:(NSData *)data {
152
+ return animatedImageWithAnimatedGIFReleasingImageSource(
153
+ CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL));
154
+ }
155
+
156
+ @end