react-native-enriched 0.2.1 → 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 (156) hide show
  1. package/README.md +15 -12
  2. package/android/build.gradle +77 -72
  3. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +18 -0
  4. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +6 -0
  5. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +146 -0
  6. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +140 -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 +245 -116
  12. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewLayoutManager.kt +3 -1
  13. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +162 -53
  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 +20 -10
  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 +1 -2
  29. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +21 -8
  30. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +5 -4
  31. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +7 -5
  32. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +5 -4
  33. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +5 -4
  34. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +5 -4
  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 +29 -17
  39. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +5 -4
  40. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +5 -4
  41. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +7 -7
  42. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +11 -14
  43. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +15 -14
  44. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +167 -71
  45. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +5 -4
  46. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +5 -4
  47. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +8 -8
  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 +1 -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 +78 -21
  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 +86 -26
  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 +128 -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/react/renderer/components/RNEnrichedTextInputViewSpec/conversions.h +21 -1
  73. package/ios/EnrichedTextInputView.h +1 -1
  74. package/ios/EnrichedTextInputView.mm +381 -49
  75. package/ios/config/InputConfig.h +18 -0
  76. package/ios/config/InputConfig.mm +118 -8
  77. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +146 -0
  78. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +140 -0
  79. package/ios/generated/RNEnrichedTextInputViewSpec/Props.cpp +10 -0
  80. package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +194 -0
  81. package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +74 -0
  82. package/ios/inputParser/InputParser.mm +83 -10
  83. package/ios/{attachments → interfaces}/ImageAttachment.mm +3 -1
  84. package/ios/interfaces/LinkRegexConfig.h +19 -0
  85. package/ios/interfaces/LinkRegexConfig.mm +37 -0
  86. package/ios/{utils → interfaces}/MentionStyleProps.mm +2 -2
  87. package/ios/{utils → interfaces}/StyleHeaders.h +10 -0
  88. package/ios/{utils → interfaces}/StyleTypeEnum.h +3 -0
  89. package/ios/styles/BlockQuoteStyle.mm +5 -5
  90. package/ios/styles/BoldStyle.mm +21 -6
  91. package/ios/styles/CodeBlockStyle.mm +5 -5
  92. package/ios/styles/H4Style.mm +17 -0
  93. package/ios/styles/H5Style.mm +17 -0
  94. package/ios/styles/H6Style.mm +17 -0
  95. package/ios/styles/HeadingStyleBase.mm +27 -10
  96. package/ios/styles/ImageStyle.mm +5 -5
  97. package/ios/styles/InlineCodeStyle.mm +30 -19
  98. package/ios/styles/ItalicStyle.mm +5 -5
  99. package/ios/styles/LinkStyle.mm +98 -40
  100. package/ios/styles/MentionStyle.mm +4 -4
  101. package/ios/styles/OrderedListStyle.mm +5 -5
  102. package/ios/styles/StrikethroughStyle.mm +5 -5
  103. package/ios/styles/UnderlineStyle.mm +5 -5
  104. package/ios/styles/UnorderedListStyle.mm +5 -5
  105. package/ios/utils/ParagraphAttributesUtils.h +4 -0
  106. package/ios/utils/ParagraphAttributesUtils.mm +67 -0
  107. package/ios/utils/ParagraphsUtils.mm +4 -4
  108. package/lib/module/EnrichedTextInput.js +22 -1
  109. package/lib/module/EnrichedTextInput.js.map +1 -1
  110. package/lib/module/EnrichedTextInputNativeComponent.ts +138 -12
  111. package/lib/module/{normalizeHtmlStyle.js → utils/normalizeHtmlStyle.js} +12 -0
  112. package/lib/module/utils/normalizeHtmlStyle.js.map +1 -0
  113. package/lib/module/utils/regexParser.js +46 -0
  114. package/lib/module/utils/regexParser.js.map +1 -0
  115. package/lib/typescript/src/EnrichedTextInput.d.ts +23 -14
  116. package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
  117. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +123 -12
  118. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
  119. package/lib/typescript/src/index.d.ts +1 -1
  120. package/lib/typescript/src/index.d.ts.map +1 -1
  121. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts +4 -0
  122. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts.map +1 -0
  123. package/lib/typescript/src/utils/regexParser.d.ts +3 -0
  124. package/lib/typescript/src/utils/regexParser.d.ts.map +1 -0
  125. package/package.json +10 -6
  126. package/src/EnrichedTextInput.tsx +51 -13
  127. package/src/EnrichedTextInputNativeComponent.ts +138 -12
  128. package/src/index.tsx +2 -0
  129. package/src/{normalizeHtmlStyle.ts → utils/normalizeHtmlStyle.ts} +14 -2
  130. package/src/utils/regexParser.ts +56 -0
  131. package/lib/module/normalizeHtmlStyle.js.map +0 -1
  132. package/lib/typescript/src/normalizeHtmlStyle.d.ts +0 -4
  133. package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +0 -1
  134. /package/ios/{utils → extensions}/ColorExtension.h +0 -0
  135. /package/ios/{utils → extensions}/ColorExtension.mm +0 -0
  136. /package/ios/{utils → extensions}/FontExtension.h +0 -0
  137. /package/ios/{utils → extensions}/FontExtension.mm +0 -0
  138. /package/ios/{utils → extensions}/LayoutManagerExtension.h +0 -0
  139. /package/ios/{utils → extensions}/LayoutManagerExtension.mm +0 -0
  140. /package/ios/{utils → extensions}/StringExtension.h +0 -0
  141. /package/ios/{utils → extensions}/StringExtension.mm +0 -0
  142. /package/ios/{utils → interfaces}/BaseStyleProtocol.h +0 -0
  143. /package/ios/{attachments → interfaces}/ImageAttachment.h +0 -0
  144. /package/ios/{utils → interfaces}/ImageData.h +0 -0
  145. /package/ios/{utils → interfaces}/ImageData.mm +0 -0
  146. /package/ios/{utils → interfaces}/LinkData.h +0 -0
  147. /package/ios/{utils → interfaces}/LinkData.mm +0 -0
  148. /package/ios/{attachments → interfaces}/MediaAttachment.h +0 -0
  149. /package/ios/{attachments → interfaces}/MediaAttachment.mm +0 -0
  150. /package/ios/{utils → interfaces}/MentionParams.h +0 -0
  151. /package/ios/{utils → interfaces}/MentionParams.mm +0 -0
  152. /package/ios/{utils → interfaces}/MentionStyleProps.h +0 -0
  153. /package/ios/{utils → interfaces}/StylePair.h +0 -0
  154. /package/ios/{utils → interfaces}/StylePair.mm +0 -0
  155. /package/ios/{utils → interfaces}/TextDecorationLineEnum.h +0 -0
  156. /package/ios/{utils → interfaces}/TextDecorationLineEnum.mm +0 -0
