react-native-enriched 0.3.0 → 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 (202) hide show
  1. package/README.md +6 -4
  2. package/android/build.gradle +3 -3
  3. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +3 -0
  4. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +1 -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/{ios/generated/RNEnrichedTextInputViewSpec → android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec}/EventEmitters.cpp +31 -29
  8. package/{ios/generated/RNEnrichedTextInputViewSpec → android/generated/jni/react/renderer/components/ReactNativeEnrichedSpec}/EventEmitters.h +22 -25
  9. package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/Props.h +57 -0
  10. package/android/gradle.properties +5 -5
  11. package/android/src/main/java/com/swmansion/enriched/{EnrichedTextInputViewPackage.kt → ReactNativeEnrichedPackage.kt} +3 -2
  12. package/android/src/main/java/com/swmansion/enriched/{utils → common}/AsyncDrawable.kt +40 -8
  13. package/android/src/main/java/com/swmansion/enriched/common/CheckboxDrawable.kt +81 -0
  14. package/android/src/main/java/com/swmansion/enriched/{utils → common}/EnrichedConstants.kt +1 -1
  15. package/android/src/main/java/com/swmansion/enriched/common/EnrichedStyle.kt +57 -0
  16. package/android/src/main/java/com/swmansion/enriched/{spans/utils → common}/ForceRedrawSpan.kt +1 -1
  17. package/android/src/main/java/com/swmansion/enriched/common/MentionStyle.kt +7 -0
  18. package/android/src/main/java/com/swmansion/enriched/{utils → common}/ResourceManager.kt +1 -1
  19. package/android/src/main/java/com/swmansion/enriched/{utils → common/parser}/EnrichedParser.java +126 -99
  20. package/android/src/main/java/com/swmansion/enriched/common/parser/EnrichedSpanFactory.kt +79 -0
  21. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/EnrichedBlockQuoteSpan.kt +9 -13
  22. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedBoldSpan.kt +12 -0
  23. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedCheckboxListSpan.kt +91 -0
  24. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/EnrichedCodeBlockSpan.kt +8 -12
  25. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH1Span.kt +20 -0
  26. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH2Span.kt +20 -0
  27. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH3Span.kt +20 -0
  28. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH4Span.kt +21 -0
  29. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH5Span.kt +20 -0
  30. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedH6Span.kt +20 -0
  31. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/EnrichedImageSpan.kt +43 -38
  32. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/EnrichedInlineCodeSpan.kt +7 -11
  33. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedItalicSpan.kt +12 -0
  34. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/EnrichedLinkSpan.kt +7 -11
  35. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/EnrichedMentionSpan.kt +6 -10
  36. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/EnrichedOrderedListSpan.kt +12 -21
  37. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedStrikeThroughSpan.kt +11 -0
  38. package/android/src/main/java/com/swmansion/enriched/common/spans/EnrichedUnderlineSpan.kt +11 -0
  39. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/EnrichedUnorderedListSpan.kt +9 -13
  40. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/interfaces/EnrichedBlockSpan.kt +1 -1
  41. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/interfaces/EnrichedHeadingSpan.kt +1 -1
  42. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedInlineSpan.kt +3 -0
  43. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/interfaces/EnrichedParagraphSpan.kt +1 -1
  44. package/android/src/main/java/com/swmansion/enriched/common/spans/interfaces/EnrichedSpan.kt +3 -0
  45. package/android/src/main/java/com/swmansion/enriched/{spans → common/spans}/interfaces/EnrichedZeroWidthSpaceSpan.kt +1 -1
  46. package/android/src/main/java/com/swmansion/enriched/{EnrichedTextInputConnectionWrapper.kt → textinput/EnrichedTextInputConnectionWrapper.kt} +2 -2
  47. package/android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputSpannableFactory.kt +83 -0
  48. package/android/src/main/java/com/swmansion/enriched/{EnrichedTextInputView.kt → textinput/EnrichedTextInputView.kt} +87 -51
  49. package/android/src/main/java/com/swmansion/enriched/{EnrichedTextInputViewLayoutManager.kt → textinput/EnrichedTextInputViewLayoutManager.kt} +1 -1
  50. package/android/src/main/java/com/swmansion/enriched/{EnrichedTextInputViewManager.kt → textinput/EnrichedTextInputViewManager.kt} +24 -17
  51. package/android/src/main/java/com/swmansion/enriched/{MeasurementStore.kt → textinput/MeasurementStore.kt} +5 -4
  52. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/MentionHandler.kt +2 -2
  53. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnChangeHtmlEvent.kt +1 -1
  54. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnChangeSelectionEvent.kt +1 -1
  55. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnChangeStateEvent.kt +1 -1
  56. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnChangeTextEvent.kt +2 -2
  57. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnInputBlurEvent.kt +1 -1
  58. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnInputFocusEvent.kt +1 -1
  59. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnInputKeyPressEvent.kt +1 -1
  60. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnLinkDetectedEvent.kt +1 -1
  61. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnMentionDetectedEvent.kt +1 -1
  62. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnMentionEvent.kt +1 -1
  63. package/android/src/main/java/com/swmansion/enriched/textinput/events/OnPasteImagesEvent.kt +47 -0
  64. package/android/src/main/java/com/swmansion/enriched/{events → textinput/events}/OnRequestHtmlResultEvent.kt +1 -1
  65. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputBlockQuoteSpan.kt +14 -0
  66. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputBoldSpan.kt +14 -0
  67. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputCheckboxListSpan.kt +15 -0
  68. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputCodeBlockSpan.kt +14 -0
  69. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH1Span.kt +14 -0
  70. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH2Span.kt +14 -0
  71. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH3Span.kt +14 -0
  72. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH4Span.kt +14 -0
  73. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH5Span.kt +14 -0
  74. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputH6Span.kt +14 -0
  75. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputImageSpan.kt +36 -0
  76. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputInlineCodeSpan.kt +14 -0
  77. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputItalicSpan.kt +14 -0
  78. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputLinkSpan.kt +15 -0
  79. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputMentionSpan.kt +18 -0
  80. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputOrderedListSpan.kt +21 -0
  81. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputStrikeThroughSpan.kt +14 -0
  82. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputUnderlineSpan.kt +14 -0
  83. package/android/src/main/java/com/swmansion/enriched/textinput/spans/EnrichedInputUnorderedListSpan.kt +14 -0
  84. package/android/src/main/java/com/swmansion/enriched/{spans → textinput/spans}/EnrichedSpans.kt +39 -30
  85. package/android/src/main/java/com/swmansion/enriched/textinput/spans/interfaces/EnrichedInputSpan.kt +10 -0
  86. package/android/src/main/java/com/swmansion/enriched/{styles → textinput/styles}/HtmlStyle.kt +58 -43
  87. package/android/src/main/java/com/swmansion/enriched/{styles → textinput/styles}/InlineStyles.kt +4 -4
  88. package/android/src/main/java/com/swmansion/enriched/{styles → textinput/styles}/ListStyles.kt +77 -26
  89. package/android/src/main/java/com/swmansion/enriched/{styles → textinput/styles}/ParagraphStyles.kt +11 -11
  90. package/android/src/main/java/com/swmansion/enriched/{styles → textinput/styles}/ParametrizedStyles.kt +19 -19
  91. package/android/src/main/java/com/swmansion/enriched/{utils → textinput/utils}/EnrichedEditableFactory.kt +2 -2
  92. package/android/src/main/java/com/swmansion/enriched/{utils → textinput/utils}/EnrichedSelection.kt +15 -14
  93. package/android/src/main/java/com/swmansion/enriched/{utils → textinput/utils}/EnrichedSpanState.kt +15 -50
  94. package/android/src/main/java/com/swmansion/enriched/{utils → textinput/utils}/EnrichedSpannable.kt +3 -3
  95. package/android/src/main/java/com/swmansion/enriched/{utils → textinput/utils}/EnrichedSpannableStringBuilder.kt +2 -1
  96. package/android/src/main/java/com/swmansion/enriched/textinput/utils/RichContentReceiver.kt +127 -0
  97. package/android/src/main/java/com/swmansion/enriched/textinput/utils/Utils.kt +106 -0
  98. package/android/src/main/java/com/swmansion/enriched/{watchers → textinput/watchers}/EnrichedSpanWatcher.kt +10 -10
  99. package/android/src/main/java/com/swmansion/enriched/{watchers → textinput/watchers}/EnrichedTextWatcher.kt +3 -3
  100. package/android/src/main/new_arch/CMakeLists.txt +1 -1
  101. package/android/src/main/new_arch/ReactNativeEnrichedSpec.cpp +11 -0
  102. package/android/src/main/new_arch/ReactNativeEnrichedSpec.h +15 -0
  103. package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputMeasurementManager.h +1 -1
  104. package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputShadowNode.h +2 -2
  105. package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/conversions.h +1 -1
  106. package/ios/EnrichedTextInputView.h +1 -0
  107. package/ios/EnrichedTextInputView.mm +266 -55
  108. package/ios/config/InputConfig.h +10 -0
  109. package/ios/config/InputConfig.mm +119 -0
  110. package/ios/extensions/ImageExtension.h +35 -0
  111. package/ios/extensions/ImageExtension.mm +156 -0
  112. package/ios/extensions/LayoutManagerExtension.mm +115 -95
  113. package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ComponentDescriptors.cpp +1 -1
  114. package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ComponentDescriptors.h +1 -1
  115. package/{android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec → ios/generated/ReactNativeEnrichedSpec}/EventEmitters.cpp +31 -29
  116. package/{android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec → ios/generated/ReactNativeEnrichedSpec}/EventEmitters.h +22 -25
  117. package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/Props.h +57 -0
  118. package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/RCTComponentViewHelpers.h +21 -0
  119. package/ios/inputParser/InputParser.mm +135 -8
  120. package/ios/inputTextView/InputTextView.mm +118 -0
  121. package/ios/interfaces/ImageAttachment.h +1 -0
  122. package/ios/interfaces/ImageAttachment.mm +14 -4
  123. package/ios/interfaces/StyleHeaders.h +13 -2
  124. package/ios/interfaces/StyleTypeEnum.h +1 -0
  125. package/ios/internals/EnrichedTextInputViewState.cpp +6 -6
  126. package/ios/styles/CheckboxListStyle.mm +321 -0
  127. package/ios/styles/H1Style.mm +3 -0
  128. package/ios/styles/H2Style.mm +3 -0
  129. package/ios/styles/H3Style.mm +3 -0
  130. package/ios/styles/H4Style.mm +3 -0
  131. package/ios/styles/H5Style.mm +3 -0
  132. package/ios/styles/H6Style.mm +3 -0
  133. package/ios/styles/HeadingStyleBase.mm +150 -78
  134. package/ios/utils/CheckboxHitTestUtils.h +10 -0
  135. package/ios/utils/CheckboxHitTestUtils.mm +123 -0
  136. package/ios/utils/ParagraphAttributesUtils.mm +83 -53
  137. package/ios/utils/TextBlockTapGestureRecognizer.h +17 -0
  138. package/ios/utils/TextBlockTapGestureRecognizer.mm +56 -0
  139. package/ios/utils/ZeroWidthSpaceUtils.mm +14 -3
  140. package/lib/module/EnrichedTextInput.js +36 -11
  141. package/lib/module/EnrichedTextInput.js.map +1 -1
  142. package/lib/module/{EnrichedTextInputNativeComponent.ts → spec/EnrichedTextInputNativeComponent.ts} +40 -9
  143. package/lib/module/types.js +4 -0
  144. package/lib/module/types.js.map +1 -0
  145. package/lib/module/utils/normalizeHtmlStyle.js +6 -0
  146. package/lib/module/utils/normalizeHtmlStyle.js.map +1 -1
  147. package/lib/module/utils/nullthrows.js +9 -0
  148. package/lib/module/utils/nullthrows.js.map +1 -0
  149. package/lib/typescript/src/EnrichedTextInput.d.ts +9 -49
  150. package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
  151. package/lib/typescript/src/index.d.ts +2 -1
  152. package/lib/typescript/src/index.d.ts.map +1 -1
  153. package/lib/typescript/src/{EnrichedTextInputNativeComponent.d.ts → spec/EnrichedTextInputNativeComponent.d.ts} +33 -8
  154. package/lib/typescript/src/spec/EnrichedTextInputNativeComponent.d.ts.map +1 -0
  155. package/lib/typescript/src/types.d.ts +58 -0
  156. package/lib/typescript/src/types.d.ts.map +1 -0
  157. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts +2 -2
  158. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts.map +1 -1
  159. package/lib/typescript/src/utils/nullthrows.d.ts +2 -0
  160. package/lib/typescript/src/utils/nullthrows.d.ts.map +1 -0
  161. package/lib/typescript/src/utils/regexParser.d.ts +1 -1
  162. package/lib/typescript/src/utils/regexParser.d.ts.map +1 -1
  163. package/package.json +4 -4
  164. package/src/EnrichedTextInput.tsx +49 -62
  165. package/src/index.tsx +3 -1
  166. package/src/{EnrichedTextInputNativeComponent.ts → spec/EnrichedTextInputNativeComponent.ts} +40 -9
  167. package/src/types.ts +59 -0
  168. package/src/utils/normalizeHtmlStyle.ts +8 -5
  169. package/src/utils/nullthrows.ts +7 -0
  170. package/src/utils/regexParser.ts +1 -1
  171. package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateDeprecatedEvent.kt +0 -21
  172. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +0 -17
  173. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +0 -24
  174. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +0 -24
  175. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +0 -24
  176. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH4Span.kt +0 -24
  177. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH5Span.kt +0 -24
  178. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH6Span.kt +0 -24
  179. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +0 -16
  180. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +0 -15
  181. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +0 -15
  182. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedInlineSpan.kt +0 -3
  183. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +0 -9
  184. package/android/src/main/java/com/swmansion/enriched/utils/Utils.kt +0 -21
  185. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +0 -22
  186. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +0 -26
  187. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +0 -1
  188. /package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/Props.cpp +0 -0
  189. /package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ShadowNodes.cpp +0 -0
  190. /package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ShadowNodes.h +0 -0
  191. /package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/States.cpp +0 -0
  192. /package/android/generated/jni/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/States.h +0 -0
  193. /package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputComponentDescriptor.h +0 -0
  194. /package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputMeasurementManager.cpp +0 -0
  195. /package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputShadowNode.cpp +0 -0
  196. /package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputState.cpp +0 -0
  197. /package/android/src/main/new_arch/react/renderer/components/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/EnrichedTextInputState.h +0 -0
  198. /package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/Props.cpp +0 -0
  199. /package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ShadowNodes.cpp +0 -0
  200. /package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/ShadowNodes.h +0 -0
  201. /package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/States.cpp +0 -0
  202. /package/ios/generated/{RNEnrichedTextInputViewSpec → ReactNativeEnrichedSpec}/States.h +0 -0
