react-native-enriched 0.2.0 → 0.3.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 (186) hide show
  1. package/README.md +16 -17
  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/EventEmitters.cpp +156 -0
  6. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +147 -0
  7. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.cpp +10 -0
  8. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +194 -0
  9. package/android/lint.gradle +70 -0
  10. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputConnectionWrapper.kt +140 -0
  11. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +304 -83
  12. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewLayoutManager.kt +3 -1
  13. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +166 -51
  14. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +1 -3
  15. package/android/src/main/java/com/swmansion/enriched/MeasurementStore.kt +70 -21
  16. package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +21 -11
  17. package/android/src/main/java/com/swmansion/enriched/events/OnChangeHtmlEvent.kt +8 -9
  18. package/android/src/main/java/com/swmansion/enriched/events/OnChangeSelectionEvent.kt +10 -9
  19. package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateDeprecatedEvent.kt +21 -0
  20. package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateEvent.kt +9 -12
  21. package/android/src/main/java/com/swmansion/enriched/events/OnChangeTextEvent.kt +10 -10
  22. package/android/src/main/java/com/swmansion/enriched/events/OnInputBlurEvent.kt +7 -9
  23. package/android/src/main/java/com/swmansion/enriched/events/OnInputFocusEvent.kt +7 -9
  24. package/android/src/main/java/com/swmansion/enriched/events/OnInputKeyPressEvent.kt +27 -0
  25. package/android/src/main/java/com/swmansion/enriched/events/OnLinkDetectedEvent.kt +13 -11
  26. package/android/src/main/java/com/swmansion/enriched/events/OnMentionDetectedEvent.kt +10 -9
  27. package/android/src/main/java/com/swmansion/enriched/events/OnMentionEvent.kt +9 -8
  28. package/android/src/main/java/com/swmansion/enriched/events/OnRequestHtmlResultEvent.kt +32 -0
  29. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +24 -5
  30. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +8 -1
  31. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +10 -2
  32. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +8 -1
  33. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +8 -1
  34. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +8 -1
  35. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH4Span.kt +24 -0
  36. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH5Span.kt +24 -0
  37. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH6Span.kt +24 -0
  38. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +34 -17
  39. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +8 -1
  40. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +7 -1
  41. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +10 -4
  42. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +14 -11
  43. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +18 -11
  44. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +174 -72
  45. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +7 -1
  46. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +7 -1
  47. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +11 -5
  48. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedBlockSpan.kt +3 -2
  49. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedHeadingSpan.kt +1 -2
  50. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedInlineSpan.kt +1 -2
  51. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedParagraphSpan.kt +3 -2
  52. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +5 -0
  53. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedZeroWidthSpaceSpan.kt +1 -2
  54. package/android/src/main/java/com/swmansion/enriched/spans/utils/ForceRedrawSpan.kt +2 -1
  55. package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +155 -20
  56. package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +25 -8
  57. package/android/src/main/java/com/swmansion/enriched/styles/ListStyles.kt +60 -20
  58. package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +161 -25
  59. package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +128 -52
  60. package/android/src/main/java/com/swmansion/enriched/utils/AsyncDrawable.kt +10 -7
  61. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedConstants.kt +11 -0
  62. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedEditableFactory.kt +17 -0
  63. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +136 -87
  64. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSelection.kt +71 -42
  65. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpanState.kt +183 -48
  66. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpannable.kt +82 -0
  67. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpannableStringBuilder.kt +15 -0
  68. package/android/src/main/java/com/swmansion/enriched/utils/Utils.kt +0 -70
  69. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +46 -14
  70. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedTextWatcher.kt +34 -11
  71. package/android/src/main/new_arch/CMakeLists.txt +6 -0
  72. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +6 -6
  73. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +6 -6
  74. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +19 -19
  75. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +40 -51
  76. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +13 -15
  77. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +23 -21
  78. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +35 -36
  79. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +4 -4
  80. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +13 -14
  81. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/conversions.h +33 -14
  82. package/ios/EnrichedTextInputView.h +26 -14
  83. package/ios/EnrichedTextInputView.mm +1209 -586
  84. package/ios/config/InputConfig.h +24 -6
  85. package/ios/config/InputConfig.mm +154 -38
  86. package/ios/{utils → extensions}/ColorExtension.mm +7 -5
  87. package/ios/extensions/FontExtension.mm +106 -0
  88. package/ios/{utils → extensions}/LayoutManagerExtension.h +1 -1
  89. package/ios/extensions/LayoutManagerExtension.mm +396 -0
  90. package/ios/{utils → extensions}/StringExtension.mm +19 -16
  91. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +156 -0
  92. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +147 -0
  93. package/ios/generated/RNEnrichedTextInputViewSpec/Props.cpp +10 -0
  94. package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +194 -0
  95. package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +95 -0
  96. package/ios/inputParser/InputParser.h +5 -5
  97. package/ios/inputParser/InputParser.mm +864 -380
  98. package/ios/inputTextView/InputTextView.h +1 -1
  99. package/ios/inputTextView/InputTextView.mm +100 -59
  100. package/ios/{utils → interfaces}/BaseStyleProtocol.h +2 -2
  101. package/ios/interfaces/ImageAttachment.h +10 -0
  102. package/ios/interfaces/ImageAttachment.mm +36 -0
  103. package/ios/interfaces/LinkRegexConfig.h +19 -0
  104. package/ios/interfaces/LinkRegexConfig.mm +37 -0
  105. package/ios/interfaces/MediaAttachment.h +23 -0
  106. package/ios/interfaces/MediaAttachment.mm +31 -0
  107. package/ios/{utils → interfaces}/MentionParams.h +0 -1
  108. package/ios/{utils → interfaces}/MentionStyleProps.mm +27 -20
  109. package/ios/{utils → interfaces}/StyleHeaders.h +37 -15
  110. package/ios/{utils → interfaces}/StyleTypeEnum.h +3 -0
  111. package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +11 -9
  112. package/ios/internals/EnrichedTextInputViewShadowNode.h +28 -25
  113. package/ios/internals/EnrichedTextInputViewShadowNode.mm +45 -40
  114. package/ios/internals/EnrichedTextInputViewState.h +3 -1
  115. package/ios/styles/BlockQuoteStyle.mm +189 -118
  116. package/ios/styles/BoldStyle.mm +110 -63
  117. package/ios/styles/CodeBlockStyle.mm +204 -128
  118. package/ios/styles/H1Style.mm +10 -4
  119. package/ios/styles/H2Style.mm +10 -4
  120. package/ios/styles/H3Style.mm +10 -4
  121. package/ios/styles/H4Style.mm +17 -0
  122. package/ios/styles/H5Style.mm +17 -0
  123. package/ios/styles/H6Style.mm +17 -0
  124. package/ios/styles/HeadingStyleBase.mm +148 -86
  125. package/ios/styles/ImageStyle.mm +75 -73
  126. package/ios/styles/InlineCodeStyle.mm +162 -88
  127. package/ios/styles/ItalicStyle.mm +76 -52
  128. package/ios/styles/LinkStyle.mm +411 -232
  129. package/ios/styles/MentionStyle.mm +363 -246
  130. package/ios/styles/OrderedListStyle.mm +171 -106
  131. package/ios/styles/StrikethroughStyle.mm +52 -35
  132. package/ios/styles/UnderlineStyle.mm +68 -46
  133. package/ios/styles/UnorderedListStyle.mm +169 -106
  134. package/ios/utils/OccurenceUtils.h +42 -42
  135. package/ios/utils/OccurenceUtils.mm +142 -119
  136. package/ios/utils/ParagraphAttributesUtils.h +10 -2
  137. package/ios/utils/ParagraphAttributesUtils.mm +182 -71
  138. package/ios/utils/ParagraphsUtils.h +2 -1
  139. package/ios/utils/ParagraphsUtils.mm +41 -27
  140. package/ios/utils/TextInsertionUtils.h +13 -2
  141. package/ios/utils/TextInsertionUtils.mm +38 -20
  142. package/ios/utils/WordsUtils.h +2 -1
  143. package/ios/utils/WordsUtils.mm +32 -22
  144. package/ios/utils/ZeroWidthSpaceUtils.h +3 -1
  145. package/ios/utils/ZeroWidthSpaceUtils.mm +145 -79
  146. package/lib/module/EnrichedTextInput.js +61 -2
  147. package/lib/module/EnrichedTextInput.js.map +1 -1
  148. package/lib/module/EnrichedTextInputNativeComponent.ts +149 -12
  149. package/lib/module/{normalizeHtmlStyle.js → utils/normalizeHtmlStyle.js} +12 -0
  150. package/lib/module/utils/normalizeHtmlStyle.js.map +1 -0
  151. package/lib/module/utils/regexParser.js +46 -0
  152. package/lib/module/utils/regexParser.js.map +1 -0
  153. package/lib/typescript/src/EnrichedTextInput.d.ts +24 -14
  154. package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
  155. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +129 -12
  156. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
  157. package/lib/typescript/src/index.d.ts +1 -1
  158. package/lib/typescript/src/index.d.ts.map +1 -1
  159. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts +4 -0
  160. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts.map +1 -0
  161. package/lib/typescript/src/utils/regexParser.d.ts +3 -0
  162. package/lib/typescript/src/utils/regexParser.d.ts.map +1 -0
  163. package/package.json +17 -6
  164. package/src/EnrichedTextInput.tsx +96 -13
  165. package/src/EnrichedTextInputNativeComponent.ts +149 -12
  166. package/src/index.tsx +2 -0
  167. package/src/{normalizeHtmlStyle.ts → utils/normalizeHtmlStyle.ts} +14 -2
  168. package/src/utils/regexParser.ts +56 -0
  169. package/ios/utils/FontExtension.mm +0 -91
  170. package/ios/utils/LayoutManagerExtension.mm +0 -286
  171. package/lib/module/normalizeHtmlStyle.js.map +0 -1
  172. package/lib/typescript/src/normalizeHtmlStyle.d.ts +0 -4
  173. package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +0 -1
  174. package/ios/{utils → extensions}/ColorExtension.h +0 -0
  175. package/ios/{utils → extensions}/FontExtension.h +0 -0
  176. package/ios/{utils → extensions}/StringExtension.h +1 -1
  177. package/ios/{utils → interfaces}/ImageData.h +0 -0
  178. package/ios/{utils → interfaces}/ImageData.mm +0 -0
  179. package/ios/{utils → interfaces}/LinkData.h +0 -0
  180. package/ios/{utils → interfaces}/LinkData.mm +0 -0
  181. package/ios/{utils → interfaces}/MentionParams.mm +0 -0
  182. package/ios/{utils → interfaces}/MentionStyleProps.h +1 -1
  183. /package/ios/{utils → interfaces}/StylePair.h +0 -0
  184. /package/ios/{utils → interfaces}/StylePair.mm +0 -0
  185. /package/ios/{utils → interfaces}/TextDecorationLineEnum.h +0 -0
  186. /package/ios/{utils → interfaces}/TextDecorationLineEnum.mm +0 -0