@@ -186,7 +186,7 @@
186
186
  return NO;
187
187
  }
188
188
 
189
- - (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
189
+ - (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
190
190
  NSParagraphStyle *pStyle = (NSParagraphStyle *)value;
191
191
  return pStyle != nullptr && pStyle.headIndent == [self getHeadIndent] &&
192
192
  pStyle.firstLineHeadIndent == [self getHeadIndent] &&
@@ -199,7 +199,7 @@
199
199
  withInput:_input
200
200
  inRange:range
201
201
  withCondition:^BOOL(id _Nullable value, NSRange range) {
202
- return [self styleCondition:value:range];
202
+ return [self styleCondition:value range:range];
203
203
  }];
204
204
  } else {
205
205
  return [OccurenceUtils detect:NSParagraphStyleAttributeName
@@ -207,7 +207,7 @@
207
207
  atIndex:range.location
208
208
  checkPrevious:YES
209
209
  withCondition:^BOOL(id _Nullable value, NSRange range) {
210
- return [self styleCondition:value:range];
210
+ return [self styleCondition:value range:range];
211
211
  }];
212
212
  }
213
213
  }
@@ -217,7 +217,7 @@
217
217
  withInput:_input
218
218
  inRange:range
219
219
  withCondition:^BOOL(id _Nullable value, NSRange range) {
220
- return [self styleCondition:value:range];
220
+ return [self styleCondition:value range:range];
221
221
  }];
222
222
  }
223
223
 
@@ -226,7 +226,7 @@
226
226
  withInput:_input
227
227
  inRange:range
228
228
  withCondition:^BOOL(id _Nullable value, NSRange range) {
229
- return [self styleCondition:value:range];
229
+ return [self styleCondition:value range:range];
230
230
  }];
231
231
  }
232
232
 
@@ -104,6 +104,18 @@
104
104
  if (![_input->config h3Bold]) {
105
105
  return NO;
106
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
+ }
107
119
  }
108
120
 
109
121
  id<BaseStyleProtocol> headingStyle = _input->stylesDict[@(type)];