@@ -1,6 +1,7 @@
1
1
  #import "EnrichedTextInputView.h"
2
2
  #import "FontExtension.h"
3
3
  #import "OccurenceUtils.h"
4
+ #import "ParagraphsUtils.h"
4
5
  #import "StyleHeaders.h"
5
6
  #import "TextInsertionUtils.h"
6
7
 
@@ -13,6 +14,9 @@
13
14
  - (CGFloat)getHeadingFontSize {
14
15
  return 0;
15
16
  }
17
+ - (NSString *)getHeadingLevelString {
18
+ return @"";
19
+ }
16
20
  - (BOOL)isHeadingBold {
17
21
  return false;
18
22
  }
@@ -27,7 +31,6 @@
27
31
  - (instancetype)initWithInput:(id)input {
28
32
  self = [super init];
29
33
  self->input = input;
30
- _lastAppliedFontSize = 0.0;
31
34
  return self;
32
35
  }
33
36
 
@@ -41,20 +44,50 @@
41
44
  } else {
42
45
  isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
43
46
  }
44
- _lastAppliedFontSize = [self getHeadingFontSize];
47
+ }
48
+
49
+ - (NSTextList *)getTextListObject {
50
+ return [[NSTextList alloc]
51
+ initWithMarkerFormat:[NSString
52
+ stringWithFormat:@"{heading:%@}",
53
+ [self getHeadingLevelString]]
54
+ options:0];
45
55
  }