@@ -1,15 +1,19 @@
1
- #import "StyleHeaders.h"
2
1
  #import "EnrichedTextInputView.h"
3
2
  #import "FontExtension.h"
4
3
  #import "OccurenceUtils.h"
4
+ #import "StyleHeaders.h"
5
5
 
6
6
  @implementation BoldStyle {
7
7
  EnrichedTextInputView *_input;
8
8
  }
9
9
 
10
- + (StyleType)getStyleType { return Bold; }
10
+ + (StyleType)getStyleType {
11
+ return Bold;
12
+ }
11
13
 
12
- + (BOOL)isParagraphStyle { return NO; }
14
+ + (BOOL)isParagraphStyle {
15
+ return NO;
16
+ }
13
17
 
14
18
  - (instancetype)initWithInput:(id)input {
15
19
  self = [super init];
@@ -19,31 +23,39 @@
19
23
 
20
24
  - (void)applyStyle:(NSRange)range {
21
25
  BOOL isStylePresent = [self detectStyle:range];
22
- if(range.length >= 1) {
23
- isStylePresent ? [self removeAttributes:range] : [self addAttributes:range];
26
+ if (range.length >= 1) {
27
+ isStylePresent ? [self removeAttributes:range]
28
+ : [self addAttributes:range withTypingAttr:YES];
24
29
  } else {
25
30
  isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
26
31
  }
27
32
  }
28
33
 
29
- - (void)addAttributes:(NSRange)range {
34
+ - (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
30
35
  [_input->textView.textStorage beginEditing];
31
- [_input->textView.textStorage enumerateAttribute:NSFontAttributeName inRange:range options:0
32
- usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
33
- UIFont *font = (UIFont *)value;
34
- if(font != nullptr) {
35
- UIFont *newFont = [font setBold];
36
- [_input->textView.textStorage addAttribute:NSFontAttributeName value:newFont range:range];
37
- }
38
- }
39
- ];
36
+ [_input->textView.textStorage
37
+ enumerateAttribute:NSFontAttributeName
38
+ inRange:range
39
+ options:0
40
+ usingBlock:^(id _Nullable value, NSRange range,
41
+ BOOL *_Nonnull stop) {
42
+ UIFont *font = (UIFont *)value;
43
+ if (font != nullptr) {
44
+ UIFont *newFont = [font setBold];
45
+ [_input->textView.textStorage addAttribute:NSFontAttributeName
46
+ value:newFont
47
+ range:range];
48
+ }
49
+ }];
40
50
  [_input->textView.textStorage endEditing];
41
51
  }
42
52
 
43
53
  - (void)addTypingAttributes {
44
- UIFont *currentFontAttr = (UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
45
- if(currentFontAttr != nullptr) {
46
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
54
+ UIFont *currentFontAttr =
55
+ (UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
56
+ if (currentFontAttr != nullptr) {
57
+ NSMutableDictionary *newTypingAttrs =
58
+ [_input->textView.typingAttributes mutableCopy];
47
59
  newTypingAttrs[NSFontAttributeName] = [currentFontAttr setBold];
48
60
  _input->textView.typingAttributes = newTypingAttrs;
49
61
  }
@@ -51,77 +63,112 @@
51
63
 
52
64
  - (void)removeAttributes:(NSRange)range {
53
65
  [_input->textView.textStorage beginEditing];
54
- [_input->textView.textStorage enumerateAttribute:NSFontAttributeName inRange:range options:0
55
- usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
56
- UIFont *font = (UIFont *)value;
57
- if(font != nullptr) {
58
- UIFont *newFont = [font removeBold];
59
- [_input->textView.textStorage addAttribute:NSFontAttributeName value:newFont range:range];
60
- }
61
- }
62
- ];
66
+ [_input->textView.textStorage
67
+ enumerateAttribute:NSFontAttributeName
68
+ inRange:range
69
+ options:0
70
+ usingBlock:^(id _Nullable value, NSRange range,
71
+ BOOL *_Nonnull stop) {
72
+ UIFont *font = (UIFont *)value;
73
+ if (font != nullptr) {
74
+ UIFont *newFont = [font removeBold];
75
+ [_input->textView.textStorage addAttribute:NSFontAttributeName
76
+ value:newFont
77
+ range:range];
78
+ }
79
+ }];
63
80
  [_input->textView.textStorage endEditing];
64
81
  }
65
82
 
66
83
  - (void)removeTypingAttributes {
67
- UIFont *currentFontAttr = (UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
68
- if(currentFontAttr != nullptr) {
69
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
84
+ UIFont *currentFontAttr =
85
+ (UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
86
+ if (currentFontAttr != nullptr) {
87
+ NSMutableDictionary *newTypingAttrs =
88
+ [_input->textView.typingAttributes mutableCopy];
70
89
  newTypingAttrs[NSFontAttributeName] = [currentFontAttr removeBold];
71
90
  _input->textView.typingAttributes = newTypingAttrs;
72
91
  }
73
92
  }
74
93
 
75
94
  - (BOOL)boldHeadingConflictsInRange:(NSRange)range type:(StyleType)type {
76
- if(type == H1) {
77
- if(![_input->config h1Bold]) { return NO; }
78
- } else if(type == H2) {
79
- if(![_input->config h2Bold]) { return NO; }
80
- } else if(type == H3) {
81
- if(![_input->config h3Bold]) { return NO; }
95
+ if (type == H1) {
96
+ if (![_input->config h1Bold]) {
97
+ return NO;
98
+ }
99
+ } else if (type == H2) {
100
+ if (![_input->config h2Bold]) {
101
+ return NO;
102
+ }
103
+ } else if (type == H3) {
104
+ if (![_input->config h3Bold]) {
105
+ return NO;
106
+ }
107
+ } else if (type == H4) {
108
+ if (![_input->config h4Bold]) {
109
+ return NO;
110
+ }
111
+ } else if (type == H5) {
112
+ if (![_input->config h5Bold]) {
113
+ return NO;
114
+ }
115
+ } else if (type == H6) {
116
+ if (![_input->config h6Bold]) {
117
+ return NO;
118
+ }
82
119
  }
83
-
120
+
84
121
  id<BaseStyleProtocol> headingStyle = _input->stylesDict[@(type)];
85
- return range.length > 0
86
- ? [headingStyle anyOccurence:range]
87
- : [headingStyle detectStyle:range];
122
+ return range.length > 0 ? [headingStyle anyOccurence:range]
123
+ : [headingStyle detectStyle:range];
88
124
  }
89
125
 
90
- - (BOOL)styleCondition:(id _Nullable)value :(NSRange)range {
126
+ - (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
91
127
  UIFont *font = (UIFont *)value;
92
- return font != nullptr && [font isBold] && ![self boldHeadingConflictsInRange:range type:H1] && ![self boldHeadingConflictsInRange:range type:H2] && ![self boldHeadingConflictsInRange:range type:H3];
128
+ return font != nullptr && [font isBold] &&
129
+ ![self boldHeadingConflictsInRange:range type:H1] &&
130
+ ![self boldHeadingConflictsInRange:range type:H2] &&
131
+ ![self boldHeadingConflictsInRange:range type:H3] &&
132
+ ![self boldHeadingConflictsInRange:range type:H4] &&
133
+ ![self boldHeadingConflictsInRange:range type:H5] &&
134
+ ![self boldHeadingConflictsInRange:range type:H6];
93
135
  }
94
136
 
95
137
  - (BOOL)detectStyle:(NSRange)range {
96
- if(range.length >= 1) {
97
- return [OccurenceUtils detect:NSFontAttributeName withInput:_input inRange:range
98
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
99
- return [self styleCondition:value :range];
100
- }
101
- ];
138
+ if (range.length >= 1) {
139
+ return [OccurenceUtils detect:NSFontAttributeName
140
+ withInput:_input
141
+ inRange:range
142
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
143
+ return [self styleCondition:value range:range];
144
+ }];
102
145
  } else {
103
- return [OccurenceUtils detect:NSFontAttributeName withInput:_input atIndex:range.location checkPrevious:NO
104
- withCondition:^BOOL(id _Nullable value, NSRange range) {
105
- return [self styleCondition:value :range];
106
- }
107
- ];
146
+ return [OccurenceUtils detect:NSFontAttributeName
147
+ withInput:_input
148
+ atIndex:range.location
149
+ checkPrevious:NO
150
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
151
+ return [self styleCondition:value range:range];
152
+ }];
108
153
  }
109
154
  }
110
155
 
111
156
  - (BOOL)anyOccurence:(NSRange)range {
112
- return [OccurenceUtils any:NSFontAttributeName withInput:_input inRange:range
113
- withCondition:^BOOL(id _Nullable value, NSRange range) {
114
- return [self styleCondition:value :range];
115
- }
116
- ];
157
+ return [OccurenceUtils any:NSFontAttributeName
158
+ withInput:_input
159
+ inRange:range
160
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
161
+ return [self styleCondition:value range:range];
162
+ }];
117
163
  }
118
164
 
119
165
  - (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
120
- return [OccurenceUtils all:NSFontAttributeName withInput:_input inRange:range
121
- withCondition:^BOOL(id _Nullable value, NSRange range) {
122
- return [self styleCondition:value :range];
123
- }
124
- ];
166
+ return [OccurenceUtils all:NSFontAttributeName
167
+ withInput:_input
168
+ inRange:range
169
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
170
+ return [self styleCondition:value range:range];
171
+ }];
125
172
  }
126
173
 
127
174
  @end
@@ -1,19 +1,23 @@
1
- #import "StyleHeaders.h"
1
+ #import "ColorExtension.h"
2
2
  #import "EnrichedTextInputView.h"
3
3
  #import "FontExtension.h"
4
4
  #import "OccurenceUtils.h"
5
5
  #import "ParagraphsUtils.h"
6
+ #import "StyleHeaders.h"
6
7
  #import "TextInsertionUtils.h"
7
- #import "ColorExtension.h"
8
8
 
9
9
  @implementation CodeBlockStyle {
10
10
  EnrichedTextInputView *_input;
11
11
  NSArray *_stylesToExclude;
12
12
  }
13
13
 
14
- + (StyleType)getStyleType { return CodeBlock; }
14
+ + (StyleType)getStyleType {
15
+ return CodeBlock;
16
+ }
15
17
 
16
- + (BOOL)isParagraphStyle { return YES; }
18
+ + (BOOL)isParagraphStyle {
19
+ return YES;
20
+ }
17
21
 
18
22
  - (instancetype)initWithInput:(id)input {
19
23
  self = [super init];
@@ -24,94 +28,130 @@
24
28
 
25
29
  - (void)applyStyle:(NSRange)range {
26
30
  BOOL isStylePresent = [self detectStyle:range];
27
- if(range.length >= 1) {
28
- isStylePresent ? [self removeAttributes:range] : [self addAttributes:range];
31
+ if (range.length >= 1) {
32
+ isStylePresent ? [self removeAttributes:range]
33
+ : [self addAttributes:range withTypingAttr:YES];
29
34
  } else {
30
35
  isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
31
36
  }
32
37
  }
33
38
 
34
- - (void)addAttributes:(NSRange)range {
35
- NSTextList *codeBlockList = [[NSTextList alloc] initWithMarkerFormat:@"codeblock" options:0];
36
- NSArray *paragraphs = [ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView range:range];
37
- // if we fill empty lines with zero width spaces, we need to offset later ranges
39
+ - (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
40
+ NSTextList *codeBlockList =
41
+ [[NSTextList alloc] initWithMarkerFormat:@"codeblock" options:0];
42
+ NSArray *paragraphs =
43
+ [ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView
44
+ range:range];
45
+ // if we fill empty lines with zero width spaces, we need to offset later
46
+ // ranges
38
47
  NSInteger offset = 0;
39
48
  NSRange preModificationRange = _input->textView.selectedRange;
40
-
49
+
41
50
  // to not emit any space filling selection/text changes
42
51
  _input->blockEmitting = YES;
43
52
 
44
53
  for (NSValue *value in paragraphs) {
45
- NSRange pRange = NSMakeRange([value rangeValue].location + offset, [value rangeValue].length);
46
- // length 0 with first line, length 1 and newline with some empty lines in the middle
47
- if(pRange.length == 0 ||
48
- (pRange.length == 1 &&
49
- [[NSCharacterSet newlineCharacterSet] characterIsMember: [_input->textView.textStorage.string characterAtIndex:pRange.location]])
50
- ) {
51
- [TextInsertionUtils insertText:@"\u200B" at:pRange.location additionalAttributes:nullptr input:_input withSelection:NO];
54
+ NSRange pRange = NSMakeRange([value rangeValue].location + offset,
55
+ [value rangeValue].length);
56
+ // length 0 with first line, length 1 and newline with some empty lines in
57
+ // the middle
58
+ if (pRange.length == 0 ||
59
+ (pRange.length == 1 &&
60
+ [[NSCharacterSet newlineCharacterSet]
61
+ characterIsMember:[_input->textView.textStorage.string
62
+ characterAtIndex:pRange.location]])) {
63
+ [TextInsertionUtils insertText:@"\u200B"
64
+ at:pRange.location
65
+ additionalAttributes:nullptr
66
+ input:_input
67
+ withSelection:NO];
52
68
  pRange = NSMakeRange(pRange.location, pRange.length + 1);
53
69
  offset += 1;
54
70
  }
55
-
56
- [_input->textView.textStorage enumerateAttribute:NSParagraphStyleAttributeName inRange:pRange options:0
57
- usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
58
- NSMutableParagraphStyle *pStyle = [(NSParagraphStyle *)value mutableCopy];
59
- pStyle.textLists = @[codeBlockList];
60
- [_input->textView.textStorage addAttribute:NSParagraphStyleAttributeName value:pStyle range:range];
61
- }
62
- ];
71
+
72
+ [_input->textView.textStorage
73
+ enumerateAttribute:NSParagraphStyleAttributeName
74
+ inRange:pRange
75
+ options:0
76
+ usingBlock:^(id _Nullable value, NSRange range,
77
+ BOOL *_Nonnull stop) {
78
+ NSMutableParagraphStyle *pStyle =
79
+ [(NSParagraphStyle *)value mutableCopy];
80
+ pStyle.textLists = @[ codeBlockList ];
81
+ [_input->textView.textStorage
82
+ addAttribute:NSParagraphStyleAttributeName
83
+ value:pStyle
84
+ range:range];
85
+ }];
63
86
  }
64
-
87
+
65
88
  // back to emitting
66
89
  _input->blockEmitting = NO;
67
-
68
- if(preModificationRange.length == 0) {
69
- // fix selection if only one line was possibly made a list and filled with a space
90
+
91
+ if (preModificationRange.length == 0) {
92
+ // fix selection if only one line was possibly made a list and filled with a
93
+ // space
70
94
  _input->textView.selectedRange = preModificationRange;
71
95
  } else {
72
96
  // in other cases, fix the selection with newly made offsets
73
- _input->textView.selectedRange = NSMakeRange(preModificationRange.location, preModificationRange.length + offset);
97
+ _input->textView.selectedRange = NSMakeRange(
98
+ preModificationRange.location, preModificationRange.length + offset);
74
99
  }
75
-
100
+
76
101
  // also add typing attributes
77
- NSMutableDictionary *typingAttrs = [_input->textView.typingAttributes mutableCopy];
78
- NSMutableParagraphStyle *pStyle = [typingAttrs[NSParagraphStyleAttributeName] mutableCopy];
79
- pStyle.textLists = @[codeBlockList];
80
- typingAttrs[NSParagraphStyleAttributeName] = pStyle;
81
-
82
- _input->textView.typingAttributes = typingAttrs;
102
+ if (withTypingAttr) {
103
+ NSMutableDictionary *typingAttrs =
104
+ [_input->textView.typingAttributes mutableCopy];
105
+ NSMutableParagraphStyle *pStyle =
106
+ [typingAttrs[NSParagraphStyleAttributeName] mutableCopy];
107
+ pStyle.textLists = @[ codeBlockList ];
108
+ typingAttrs[NSParagraphStyleAttributeName] = pStyle;
109
+
110
+ _input->textView.typingAttributes = typingAttrs;
111
+ }
83
112
  }
84
113
 
85
114
  - (void)addTypingAttributes {
86
- [self addAttributes:_input->textView.selectedRange];
115
+ [self addAttributes:_input->textView.selectedRange withTypingAttr:YES];
87
116
  }
88
117
 
89
118
  - (void)removeAttributes:(NSRange)range {
90
- NSArray *paragraphs = [ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView range:range];
91
-
119
+ NSArray *paragraphs =
120
+ [ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView
121
+ range:range];
122
+
92
123
  [_input->textView.textStorage beginEditing];
93
-
94
- for(NSValue *value in paragraphs) {
124
+
125
+ for (NSValue *value in paragraphs) {
95
126
  NSRange pRange = [value rangeValue];
96
-
97
- [_input->textView.textStorage enumerateAttribute:NSParagraphStyleAttributeName inRange:pRange options:0
98
- usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
99
- NSMutableParagraphStyle *pStyle = [(NSParagraphStyle *)value mutableCopy];
100
- pStyle.textLists = @[];
101
- [_input->textView.textStorage addAttribute:NSParagraphStyleAttributeName value:pStyle range:range];
102
- }
103
- ];
127
+
128
+ [_input->textView.textStorage
129
+ enumerateAttribute:NSParagraphStyleAttributeName
130
+ inRange:pRange
131
+ options:0
132
+ usingBlock:^(id _Nullable value, NSRange range,
133
+ BOOL *_Nonnull stop) {
134
+ NSMutableParagraphStyle *pStyle =
135
+ [(NSParagraphStyle *)value mutableCopy];
136
+ pStyle.textLists = @[];
137
+ [_input->textView.textStorage
138
+ addAttribute:NSParagraphStyleAttributeName
139
+ value:pStyle
140
+ range:range];
141
+ }];
104
142
  }
105
-
143
+
106
144
  [_input->textView.textStorage endEditing];
107
-
145
+
108
146
  // also remove typing attributes
109
- NSMutableDictionary *typingAttrs = [_input->textView.typingAttributes mutableCopy];
110
- NSMutableParagraphStyle *pStyle = [typingAttrs[NSParagraphStyleAttributeName] mutableCopy];
147
+ NSMutableDictionary *typingAttrs =
148
+ [_input->textView.typingAttributes mutableCopy];
149
+ NSMutableParagraphStyle *pStyle =
150
+ [typingAttrs[NSParagraphStyleAttributeName] mutableCopy];
111
151
  pStyle.textLists = @[];
112
-
152
+
113
153
  typingAttrs[NSParagraphStyleAttributeName] = pStyle;
114
-
154
+
115
155
  _input->textView.typingAttributes = typingAttrs;
116
156
  }
117
157
 
@@ -120,14 +160,16 @@
120
160
  }
121
161
 
122
162
  - (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text {
123
- if([self detectStyle:_input->textView.selectedRange] && text.length == 0) {
163
+ if ([self detectStyle:_input->textView.selectedRange] && text.length == 0) {
124
164
  // backspace while the style is active
125
-
126
- NSRange paragraphRange = [_input->textView.textStorage.string paragraphRangeForRange:_input->textView.selectedRange];
127
-
128
- if(NSEqualRanges(_input->textView.selectedRange, NSMakeRange(0, 0))) {
165
+
166
+ NSRange paragraphRange = [_input->textView.textStorage.string
167
+ paragraphRangeForRange:_input->textView.selectedRange];
168
+
169
+ if (NSEqualRanges(_input->textView.selectedRange, NSMakeRange(0, 0))) {
129
170
  // a backspace on the very first input's line quote
130
- // it doesn't run textVieDidChange so we need to manually remove attributes
171
+ // it doesn't run textVieDidChange so we need to manually remove
172
+ // attributes
131
173
  [self removeAttributes:paragraphRange];
132
174
  return YES;
133
175
  }
@@ -135,92 +177,126 @@
135
177
  return NO;
136
178
  }
137
179
 
138
- - (BOOL)styleCondition:(id _Nullable)value :(NSRange)range {
180
+ - (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
139
181
  NSParagraphStyle *paragraph = (NSParagraphStyle *)value;
140
- return paragraph != nullptr && paragraph.textLists.count == 1 && [paragraph.textLists.firstObject.markerFormat isEqualToString:@"codeblock"];
182
+ return paragraph != nullptr && paragraph.textLists.count == 1 &&
183
+ [paragraph.textLists.firstObject.markerFormat
184
+ isEqualToString:@"codeblock"];
141
185
  }
142
186
 
143
187
  - (BOOL)detectStyle:(NSRange)range {
144
- if(range.length >= 1) {
145
- return [OccurenceUtils detect:NSParagraphStyleAttributeName withInput:_input inRange:range
146
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
147
- return [self styleCondition:value :range];
148
- }
149
- ];
188
+ if (range.length >= 1) {
189
+ return [OccurenceUtils detect:NSParagraphStyleAttributeName
190
+ withInput:_input
191
+ inRange:range
192
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
193
+ return [self styleCondition:value range:range];
194
+ }];
150
195
  } else {
151
- return [OccurenceUtils detect:NSParagraphStyleAttributeName withInput:_input atIndex:range.location checkPrevious:YES
152
- withCondition:^BOOL(id _Nullable value, NSRange range) {
153
- return [self styleCondition:value :range];
154
- }
155
- ];
196
+ return [OccurenceUtils detect:NSParagraphStyleAttributeName
197
+ withInput:_input
198
+ atIndex:range.location
199
+ checkPrevious:YES
200
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
201
+ return [self styleCondition:value range:range];
202
+ }];
156
203
  }
157
204
  }
158
205
 
159
206
  - (BOOL)anyOccurence:(NSRange)range {
160
- return [OccurenceUtils any:NSParagraphStyleAttributeName withInput:_input inRange:range
161
- withCondition:^BOOL(id _Nullable value, NSRange range) {
162
- return [self styleCondition:value :range];
163
- }
164
- ];
207
+ return [OccurenceUtils any:NSParagraphStyleAttributeName
208
+ withInput:_input
209
+ inRange:range
210
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
211
+ return [self styleCondition:value range:range];
212
+ }];
165
213
  }
166
214
 
167
215
  - (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
168
- return [OccurenceUtils all:NSParagraphStyleAttributeName withInput:_input inRange:range
169
- withCondition:^BOOL(id _Nullable value, NSRange range) {
170
- return [self styleCondition:value :range];
171
- }
172
- ];
216
+ return [OccurenceUtils all:NSParagraphStyleAttributeName
217
+ withInput:_input
218
+ inRange:range
219
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
220
+ return [self styleCondition:value range:range];
221
+ }];
173
222
  }
174
223
 
175
224
  - (void)manageCodeBlockFontAndColor {
176
- if([[_input->config codeBlockFgColor] isEqualToColor:[_input->config primaryColor]]) {
225
+ if ([[_input->config codeBlockFgColor]
226
+ isEqualToColor:[_input->config primaryColor]]) {
177
227
  return;
178
228
  }
179
229
 
180
- NSRange wholeRange = NSMakeRange(0, _input->textView.textStorage.string.length);
181
- NSArray *paragraphs = [ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView range:wholeRange];
182
-
183
- for(NSValue *pValue in paragraphs) {
230
+ NSRange wholeRange =
231
+ NSMakeRange(0, _input->textView.textStorage.string.length);
232
+ NSArray *paragraphs =
233
+ [ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView
234
+ range:wholeRange];
235
+
236
+ for (NSValue *pValue in paragraphs) {
184
237
  NSRange paragraphRange = [pValue rangeValue];
185
- NSArray *properRanges = [OccurenceUtils getRangesWithout:_stylesToExclude withInput:_input inRange:paragraphRange];
186
-
187
- for(NSValue *value in properRanges) {
238
+ NSArray *properRanges = [OccurenceUtils getRangesWithout:_stylesToExclude
239
+ withInput:_input
240
+ inRange:paragraphRange];
241
+
242
+ for (NSValue *value in properRanges) {
188
243
  NSRange currRange = [value rangeValue];
189
244
  BOOL selfDetected = [self detectStyle:currRange];
190
-
191
- [_input->textView.textStorage enumerateAttribute:NSFontAttributeName inRange:currRange options:0
192
- usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
193
- UIFont *currentFont = (UIFont *)value;
194
- UIFont *newFont = nullptr;
195
-
196
- BOOL isCodeFont = [[currentFont familyName] isEqualToString:[[_input->config monospacedFont] familyName]];
197
-
198
- if (isCodeFont && !selfDetected) {
199
- newFont = [[[_input->config primaryFont] withFontTraits:currentFont] setSize:currentFont.pointSize];
200
- } else if (!isCodeFont && selfDetected) {
201
- newFont = [[[_input->config monospacedFont] withFontTraits:currentFont] setSize:currentFont.pointSize];
202
- }
203
-
204
- if (newFont != nullptr) {
205
- [_input->textView.textStorage addAttribute:NSFontAttributeName value:newFont range:range];
206
- }
207
- }];
208
-
209
- [_input->textView.textStorage enumerateAttribute:NSForegroundColorAttributeName inRange:currRange options:0
210
- usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
211
- UIColor *newColor = nullptr;
212
- BOOL colorApplied = [(UIColor *)value isEqualToColor:[_input->config codeBlockFgColor]];
213
-
214
- if(colorApplied && !selfDetected) {
215
- newColor = [_input->config primaryColor];
216
- } else if(!colorApplied && selfDetected) {
217
- newColor = [_input->config codeBlockFgColor];
218
- }
219
-
220
- if(newColor != nullptr) {
221
- [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName value:newColor range:range];
222
- }
223
- }];
245
+
246
+ [_input->textView.textStorage
247
+ enumerateAttribute:NSFontAttributeName
248
+ inRange:currRange
249
+ options:0
250
+ usingBlock:^(id _Nullable value, NSRange range,
251
+ BOOL *_Nonnull stop) {
252
+ UIFont *currentFont = (UIFont *)value;
253
+ UIFont *newFont = nullptr;
254
+
255
+ BOOL isCodeFont = [[currentFont familyName]
256
+ isEqualToString:[[_input->config monospacedFont]
257
+ familyName]];
258
+
259
+ if (isCodeFont && !selfDetected) {
260
+ newFont = [[[_input->config primaryFont]
261
+ withFontTraits:currentFont]
262
+ setSize:currentFont.pointSize];
263
+ } else if (!isCodeFont && selfDetected) {
264
+ newFont = [[[_input->config monospacedFont]
265
+ withFontTraits:currentFont]
266
+ setSize:currentFont.pointSize];
267
+ }
268
+
269
+ if (newFont != nullptr) {
270
+ [_input->textView.textStorage
271
+ addAttribute:NSFontAttributeName
272
+ value:newFont
273
+ range:range];
274
+ }
275
+ }];
276
+
277
+ [_input->textView.textStorage
278
+ enumerateAttribute:NSForegroundColorAttributeName
279
+ inRange:currRange
280
+ options:0
281
+ usingBlock:^(id _Nullable value, NSRange range,
282
+ BOOL *_Nonnull stop) {
283
+ UIColor *newColor = nullptr;
284
+ BOOL colorApplied = [(UIColor *)value
285
+ isEqualToColor:[_input->config codeBlockFgColor]];
286
+
287
+ if (colorApplied && !selfDetected) {
288
+ newColor = [_input->config primaryColor];
289
+ } else if (!colorApplied && selfDetected) {
290
+ newColor = [_input->config codeBlockFgColor];
291
+ }
292
+
293
+ if (newColor != nullptr) {
294
+ [_input->textView.textStorage
295
+ addAttribute:NSForegroundColorAttributeName
296
+ value:newColor
297
+ range:range];
298
+ }
299
+ }];
224
300
  }
225
301
  }
226
302
  }