@@ -111,12 +123,15 @@
111
123
  : [headingStyle detectStyle:range];
112
124
  }
113
125
 
114
- - (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
126
+ - (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
115
127
  UIFont *font = (UIFont *)value;
116
128
  return font != nullptr && [font isBold] &&
117
129
  ![self boldHeadingConflictsInRange:range type:H1] &&
118
130
  ![self boldHeadingConflictsInRange:range type:H2] &&
119
- ![self boldHeadingConflictsInRange:range type:H3];
131
+ ![self boldHeadingConflictsInRange:range type:H3] &&
132
+ ![self boldHeadingConflictsInRange:range type:H4] &&
133
+ ![self boldHeadingConflictsInRange:range type:H5] &&
134
+ ![self boldHeadingConflictsInRange:range type:H6];
120
135
  }
121
136
 
122
137
  - (BOOL)detectStyle:(NSRange)range {
@@ -125,7 +140,7 @@
125
140
  withInput:_input
126
141
  inRange:range
127
142
  withCondition:^BOOL(id _Nullable value, NSRange range) {
128
- return [self styleCondition:value:range];
143
+ return [self styleCondition:value range:range];
129
144
  }];
130
145
  } else {
131
146
  return [OccurenceUtils detect:NSFontAttributeName
@@ -133,7 +148,7 @@
133
148
  atIndex:range.location
134
149
  checkPrevious:NO
135
150
  withCondition:^BOOL(id _Nullable value, NSRange range) {
136
- return [self styleCondition:value:range];
151
+ return [self styleCondition:value range:range];
137
152
  }];
138
153
  }
139
154
  }
@@ -143,7 +158,7 @@
143
158
  withInput:_input
144
159
  inRange:range
145
160
  withCondition:^BOOL(id _Nullable value, NSRange range) {
146
- return [self styleCondition:value:range];
161
+ return [self styleCondition:value range:range];
147
162
  }];
148
163
  }
149
164
 
@@ -152,7 +167,7 @@
152
167
  withInput:_input
153
168
  inRange:range
154
169
  withCondition:^BOOL(id _Nullable value, NSRange range) {
155
- return [self styleCondition:value:range];
170
+ return [self styleCondition:value range:range];
156
171
  }];
157
172
  }
158
173
 
@@ -177,7 +177,7 @@
177
177
  return NO;
178
178
  }
179
179
 
180
- - (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
180
+ - (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
181
181
  NSParagraphStyle *paragraph = (NSParagraphStyle *)value;
182
182
  return paragraph != nullptr && paragraph.textLists.count == 1 &&
183
183
  [paragraph.textLists.firstObject.markerFormat
@@ -190,7 +190,7 @@
190
190
  withInput:_input
191
191
  inRange:range
192
192
  withCondition:^BOOL(id _Nullable value, NSRange range) {
193
- return [self styleCondition:value:range];
193
+ return [self styleCondition:value range:range];
194
194
  }];
195
195
  } else {
196
196
  return [OccurenceUtils detect:NSParagraphStyleAttributeName
@@ -198,7 +198,7 @@
198
198
  atIndex:range.location
199
199
  checkPrevious:YES
200
200
  withCondition:^BOOL(id _Nullable value, NSRange range) {
201
- return [self styleCondition:value:range];
201
+ return [self styleCondition:value range:range];
202
202
  }];
203
203
  }
204
204
  }
@@ -208,7 +208,7 @@
208
208
  withInput:_input
209
209
  inRange:range
210
210
  withCondition:^BOOL(id _Nullable value, NSRange range) {
211
- return [self styleCondition:value:range];
211
+ return [self styleCondition:value range:range];
212
212
  }];
213
213
  }
214
214
 
@@ -217,7 +217,7 @@
217
217
  withInput:_input
218
218
  inRange:range
219
219
  withCondition:^BOOL(id _Nullable value, NSRange range) {
220
- return [self styleCondition:value:range];
220
+ return [self styleCondition:value range:range];
221
221
  }];
222
222
  }
223
223
 