46
56
 
47
57
  // the range will already be the proper full paragraph/s range
48
58
  - (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
49
- [[self typedInput]->textView.textStorage beginEditing];
50
- [[self typedInput]->textView.textStorage
51
- enumerateAttribute:NSFontAttributeName
52
- inRange:range
53
- options:0
54
- usingBlock:^(id _Nullable value, NSRange range,
55
- BOOL *_Nonnull stop) {
56
- UIFont *font = (UIFont *)value;
57
- if (font != nullptr) {
59
+ NSTextList *textListMarker = [self getTextListObject];
60
+ NSArray *paragraphs =
61
+ [ParagraphsUtils getSeparateParagraphsRangesIn:[self typedInput]->textView
62
+ range:range];
63
+ for (NSValue *value in paragraphs) {
64
+ NSRange paragraphRange = [value rangeValue];
65
+
66
+ [[self typedInput]->textView.textStorage
67
+ enumerateAttribute:NSParagraphStyleAttributeName
68
+ inRange:paragraphRange
69
+ options:0
70
+ usingBlock:^(id _Nullable value, NSRange range,
71
+ BOOL *_Nonnull stop) {
72
+ NSMutableParagraphStyle *pStyle =
73
+ [(NSParagraphStyle *)value mutableCopy];
74
+ pStyle.textLists = @[ textListMarker ];
75
+ [[self typedInput]->textView.textStorage
76
+ addAttribute:NSParagraphStyleAttributeName
77
+ value:pStyle
78
+ range:range];
79
+ }];
80
+
81
+ [[self typedInput]->textView.textStorage
82
+ enumerateAttribute:NSFontAttributeName
83
+ inRange:paragraphRange
84
+ options:0
85
+ usingBlock:^(id _Nullable value, NSRange range,
86
+ BOOL *_Nonnull stop) {
87
+ UIFont *font = (UIFont *)value;
88
+ if (font == nullptr) {
89
+ return;
90
+ }
58
91
  UIFont *newFont = [font setSize:[self getHeadingFontSize]];
59
92
  if ([self isHeadingBold]) {
60
93
  newFont = [newFont setBold];
@@ -63,9 +96,8 @@
63
96
  addAttribute:NSFontAttributeName
64
97
  value:newFont
65
98
  range:range];
66
- }
67
- }];
68
- [[self typedInput]->textView.textStorage endEditing];
99
+ }];
100
+ }
69
101
 
70
102
  // also toggle typing attributes
71
103
  if (withTypingAttr) {
@@ -76,34 +108,57 @@
76
108
  // will always be called on empty paragraphs so only typing attributes can be
77
109
  // changed
78
110
  - (void)addTypingAttributes {
79
- UIFont *currentFontAttr =
80
- (UIFont *)[self typedInput]
81
- ->textView.typingAttributes[NSFontAttributeName];
111
+ NSMutableDictionary *newTypingAttrs =
112
+ [[self typedInput]->textView.typingAttributes mutableCopy];
113
+
114
+ NSMutableParagraphStyle *pStyle =
115
+ [newTypingAttrs[NSParagraphStyleAttributeName] mutableCopy];
116
+ if (pStyle != nullptr) {
117
+ pStyle.textLists = @[ [self getTextListObject] ];
118
+ newTypingAttrs[NSParagraphStyleAttributeName] = pStyle;
119
+ }
120
+
121
+ UIFont *currentFontAttr = (UIFont *)newTypingAttrs[NSFontAttributeName];
82
122
  if (currentFontAttr != nullptr) {
83
- NSMutableDictionary *newTypingAttrs =
84
- [[self typedInput]->textView.typingAttributes mutableCopy];
85
123
  UIFont *newFont = [currentFontAttr setSize:[self getHeadingFontSize]];
86
124
  if ([self isHeadingBold]) {
87
125
  newFont = [newFont setBold];
88
126
  }
89
127
  newTypingAttrs[NSFontAttributeName] = newFont;
90
- [self typedInput]->textView.typingAttributes = newTypingAttrs;
91
128
  }
129
+
130
+ [self typedInput]->textView.typingAttributes = newTypingAttrs;
92
131
  }
93
132
 
94
133
  // we need to remove the style from the whole paragraph
95
134
  - (void)removeAttributes:(NSRange)range {
96
- NSRange paragraphRange = [[self typedInput]->textView.textStorage.string
97
- paragraphRangeForRange:range];
98
-
99
- [[self typedInput]->textView.textStorage beginEditing];
100
- [[self typedInput]->textView.textStorage
101
- enumerateAttribute:NSFontAttributeName
102
- inRange:paragraphRange
103
- options:0
104
- usingBlock:^(id _Nullable value, NSRange range,
105
- BOOL *_Nonnull stop) {
106
- if ([self styleCondition:value range:range]) {
135
+ NSArray *paragraphs =
136
+ [ParagraphsUtils getSeparateParagraphsRangesIn:[self typedInput]->textView
137
+ range:range];
138
+
139
+ for (NSValue *value in paragraphs) {
140
+ NSRange paragraphRange = [value rangeValue];
141
+ [[self typedInput]->textView.textStorage
142
+ enumerateAttribute:NSParagraphStyleAttributeName
143
+ inRange:paragraphRange
144
+ options:0
145
+ usingBlock:^(id _Nullable value, NSRange range,
146
+ BOOL *_Nonnull stop) {
147
+ NSMutableParagraphStyle *pStyle =
148
+ [(NSParagraphStyle *)value mutableCopy];
149
+ pStyle.textLists = @[];
150
+ [[self typedInput]->textView.textStorage
151
+ addAttribute:NSParagraphStyleAttributeName
152
+ value:pStyle
153
+ range:range];
154
+ }];
155
+
156
+ [[self typedInput]->textView.textStorage
157
+ enumerateAttribute:NSFontAttributeName
158
+ inRange:paragraphRange
159
+ options:0
160
+ usingBlock:^(id _Nullable value, NSRange range,
161
+ BOOL *_Nonnull stop) {
107
162
  UIFont *newFont = [(UIFont *)value
108
163
  setSize:[[[self typedInput]->config scaledPrimaryFontSize]
109
164
  floatValue]];
@@ -114,60 +169,57 @@
114
169
  addAttribute:NSFontAttributeName
115
170
  value:newFont
116
171
  range:range];
117
- }
118
- }];
119
- [[self typedInput]->textView.textStorage endEditing];
172
+ }];
173
+ }
120
174
 
121
175
  // typing attributes still need to be removed
122
- UIFont *currentFontAttr =
123
- (UIFont *)[self typedInput]
124
- ->textView.typingAttributes[NSFontAttributeName];
176
+ NSMutableDictionary *newTypingAttrs =
177
+ [[self typedInput]->textView.typingAttributes mutableCopy];
178
+
179
+ NSMutableParagraphStyle *pStyle =
180
+ [newTypingAttrs[NSParagraphStyleAttributeName] mutableCopy];
181
+ if (pStyle != nullptr) {
182
+ pStyle.textLists = @[];
183
+ newTypingAttrs[NSParagraphStyleAttributeName] = pStyle;
184
+ }
185
+
186
+ UIFont *currentFontAttr = (UIFont *)newTypingAttrs[NSFontAttributeName];
125
187
  if (currentFontAttr != nullptr) {
126
- NSMutableDictionary *newTypingAttrs =
127
- [[self typedInput]->textView.typingAttributes mutableCopy];
128
188
  UIFont *newFont = [currentFontAttr
129
189
  setSize:[[[self typedInput]->config scaledPrimaryFontSize] floatValue]];
130
190
  if ([self isHeadingBold]) {
131
191
  newFont = [newFont removeBold];
132
192
  }
133
193
  newTypingAttrs[NSFontAttributeName] = newFont;
134
- [self typedInput]->textView.typingAttributes = newTypingAttrs;
135
194
  }
195
+
196
+ [self typedInput]->textView.typingAttributes = newTypingAttrs;
136
197
  }
137
198
 
138
199
  - (void)removeTypingAttributes {
139
- // all the heading still needs to be removed because this function may be
140
- // called in conflicting styles logic typing attributes already get removed in
141
- // there as well
200
+ // All the heading still needs to be removed because this function may be
201
+ // called in conflicting styles logic. Typing attributes already get removed
202
+ // in there as well.
142
203
  [self removeAttributes:[self typedInput]->textView.selectedRange];
143
204
  }
144
205
 
145
- // when the traits already change, the getHeadginFontSize will return the new
146
- // font size and no headings would be properly detected, so that's why we have
147
- // to use the latest applied font size rather than that value.
148
206
  - (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
149
- UIFont *font = (UIFont *)value;
150
- if (font == nullptr) {
151
- return NO;
152
- }
153
-
154
- if (self.lastAppliedFontSize > 0.0) {
155
- return font.pointSize == self.lastAppliedFontSize;
156
- }
157
-
158
- return font.pointSize == [self getHeadingFontSize];
207
+ NSParagraphStyle *paragraph = (NSParagraphStyle *)value;
208
+ return paragraph != nullptr && paragraph.textLists.count == 1 &&
209
+ [paragraph.textLists.firstObject.markerFormat
210
+ isEqualToString:[self getTextListObject].markerFormat];
159
211
  }
160
212
 
161
213
  - (BOOL)detectStyle:(NSRange)range {
162
214
  if (range.length >= 1) {
163
- return [OccurenceUtils detect:NSFontAttributeName
215
+ return [OccurenceUtils detect:NSParagraphStyleAttributeName
164
216
  withInput:[self typedInput]
165
217
  inRange:range
166
218
  withCondition:^BOOL(id _Nullable value, NSRange range) {
167
219
  return [self styleCondition:value range:range];
168
220
  }];
169
221
  } else {
170
- return [OccurenceUtils detect:NSFontAttributeName
222
+ return [OccurenceUtils detect:NSParagraphStyleAttributeName
171
223
  withInput:[self typedInput]
172
224
  atIndex:range.location
173
225
  checkPrevious:YES
@@ -178,7 +230,7 @@
178
230
  }
179
231
 
180
232
  - (BOOL)anyOccurence:(NSRange)range {
181
- return [OccurenceUtils any:NSFontAttributeName
233
+ return [OccurenceUtils any:NSParagraphStyleAttributeName
182
234
  withInput:[self typedInput]
183
235
  inRange:range
184
236
  withCondition:^BOOL(id _Nullable value, NSRange range) {
@@ -187,7 +239,7 @@
187
239
  }
188
240
 
189
241
  - (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
190
- return [OccurenceUtils all:NSFontAttributeName
242
+ return [OccurenceUtils all:NSParagraphStyleAttributeName
191
243
  withInput:[self typedInput]
192
244
  inRange:range
193
245
  withCondition:^BOOL(id _Nullable value, NSRange range) {
@@ -208,31 +260,51 @@
208
260
  additionalAttributes:nullptr
209
261
  input:[self typedInput]
210
262
  withSelection:YES];
211
- // remove the attribtues at the new selection
263
+ // remove the attributes at the new selection
212
264
  [self removeAttributes:[self typedInput]->textView.selectedRange];
213
265
  return YES;
214
266
  }
215
267
  return NO;
216
268
  }
217
269
 
218
- // backspacing a line after a heading "into" a heading will not result in the
219
- // text attaining heading attributes so, we do it manually
220
- - (void)handleImproperHeadings {
221
- NSArray *occurences = [self
222
- findAllOccurences:NSMakeRange(0,
223
- [self typedInput]
224
- ->textView.textStorage.string.length)];
225
- for (StylePair *pair in occurences) {
226
- NSRange occurenceRange = [pair.rangeValue rangeValue];
227
- NSRange paragraphRange = [[self typedInput]->textView.textStorage.string
228
- paragraphRangeForRange:occurenceRange];
229
- if (!NSEqualRanges(occurenceRange, paragraphRange)) {
230
- // we have a heading but it does not span its whole paragraph - let's fix
231
- // it
232
- [self addAttributes:paragraphRange withTypingAttr:NO];
233
- }
270
+ // Backspacing a line after a heading "into" a heading will not result in the
271
+ // text not receiving heading font attributes.
272
+ // Hence, we fix these attributes then.
273
+ - (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text {
274
+ // Must be a backspace.
275
+ if (text.length != 0) {
276
+ return NO;
234
277
  }
235
- _lastAppliedFontSize = [self getHeadingFontSize];
278
+
279
+ // Backspace must have removed a newline character.
280
+ NSString *removedString =
281
+ [[self typedInput]->textView.textStorage.string substringWithRange:range];
282
+ if ([removedString
283
+ rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]]
284
+ .location == NSNotFound) {
285
+ return NO;
286
+ }
287
+
288
+ // Heading style must have been present in a paragraph before the backspaced
289
+ // range.
290
+ NSRange paragraphBeforeBackspaceRange =
291
+ [[self typedInput]->textView.textStorage.string
292
+ paragraphRangeForRange:NSMakeRange(range.location, 0)];
293
+ if (![self detectStyle:paragraphBeforeBackspaceRange]) {
294
+ return NO;
295
+ }
296
+
297
+ // Manually do the replacing.
298
+ [TextInsertionUtils replaceText:text
299
+ at:range
300
+ additionalAttributes:nullptr
301
+ input:[self typedInput]
302
+ withSelection:YES];
303
+ // Reapply attributes at the beginning of the backspaced range (it will cover
304
+ // the whole paragraph properly).
305
+ [self addAttributes:NSMakeRange(range.location, 0) withTypingAttr:YES];
306
+
307
+ return YES;
236
308
  }
237
309
 
238
310
  @end
@@ -0,0 +1,10 @@
1
+ #import <UIKit/UIKit.h>
2
+
3
+ @class EnrichedTextInputView;
4
+
5
+ @interface CheckboxHitTestUtils : NSObject
6
+
7
+ + (NSInteger)hitTestCheckboxAtPoint:(CGPoint)pt
8
+ inInput:(EnrichedTextInputView *)input;
9
+
10
+ @end
@@ -0,0 +1,123 @@
1
+ #import "CheckboxHitTestUtils.h"
2
+ #import "EnrichedTextInputView.h"
3
+ #import "InputConfig.h"
4
+ #import "StyleHeaders.h"
5
+
6
+ static const CGFloat kCheckboxHitSlopLeft = 8.0;
7
+ static const CGFloat kCheckboxHitSlopVertical = 6.0;
8
+
9
+ @implementation CheckboxHitTestUtils
10
+
11
+ // MARK: - Coordinate helpers
12
+
13
+ + (CGPoint)containerPointFromViewPoint:(CGPoint)point
14
+ textView:(UITextView *)textView {
15
+ return CGPointMake(point.x - textView.textContainerInset.left,
16
+ point.y - textView.textContainerInset.top);
17
+ }
18
+
19
+ // MARK: - Glyph lookup
20
+
21
+ + (NSUInteger)glyphIndexAtContainerPoint:(CGPoint)point
22
+ textView:(UITextView *)textView {
23
+ return [textView.layoutManager glyphIndexForPoint:point
24
+ inTextContainer:textView.textContainer
25
+ fractionOfDistanceThroughGlyph:nil];
26
+ }
27
+
28
+ // MARK: - Checkbox detection
29
+
30
+ + (BOOL)isCheckboxGlyph:(NSUInteger)glyphIndex
31
+ inInput:(EnrichedTextInputView *)input {
32
+ UITextView *textView = input->textView;
33
+ NSLayoutManager *layoutManager = textView.layoutManager;
34
+ NSTextStorage *storage = textView.textStorage;
35
+
36
+ NSUInteger charIndex =
37
+ [layoutManager characterIndexForGlyphAtIndex:glyphIndex];
38
+
39
+ if (charIndex >= storage.length) {
40
+ return NO;
41
+ }
42
+
43
+ CheckboxListStyle *checkboxListStyle =
44
+ (CheckboxListStyle *)
45
+ input->stylesDict[@([CheckboxListStyle getStyleType])];
46
+
47
+ if (!checkboxListStyle) {
48
+ return NO;
49
+ }
50
+
51
+ return [checkboxListStyle detectStyle:NSMakeRange(charIndex, 0)];
52
+ }
53
+
54
+ // MARK: - Checkbox rect
55
+
56
+ + (CGRect)checkboxRectForGlyphIndex:(NSUInteger)glyphIndex
57
+ inInput:(EnrichedTextInputView *)input {
58
+ UITextView *textView = input->textView;
59
+ NSLayoutManager *layoutManager = textView.layoutManager;
60
+ InputConfig *config = input->config;
61
+
62
+ if (!config) {
63
+ return CGRectNull;
64
+ }
65
+
66
+ CGRect lineRect = [layoutManager lineFragmentRectForGlyphAtIndex:glyphIndex
67
+ effectiveRange:nil];
68
+
69
+ CGFloat originX = lineRect.origin.x + config.checkboxListMarginLeft;
70
+
71
+ CGFloat originY = lineRect.origin.y +
72
+ (lineRect.size.height - config.checkboxListBoxSize) / 2.0;
73
+
74
+ return CGRectMake(originX, originY, config.checkboxListBoxSize,
75
+ config.checkboxListBoxSize);
76
+ }
77
+
78
+ // MARK: - Hit rect
79
+
80
+ + (CGRect)expandedHitRectFromCheckboxRect:(CGRect)rect {
81
+ if (CGRectIsNull(rect))
82
+ return rect;
83
+
84
+ return CGRectInset(rect, -kCheckboxHitSlopLeft, -kCheckboxHitSlopVertical);
85
+ }
86
+
87
+ // MARK: - Public API
88
+
89
+ + (NSInteger)hitTestCheckboxAtPoint:(CGPoint)point
90
+ inInput:(EnrichedTextInputView *)input {
91
+ UITextView *textView = input->textView;
92
+
93
+ CGPoint containerPoint = [self containerPointFromViewPoint:point
94
+ textView:textView];
95
+
96
+ NSUInteger glyphIndex = [self glyphIndexAtContainerPoint:containerPoint
97
+ textView:textView];
98
+
99
+ if (glyphIndex == NSNotFound) {
100
+ return -1;
101
+ }
102
+
103
+ if (![self isCheckboxGlyph:glyphIndex inInput:input]) {
104
+ return -1;
105
+ }
106
+
107
+ CGRect checkboxRect = [self checkboxRectForGlyphIndex:glyphIndex
108
+ inInput:input];
109
+
110
+ if (CGRectIsNull(checkboxRect)) {
111
+ return -1;
112
+ }
113
+
114
+ CGRect hitRect = [self expandedHitRectFromCheckboxRect:checkboxRect];
115
+
116
+ if (!CGRectContainsPoint(hitRect, containerPoint)) {
117
+ return -1;
118
+ }
119
+
120
+ return [textView.layoutManager characterIndexForGlyphAtIndex:glyphIndex];
121
+ }
122
+
123
+ @end
@@ -22,6 +22,8 @@
22
22
  typedInput->stylesDict[@([BlockQuoteStyle getStyleType])];
23
23
  CodeBlockStyle *cbStyle =
24
24
  typedInput->stylesDict[@([CodeBlockStyle getStyleType])];
25
+ CheckboxListStyle *cbLStyle =
26
+ typedInput->stylesDict[@([CheckboxListStyle getStyleType])];
25
27
 
26
28
  if (typedInput == nullptr) {
27
29
  return NO;
@@ -57,17 +59,35 @@
57
59
  // applied
58
60
  // - reapply the paragraph style that was present so that a zero width space
59
61
  // appears here
60
- NSArray *handledStyles = @[ ulStyle, olStyle, bqStyle, cbStyle ];
62
+ NSArray *handledStyles = @[ ulStyle, olStyle, bqStyle, cbStyle, cbLStyle ];
61
63
  for (id<BaseStyleProtocol> style in handledStyles) {
62
64
  if ([style detectStyle:nonNewlineRange]) {
63
- [TextInsertionUtils replaceText:text
64
- at:range
65
- additionalAttributes:nullptr
66
- input:typedInput
67
- withSelection:YES];
68
- typedInput->textView.typingAttributes =
69
- typedInput->defaultTypingAttributes;
70
- [style addAttributes:NSMakeRange(range.location, 0) withTypingAttr:YES];
65
+ // For checkbox lists, preserve the current checked state
66
+ if (style == cbLStyle) {
67
+ BOOL isCurrentlyChecked =
68
+ [cbLStyle getCheckboxStateAt:range.location];
69
+ [TextInsertionUtils replaceText:text
70
+ at:range
71
+ additionalAttributes:nullptr
72
+ input:typedInput
73
+ withSelection:YES];
74
+ typedInput->textView.typingAttributes =
75
+ typedInput->defaultTypingAttributes;
76
+ [cbLStyle addAttributesWithCheckedValue:isCurrentlyChecked
77
+ inRange:NSMakeRange(range.location, 0)
78
+ withTypingAttr:YES];
79
+ } else {
80
+ [TextInsertionUtils replaceText:text
81
+ at:range
82
+ additionalAttributes:nullptr
83
+ input:typedInput
84
+ withSelection:YES];
85
+ typedInput->textView.typingAttributes =
86
+ typedInput->defaultTypingAttributes;
87
+ [style addAttributes:NSMakeRange(range.location, 0)
88
+ withTypingAttr:YES];
89
+ }
90
+
71
91
  return YES;
72
92
  }
73
93
  }
@@ -116,63 +136,73 @@
116
136
  return NO;
117
137
  }
118
138
 
119
- if (text.length == 0) {
120
- NSRange leftRange = [typedInput->textView.textStorage.string
121
- paragraphRangeForRange:NSMakeRange(range.location, 0)];
139
+ // Must be a backspace.
140
+ if (text.length > 0) {
141
+ return NO;
142
+ }
122
143
 
123
- id<BaseStyleProtocol> leftParagraphStyle = nullptr;
124
- for (NSNumber *key in typedInput->stylesDict) {
125
- id<BaseStyleProtocol> style = typedInput->stylesDict[key];
126
- if ([[style class] isParagraphStyle] && [style detectStyle:leftRange]) {
127
- leftParagraphStyle = style;
128
- }
129
- }
144
+ // Backspace must have removed a newline character.
145
+ NSString *removedString =
146
+ [typedInput->textView.textStorage.string substringWithRange:range];
147
+ if ([removedString
148
+ rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]]
149
+ .location == NSNotFound) {
150
+ return NO;
151
+ }
130
152
 
131
- if (leftParagraphStyle == nullptr) {
132
- return NO;
133
- }
153
+ NSRange leftRange = [typedInput->textView.textStorage.string
154
+ paragraphRangeForRange:NSMakeRange(range.location, 0)];
134
155
 
135
- // index out of bounds
136
- NSUInteger rightRangeStart = range.location + range.length;
137
- if (rightRangeStart >= typedInput->textView.textStorage.string.length) {
138
- return NO;
156
+ id<BaseStyleProtocol> leftParagraphStyle = nullptr;
157
+ for (NSNumber *key in typedInput->stylesDict) {
158
+ id<BaseStyleProtocol> style = typedInput->stylesDict[key];
159
+ if ([[style class] isParagraphStyle] && [style detectStyle:leftRange]) {
160
+ leftParagraphStyle = style;
139
161
  }
162
+ }
140
163
 
141
- NSRange rightRange = [typedInput->textView.textStorage.string
142
- paragraphRangeForRange:NSMakeRange(rightRangeStart, 1)];
164
+ if (leftParagraphStyle == nullptr) {
165
+ return NO;
166
+ }
143
167
 
144
- StyleType type = [[leftParagraphStyle class] getStyleType];
168
+ // index out of bounds
169
+ NSUInteger rightRangeStart = range.location + range.length;
170
+ if (rightRangeStart >= typedInput->textView.textStorage.string.length) {
171
+ return NO;
172
+ }
145
173
 
146
- NSArray *conflictingStyles = [typedInput
147
- getPresentStyleTypesFrom:typedInput->conflictingStyles[@(type)]
148
- range:rightRange];
149
- NSArray *blockingStyles =
150
- [typedInput getPresentStyleTypesFrom:typedInput->blockingStyles[@(type)]
151
- range:rightRange];
152
- NSArray *allToBeRemoved =
153
- [conflictingStyles arrayByAddingObjectsFromArray:blockingStyles];
174
+ NSRange rightRange = [typedInput->textView.textStorage.string
175
+ paragraphRangeForRange:NSMakeRange(rightRangeStart, 1)];
154
176
 
155
- for (NSNumber *style in allToBeRemoved) {
156
- id<BaseStyleProtocol> styleClass = typedInput->stylesDict[style];
177
+ StyleType type = [[leftParagraphStyle class] getStyleType];
157
178
 
158
- // for ranges, we need to remove each occurence
159
- NSArray<StylePair *> *allOccurences =
160
- [styleClass findAllOccurences:rightRange];
179
+ NSArray *conflictingStyles = [typedInput
180
+ getPresentStyleTypesFrom:typedInput->conflictingStyles[@(type)]
181
+ range:rightRange];
182
+ NSArray *blockingStyles =
183
+ [typedInput getPresentStyleTypesFrom:typedInput->blockingStyles[@(type)]
184
+ range:rightRange];
185
+ NSArray *allToBeRemoved =
186
+ [conflictingStyles arrayByAddingObjectsFromArray:blockingStyles];
161
187
 
162
- for (StylePair *pair in allOccurences) {
163
- [styleClass removeAttributes:[pair.rangeValue rangeValue]];
164
- }
165
- }
188
+ for (NSNumber *style in allToBeRemoved) {
189
+ id<BaseStyleProtocol> styleClass = typedInput->stylesDict[style];
166
190
 
167
- [TextInsertionUtils replaceText:text
168
- at:range
169
- additionalAttributes:nullptr
170
- input:typedInput
171
- withSelection:YES];
172
- return YES;
191
+ // for ranges, we need to remove each occurence
192
+ NSArray<StylePair *> *allOccurences =
193
+ [styleClass findAllOccurences:rightRange];
194
+
195
+ for (StylePair *pair in allOccurences) {
196
+ [styleClass removeAttributes:[pair.rangeValue rangeValue]];
197
+ }
173
198
  }
174
199
 
175
- return NO;
200
+ [TextInsertionUtils replaceText:text
201
+ at:range
202
+ additionalAttributes:nullptr
203
+ input:typedInput
204
+ withSelection:YES];
205
+ return YES;
176
206
  }
177
207
 
178
208
  /**
@@ -0,0 +1,17 @@
1
+ typedef NS_ENUM(NSInteger, TextBlockTapKind) {
2
+ TextBlockTapKindNone = 0,
3
+ TextBlockTapKindCheckbox,
4
+ };
5
+
6
+ @class EnrichedTextInputView;
7
+
8
+ @interface TextBlockTapGestureRecognizer : UITapGestureRecognizer
9
+ - (instancetype _Nonnull)initWithInput:(id _Nonnull)input
10
+ action:(SEL _Nonnull)action;
11
+
12
+ @property(nonatomic, weak) EnrichedTextInputView *input;
13
+
14
+ @property(nonatomic, assign, readonly) TextBlockTapKind tapKind;
15
+ @property(nonatomic, assign, readonly) NSInteger characterIndex;
16
+
17
+ @end