@@ -0,0 +1,17 @@
1
+ #import "EnrichedTextInputView.h"
2
+ #import "StyleHeaders.h"
3
+
4
+ @implementation H4Style
5
+ + (StyleType)getStyleType {
6
+ return H4;
7
+ }
8
+ + (BOOL)isParagraphStyle {
9
+ return YES;
10
+ }
11
+ - (CGFloat)getHeadingFontSize {
12
+ return [((EnrichedTextInputView *)input)->config h4FontSize];
13
+ }
14
+ - (BOOL)isHeadingBold {
15
+ return [((EnrichedTextInputView *)input)->config h4Bold];
16
+ }
17
+ @end
@@ -0,0 +1,17 @@
1
+ #import "EnrichedTextInputView.h"
2
+ #import "StyleHeaders.h"
3
+
4
+ @implementation H5Style
5
+ + (StyleType)getStyleType {
6
+ return H5;
7
+ }
8
+ + (BOOL)isParagraphStyle {
9
+ return YES;
10
+ }
11
+ - (CGFloat)getHeadingFontSize {
12
+ return [((EnrichedTextInputView *)input)->config h5FontSize];
13
+ }
14
+ - (BOOL)isHeadingBold {
15
+ return [((EnrichedTextInputView *)input)->config h5Bold];
16
+ }
17
+ @end
@@ -0,0 +1,17 @@
1
+ #import "EnrichedTextInputView.h"
2
+ #import "StyleHeaders.h"
3
+
4
+ @implementation H6Style
5
+ + (StyleType)getStyleType {
6
+ return H6;
7
+ }
8
+ + (BOOL)isParagraphStyle {
9
+ return YES;
10
+ }
11
+ - (CGFloat)getHeadingFontSize {
12
+ return [((EnrichedTextInputView *)input)->config h6FontSize];
13
+ }
14
+ - (BOOL)isHeadingBold {
15
+ return [((EnrichedTextInputView *)input)->config h6Bold];
16
+ }
17
+ @end
@@ -6,7 +6,7 @@
6
6
 
7
7
  @implementation HeadingStyleBase
8
8
 
9
- // mock values since H1/2/3Style classes anyway are used
9
+ // mock values since H1/2/3/4/5/6Style classes anyway are used
10
10
  + (StyleType)getStyleType {
11
11
  return None;
12
12
  }
@@ -16,6 +16,9 @@
16
16
  - (BOOL)isHeadingBold {
17
17
  return false;
18
18
  }
19
+ + (BOOL)isParagraphStyle {
20
+ return true;
21
+ }
19
22
 
20
23
  - (EnrichedTextInputView *)typedInput {
21
24
  return (EnrichedTextInputView *)input;
@@ -24,6 +27,7 @@
24
27
  - (instancetype)initWithInput:(id)input {
25
28
  self = [super init];
26
29
  self->input = input;
30
+ _lastAppliedFontSize = 0.0;
27
31
  return self;
28
32
  }
29
33
 
@@ -37,6 +41,7 @@
37
41
  } else {
38
42
  isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
39
43
  }
44
+ _lastAppliedFontSize = [self getHeadingFontSize];
40
45
  }
41
46
 
42
47
  // the range will already be the proper full paragraph/s range
@@ -98,9 +103,9 @@
98
103
  options:0
99
104
  usingBlock:^(id _Nullable value, NSRange range,
100
105
  BOOL *_Nonnull stop) {
101
- if ([self styleCondition:value:range]) {
106
+ if ([self styleCondition:value range:range]) {
102
107
  UIFont *newFont = [(UIFont *)value
103
- setSize:[[[self typedInput]->config primaryFontSize]
108
+ setSize:[[[self typedInput]->config scaledPrimaryFontSize]
104
109
  floatValue]];
105
110
  if ([self isHeadingBold]) {
106
111
  newFont = [newFont removeBold];
@@ -121,7 +126,7 @@
121
126
  NSMutableDictionary *newTypingAttrs =
122
127
  [[self typedInput]->textView.typingAttributes mutableCopy];
123
128
  UIFont *newFont = [currentFontAttr
124
- setSize:[[[self typedInput]->config primaryFontSize] floatValue]];
129
+ setSize:[[[self typedInput]->config scaledPrimaryFontSize] floatValue]];
125
130
  if ([self isHeadingBold]) {
126
131
  newFont = [newFont removeBold];
127
132
  }
@@ -137,9 +142,20 @@
137
142
  [self removeAttributes:[self typedInput]->textView.selectedRange];
138
143
  }
139
144
 
140
- - (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
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
+ - (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
141
149
  UIFont *font = (UIFont *)value;
142
- return font != nullptr && font.pointSize == [self getHeadingFontSize];
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];
143
159
  }
144
160
 
145
161
  - (BOOL)detectStyle:(NSRange)range {
@@ -148,7 +164,7 @@
148
164
  withInput:[self typedInput]
149
165
  inRange:range
150
166
  withCondition:^BOOL(id _Nullable value, NSRange range) {
151
- return [self styleCondition:value:range];
167
+ return [self styleCondition:value range:range];
152
168
  }];
153
169
  } else {
154
170
  return [OccurenceUtils detect:NSFontAttributeName
@@ -156,7 +172,7 @@
156
172
  atIndex:range.location
157
173
  checkPrevious:YES
158
174
  withCondition:^BOOL(id _Nullable value, NSRange range) {
159
- return [self styleCondition:value:range];
175
+ return [self styleCondition:value range:range];
160
176
  }];
161
177
  }
162
178
  }
@@ -166,7 +182,7 @@
166
182
  withInput:[self typedInput]
167
183
  inRange:range
168
184
  withCondition:^BOOL(id _Nullable value, NSRange range) {
169
- return [self styleCondition:value:range];
185
+ return [self styleCondition:value range:range];
170
186
  }];
171
187
  }
172
188
 
@@ -175,7 +191,7 @@
175
191
  withInput:[self typedInput]
176
192
  inRange:range
177
193
  withCondition:^BOOL(id _Nullable value, NSRange range) {
178
- return [self styleCondition:value:range];
194
+ return [self styleCondition:value range:range];
179
195
  }];
180
196
  }
181
197
 
@@ -216,6 +232,7 @@
216
232
  [self addAttributes:paragraphRange withTypingAttr:NO];
217
233
  }
218
234
  }
235
+ _lastAppliedFontSize = [self getHeadingFontSize];
219
236
  }
220
237
 
221
238
  @end
@@ -54,7 +54,7 @@ static NSString *const ImageAttributeName = @"ImageAttributeName";
54
54
  _input->textView.typingAttributes = currentAttributes;
55
55
  }
56
56
 
57
- - (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
57
+ - (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
58
58
  return [value isKindOfClass:[ImageData class]];
59
59
  }
60
60
 
@@ -63,7 +63,7 @@ static NSString *const ImageAttributeName = @"ImageAttributeName";
63
63
  withInput:_input
64
64
  inRange:range
65
65
  withCondition:^BOOL(id _Nullable value, NSRange range) {
66
- return [self styleCondition:value:range];
66
+ return [self styleCondition:value range:range];
67
67
  }];
68
68
  }
69
69
 
@@ -73,7 +73,7 @@ static NSString *const ImageAttributeName = @"ImageAttributeName";
73
73
  withInput:_input
74
74
  inRange:range
75
75
  withCondition:^BOOL(id _Nullable value, NSRange range) {
76
- return [self styleCondition:value:range];
76
+ return [self styleCondition:value range:range];
77
77
  }];
78
78
  } else {
79
79
  return [OccurenceUtils detect:ImageAttributeName
@@ -81,7 +81,7 @@ static NSString *const ImageAttributeName = @"ImageAttributeName";
81
81
  atIndex:range.location
82
82
  checkPrevious:YES
83
83
  withCondition:^BOOL(id _Nullable value, NSRange range) {
84
- return [self styleCondition:value:range];
84
+ return [self styleCondition:value range:range];
85
85
  }];
86
86
  }
87
87
  }
@@ -91,7 +91,7 @@ static NSString *const ImageAttributeName = @"ImageAttributeName";
91
91
  withInput:_input
92
92
  inRange:range
93
93
  withCondition:^BOOL(id _Nullable value, NSRange range) {
94
- return [self styleCondition:value:range];
94
+ return [self styleCondition:value range:range];
95
95
  }];
96
96
  }
97
97
 
@@ -151,27 +151,38 @@
151
151
 
152
152
  // making sure no newlines get inline code style, it looks bad
153
153
  - (void)handleNewlines {
154
- for (int i = 0; i < _input->textView.textStorage.string.length; i++) {
155
- if ([[NSCharacterSet newlineCharacterSet]
156
- characterIsMember:[_input->textView.textStorage.string
157
- characterAtIndex:i]]) {
158
- NSRange mockRange = NSMakeRange(0, 0);
159
- // can't use detect style because it intentionally doesn't take newlines
160
- // into consideration
161
- UIColor *bgColor =
162
- [_input->textView.textStorage attribute:NSBackgroundColorAttributeName
163
- atIndex:i
164
- effectiveRange:&mockRange];
165
- if ([self styleCondition:bgColor:NSMakeRange(i, 1)]) {
166
- [self removeAttributes:NSMakeRange(i, 1)];
167
- }
154
+ NSTextStorage *storage = _input->textView.textStorage;
155
+ NSString *string = storage.string;
156
+ NSUInteger length = string.length;
157
+
158
+ if (length == 0)
159
+ return;
160
+
161
+ CFStringInlineBuffer buffer;
162
+ CFStringInitInlineBuffer((CFStringRef)string, &buffer,
163
+ CFRangeMake(0, length));
164
+
165
+ for (NSUInteger index = 0; index < length; index++) {
166
+ unichar ch = CFStringGetCharacterFromInlineBuffer(&buffer, index);
167
+ // check new lines only
168
+ if (![[NSCharacterSet newlineCharacterSet] characterIsMember:ch])
169
+ continue;
170
+
171
+ NSRange newlineRange = NSMakeRange(index, 1);
172
+
173
+ UIColor *bgColor = [storage attribute:NSBackgroundColorAttributeName
174
+ atIndex:index
175
+ effectiveRange:nil];
176
+
177
+ if (bgColor != nil && [self styleCondition:bgColor range:newlineRange]) {
178
+ [self removeAttributes:newlineRange];
168
179
  }
169
180
  }
170
181
  }
171
182
 
172
183
  // emojis don't retain monospace font attribute so we check for the background
173
184
  // color if there is no mention
174
- - (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
185
+ - (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
175
186
  UIColor *bgColor = (UIColor *)value;
176
187
  MentionStyle *mStyle = _input->stylesDict[@([MentionStyle getStyleType])];
177
188
  return bgColor != nullptr && mStyle != nullptr && ![mStyle detectStyle:range];
@@ -194,7 +205,7 @@
194
205
  withInput:_input
195
206
  inRange:currentRange
196
207
  withCondition:^BOOL(id _Nullable value, NSRange range) {
197
- return [self styleCondition:value:range];
208
+ return [self styleCondition:value range:range];
198
209
  }];
199
210
  detected = detected && currentDetected;
200
211
  }
@@ -206,7 +217,7 @@
206
217
  atIndex:range.location
207
218
  checkPrevious:NO
208
219
  withCondition:^BOOL(id _Nullable value, NSRange range) {
209
- return [self styleCondition:value:range];
220
+ return [self styleCondition:value range:range];
210
221
  }];
211
222
  }
212
223
  }
@@ -216,7 +227,7 @@
216
227
  withInput:_input
217
228
  inRange:range
218
229
  withCondition:^BOOL(id _Nullable value, NSRange range) {
219
- return [self styleCondition:value:range];
230
+ return [self styleCondition:value range:range];
220
231
  }];
221
232
  }
222
233
 
@@ -225,7 +236,7 @@
225
236
  withInput:_input
226
237
  inRange:range
227
238
  withCondition:^BOOL(id _Nullable value, NSRange range) {
228
- return [self styleCondition:value:range];
239
+ return [self styleCondition:value range:range];
229
240
  }];
230
241
  }
231
242
 
@@ -91,7 +91,7 @@
91
91
  }
92
92
  }
93
93
 
94
- - (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
94
+ - (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
95
95
  UIFont *font = (UIFont *)value;
96
96
  return font != nullptr && [font isItalic];
97
97
  }
@@ -102,7 +102,7 @@
102
102
  withInput:_input
103
103
  inRange:range
104
104
  withCondition:^BOOL(id _Nullable value, NSRange range) {
105
- return [self styleCondition:value:range];
105
+ return [self styleCondition:value range:range];
106
106
  }];
107
107
  } else {
108
108
  return [OccurenceUtils detect:NSFontAttributeName
@@ -110,7 +110,7 @@
110
110
  atIndex:range.location
111
111
  checkPrevious:NO
112
112
  withCondition:^BOOL(id _Nullable value, NSRange range) {
113
- return [self styleCondition:value:range];
113
+ return [self styleCondition:value range:range];
114
114
  }];
115
115
  }
116
116
  }
@@ -120,7 +120,7 @@
120
120
  withInput:_input
121
121
  inRange:range
122
122
  withCondition:^BOOL(id _Nullable value, NSRange range) {
123
- return [self styleCondition:value:range];
123
+ return [self styleCondition:value range:range];
124
124
  }];
125
125
  }
126
126
 
@@ -129,7 +129,7 @@
129
129
  withInput:_input
130
130
  inRange:range
131
131
  withCondition:^BOOL(id _Nullable value, NSRange range) {
132
- return [self styleCondition:value:range];
132
+ return [self styleCondition:value range:range];
133
133
  }];
134
134
  }
135
135