react-native-enriched 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +1 -5
  2. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +3 -0
  3. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +1 -0
  4. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
  5. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
  6. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +92 -0
  7. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +6 -0
  8. package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +1 -1
  9. package/android/src/main/java/com/swmansion/enriched/events/OnRequestHtmlResultEvent.kt +33 -0
  10. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +6 -0
  11. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +6 -0
  12. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +6 -0
  13. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +6 -0
  14. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +6 -0
  15. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +6 -0
  16. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +5 -0
  17. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +6 -0
  18. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +5 -0
  19. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +6 -0
  20. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +6 -0
  21. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +6 -0
  22. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +9 -3
  23. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +5 -0
  24. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +5 -0
  25. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +6 -0
  26. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +4 -0
  27. package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +78 -0
  28. package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +80 -4
  29. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +8 -0
  30. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +6 -6
  31. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +6 -6
  32. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +19 -19
  33. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +40 -51
  34. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +13 -15
  35. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +23 -21
  36. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +35 -36
  37. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +4 -4
  38. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +13 -14
  39. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/conversions.h +12 -13
  40. package/ios/EnrichedTextInputView.h +25 -13
  41. package/ios/EnrichedTextInputView.mm +872 -581
  42. package/ios/attachments/ImageAttachment.h +10 -0
  43. package/ios/attachments/ImageAttachment.mm +34 -0
  44. package/ios/attachments/MediaAttachment.h +23 -0
  45. package/ios/attachments/MediaAttachment.mm +31 -0
  46. package/ios/config/InputConfig.h +6 -6
  47. package/ios/config/InputConfig.mm +39 -33
  48. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
  49. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
  50. package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +21 -0
  51. package/ios/inputParser/InputParser.h +5 -5
  52. package/ios/inputParser/InputParser.mm +789 -378
  53. package/ios/inputTextView/InputTextView.h +1 -1
  54. package/ios/inputTextView/InputTextView.mm +100 -59
  55. package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +11 -9
  56. package/ios/internals/EnrichedTextInputViewShadowNode.h +28 -25
  57. package/ios/internals/EnrichedTextInputViewShadowNode.mm +45 -40
  58. package/ios/internals/EnrichedTextInputViewState.h +3 -1
  59. package/ios/styles/BlockQuoteStyle.mm +189 -118
  60. package/ios/styles/BoldStyle.mm +95 -63
  61. package/ios/styles/CodeBlockStyle.mm +204 -128
  62. package/ios/styles/H1Style.mm +10 -4
  63. package/ios/styles/H2Style.mm +10 -4
  64. package/ios/styles/H3Style.mm +10 -4
  65. package/ios/styles/HeadingStyleBase.mm +129 -84
  66. package/ios/styles/ImageStyle.mm +75 -73
  67. package/ios/styles/InlineCodeStyle.mm +148 -85
  68. package/ios/styles/ItalicStyle.mm +76 -52
  69. package/ios/styles/LinkStyle.mm +348 -227
  70. package/ios/styles/MentionStyle.mm +363 -246
  71. package/ios/styles/OrderedListStyle.mm +171 -106
  72. package/ios/styles/StrikethroughStyle.mm +52 -35
  73. package/ios/styles/UnderlineStyle.mm +68 -46
  74. package/ios/styles/UnorderedListStyle.mm +169 -106
  75. package/ios/utils/BaseStyleProtocol.h +2 -2
  76. package/ios/utils/ColorExtension.mm +7 -5
  77. package/ios/utils/FontExtension.mm +42 -27
  78. package/ios/utils/LayoutManagerExtension.h +1 -1
  79. package/ios/utils/LayoutManagerExtension.mm +280 -170
  80. package/ios/utils/MentionParams.h +0 -1
  81. package/ios/utils/MentionStyleProps.h +1 -1
  82. package/ios/utils/MentionStyleProps.mm +27 -20
  83. package/ios/utils/OccurenceUtils.h +42 -42
  84. package/ios/utils/OccurenceUtils.mm +142 -119
  85. package/ios/utils/ParagraphAttributesUtils.h +6 -2
  86. package/ios/utils/ParagraphAttributesUtils.mm +115 -71
  87. package/ios/utils/ParagraphsUtils.h +2 -1
  88. package/ios/utils/ParagraphsUtils.mm +40 -26
  89. package/ios/utils/StringExtension.h +1 -1
  90. package/ios/utils/StringExtension.mm +19 -16
  91. package/ios/utils/StyleHeaders.h +27 -15
  92. package/ios/utils/TextInsertionUtils.h +13 -2
  93. package/ios/utils/TextInsertionUtils.mm +38 -20
  94. package/ios/utils/WordsUtils.h +2 -1
  95. package/ios/utils/WordsUtils.mm +32 -22
  96. package/ios/utils/ZeroWidthSpaceUtils.h +3 -1
  97. package/ios/utils/ZeroWidthSpaceUtils.mm +145 -79
  98. package/lib/module/EnrichedTextInput.js +39 -1
  99. package/lib/module/EnrichedTextInput.js.map +1 -1
  100. package/lib/module/EnrichedTextInputNativeComponent.ts +11 -0
  101. package/lib/typescript/src/EnrichedTextInput.d.ts +1 -0
  102. package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
  103. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +6 -0
  104. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
  105. package/package.json +8 -1
  106. package/src/EnrichedTextInput.tsx +45 -0
  107. package/src/EnrichedTextInputNativeComponent.ts +11 -0
@@ -1,24 +1,28 @@
1
- #import "StyleHeaders.h"
1
+ #import "ColorExtension.h"
2
2
  #import "EnrichedTextInputView.h"
3
3
  #import "OccurenceUtils.h"
4
+ #import "StyleHeaders.h"
4
5
  #import "TextInsertionUtils.h"
5
- #import "WordsUtils.h"
6
6
  #import "UIView+React.h"
7
- #import "ColorExtension.h"
7
+ #import "WordsUtils.h"
8
8
 
9
9
  // custom NSAttributedStringKey to differentiate from links
10
10
  static NSString *const MentionAttributeName = @"MentionAttributeName";
11
11
 
12
12
  @implementation MentionStyle {
13
- EnrichedTextInputView*_input;
13
+ EnrichedTextInputView *_input;
14
14
  NSValue *_activeMentionRange;
15
15
  NSString *_activeMentionIndicator;
16
16
  BOOL _blockMentionEditing;
17
17
  }
18
18
 
19
- + (StyleType)getStyleType { return Mention; }
19
+ + (StyleType)getStyleType {
20
+ return Mention;
21
+ }
20
22
 
21
- + (BOOL)isParagraphStyle { return NO; }
23
+ + (BOOL)isParagraphStyle {
24
+ return NO;
25
+ }
22
26
 
23
27
  - (instancetype)initWithInput:(id)input {
24
28
  self = [super init];
@@ -33,7 +37,7 @@ static NSString *const MentionAttributeName = @"MentionAttributeName";
33
37
  // no-op for mentions
34
38
  }
35
39
 
36
- - (void)addAttributes:(NSRange)range {
40
+ - (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
37
41
  // no-op for mentions
38
42
  }
39
43
 
@@ -47,28 +51,43 @@ static NSString *const MentionAttributeName = @"MentionAttributeName";
47
51
 
48
52
  NSArray<StylePair *> *mentions = [self findAllOccurences:range];
49
53
  [_input->textView.textStorage beginEditing];
50
- for(StylePair *pair in mentions) {
51
- NSRange mentionRange = [self getFullMentionRangeAt:[pair.rangeValue rangeValue].location];
52
- [_input->textView.textStorage removeAttribute:MentionAttributeName range:mentionRange];
53
- [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName value:[_input->config primaryColor] range:mentionRange];
54
- [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName value:[_input->config primaryColor] range:mentionRange];
55
- [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName value:[_input->config primaryColor] range:mentionRange];
56
- [_input->textView.textStorage removeAttribute:NSBackgroundColorAttributeName range:mentionRange];
57
-
58
- if([self stylePropsWithParams:pair.styleValue].decorationLine == DecorationUnderline) {
59
- [_input->textView.textStorage removeAttribute:NSUnderlineStyleAttributeName range:mentionRange];
54
+ for (StylePair *pair in mentions) {
55
+ NSRange mentionRange =
56
+ [self getFullMentionRangeAt:[pair.rangeValue rangeValue].location];
57
+ [_input->textView.textStorage removeAttribute:MentionAttributeName
58
+ range:mentionRange];
59
+ [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName
60
+ value:[_input->config primaryColor]
61
+ range:mentionRange];
62
+ [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName
63
+ value:[_input->config primaryColor]
64
+ range:mentionRange];
65
+ [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName
66
+ value:[_input->config primaryColor]
67
+ range:mentionRange];
68
+ [_input->textView.textStorage removeAttribute:NSBackgroundColorAttributeName
69
+ range:mentionRange];
70
+
71
+ if ([self stylePropsWithParams:pair.styleValue].decorationLine ==
72
+ DecorationUnderline) {
73
+ [_input->textView.textStorage
74
+ removeAttribute:NSUnderlineStyleAttributeName
75
+ range:mentionRange];
60
76
  someMentionHadUnderline = YES;
61
77
  }
62
78
  }
63
79
  [_input->textView.textStorage endEditing];
64
-
80
+
65
81
  // remove typing attributes as well
66
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
67
- newTypingAttrs[NSForegroundColorAttributeName] = [_input->config primaryColor];
82
+ NSMutableDictionary *newTypingAttrs =
83
+ [_input->textView.typingAttributes mutableCopy];
84
+ newTypingAttrs[NSForegroundColorAttributeName] =
85
+ [_input->config primaryColor];
68
86
  newTypingAttrs[NSUnderlineColorAttributeName] = [_input->config primaryColor];
69
- newTypingAttrs[NSStrikethroughColorAttributeName] = [_input->config primaryColor];
87
+ newTypingAttrs[NSStrikethroughColorAttributeName] =
88
+ [_input->config primaryColor];
70
89
  [newTypingAttrs removeObjectForKey:NSBackgroundColorAttributeName];
71
- if(someMentionHadUnderline) {
90
+ if (someMentionHadUnderline) {
72
91
  [newTypingAttrs removeObjectForKey:NSUnderlineStyleAttributeName];
73
92
  }
74
93
  _input->textView.typingAttributes = newTypingAttrs;
@@ -76,165 +95,208 @@ static NSString *const MentionAttributeName = @"MentionAttributeName";
76
95
 
77
96
  // used for conflicts, we have to remove the whole mention
78
97
  - (void)removeTypingAttributes {
79
- NSRange mentionRange = [self getFullMentionRangeAt:_input->textView.selectedRange.location];
98
+ NSRange mentionRange =
99
+ [self getFullMentionRangeAt:_input->textView.selectedRange.location];
80
100
  [_input->textView.textStorage beginEditing];
81
- [_input->textView.textStorage removeAttribute:MentionAttributeName range:mentionRange];
82
- [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName value:[_input->config primaryColor] range:mentionRange];
83
- [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName value:[_input->config primaryColor] range:mentionRange];
84
- [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName value:[_input->config primaryColor] range:mentionRange];
85
- [_input->textView.textStorage removeAttribute:NSBackgroundColorAttributeName range:mentionRange];
86
-
101
+ [_input->textView.textStorage removeAttribute:MentionAttributeName
102
+ range:mentionRange];
103
+ [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName
104
+ value:[_input->config primaryColor]
105
+ range:mentionRange];
106
+ [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName
107
+ value:[_input->config primaryColor]
108
+ range:mentionRange];
109
+ [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName
110
+ value:[_input->config primaryColor]
111
+ range:mentionRange];
112
+ [_input->textView.textStorage removeAttribute:NSBackgroundColorAttributeName
113
+ range:mentionRange];
114
+
87
115
  MentionParams *params = [self getMentionParamsAt:mentionRange.location];
88
- if([self stylePropsWithParams:params].decorationLine == DecorationUnderline) {
89
- [_input->textView.textStorage removeAttribute:NSUnderlineStyleAttributeName range:mentionRange];
116
+ if ([self stylePropsWithParams:params].decorationLine ==
117
+ DecorationUnderline) {
118
+ [_input->textView.textStorage removeAttribute:NSUnderlineStyleAttributeName
119
+ range:mentionRange];
90
120
  }
91
121
  [_input->textView.textStorage endEditing];
92
-
122
+
93
123
  // remove typing attributes as well
94
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
95
- newTypingAttrs[NSForegroundColorAttributeName] = [_input->config primaryColor];
124
+ NSMutableDictionary *newTypingAttrs =
125
+ [_input->textView.typingAttributes mutableCopy];
126
+ newTypingAttrs[NSForegroundColorAttributeName] =
127
+ [_input->config primaryColor];
96
128
  newTypingAttrs[NSUnderlineColorAttributeName] = [_input->config primaryColor];
97
- newTypingAttrs[NSStrikethroughColorAttributeName] = [_input->config primaryColor];
129
+ newTypingAttrs[NSStrikethroughColorAttributeName] =
130
+ [_input->config primaryColor];
98
131
  [newTypingAttrs removeObjectForKey:NSBackgroundColorAttributeName];
99
- if([self stylePropsWithParams:params].decorationLine == DecorationUnderline) {
132
+ if ([self stylePropsWithParams:params].decorationLine ==
133
+ DecorationUnderline) {
100
134
  [newTypingAttrs removeObjectForKey:NSUnderlineStyleAttributeName];
101
135
  }
102
136
  _input->textView.typingAttributes = newTypingAttrs;
103
137
  }
104
138
 
105
- - (BOOL)styleCondition:(id _Nullable)value :(NSRange)range {
139
+ - (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
106
140
  MentionParams *params = (MentionParams *)value;
107
141
  return params != nullptr;
108
142
  }
109
143
 
110
144
  - (BOOL)detectStyle:(NSRange)range {
111
- if(range.length >= 1) {
112
- return [OccurenceUtils detect:MentionAttributeName withInput:_input inRange:range
113
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
114
- return [self styleCondition:value :range];
115
- }
116
- ];
145
+ if (range.length >= 1) {
146
+ return [OccurenceUtils detect:MentionAttributeName
147
+ withInput:_input
148
+ inRange:range
149
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
150
+ return [self styleCondition:value:range];
151
+ }];
117
152
  } else {
118
153
  return [self getMentionParamsAt:range.location] != nullptr;
119
154
  }
120
155
  }
121
156
 
122
157
  - (BOOL)anyOccurence:(NSRange)range {
123
- return [OccurenceUtils any:MentionAttributeName withInput:_input inRange:range
124
- withCondition:^BOOL(id _Nullable value, NSRange range) {
125
- return [self styleCondition:value :range];
126
- }
127
- ];
158
+ return [OccurenceUtils any:MentionAttributeName
159
+ withInput:_input
160
+ inRange:range
161
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
162
+ return [self styleCondition:value:range];
163
+ }];
128
164
  }
129
165
 
130
166
  - (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
131
- return [OccurenceUtils all:MentionAttributeName withInput:_input inRange:range
132
- withCondition:^BOOL(id _Nullable value, NSRange range) {
133
- return [self styleCondition:value :range];
134
- }
135
- ];
167
+ return [OccurenceUtils all:MentionAttributeName
168
+ withInput:_input
169
+ inRange:range
170
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
171
+ return [self styleCondition:value:range];
172
+ }];
136
173
  }
137
174
 
138
175
  // MARK: - Public non-standard methods
139
176
 
140
- - (void)addMention:(NSString *)indicator text:(NSString *)text attributes:(NSString *)attributes {
141
- if(_activeMentionRange == nullptr) {
177
+ - (void)addMention:(NSString *)indicator
178
+ text:(NSString *)text
179
+ attributes:(NSString *)attributes {
180
+ if (_activeMentionRange == nullptr) {
142
181
  return;
143
182
  }
144
-
145
- // we block callbacks resulting from manageMentionEditing while we tamper with them here
183
+
184
+ // we block callbacks resulting from manageMentionEditing while we tamper with
185
+ // them here
146
186
  _blockMentionEditing = YES;
147
-
187
+
148
188
  MentionParams *params = [[MentionParams alloc] init];
149
189
  params.text = text;
150
190
  params.indicator = indicator;
151
191
  params.attributes = attributes;
152
-
153
- MentionStyleProps *styleProps = [_input->config mentionStylePropsForIndicator:indicator];
154
-
192
+
193
+ MentionStyleProps *styleProps =
194
+ [_input->config mentionStylePropsForIndicator:indicator];
195
+
155
196
  NSMutableDictionary *newAttrs = [@{
156
- MentionAttributeName: params,
157
- NSForegroundColorAttributeName: styleProps.color,
158
- NSUnderlineColorAttributeName: styleProps.color,
159
- NSStrikethroughColorAttributeName: styleProps.color,
160
- NSBackgroundColorAttributeName: [styleProps.backgroundColor colorWithAlphaIfNotTransparent:0.4],
197
+ MentionAttributeName : params,
198
+ NSForegroundColorAttributeName : styleProps.color,
199
+ NSUnderlineColorAttributeName : styleProps.color,
200
+ NSStrikethroughColorAttributeName : styleProps.color,
201
+ NSBackgroundColorAttributeName :
202
+ [styleProps.backgroundColor colorWithAlphaIfNotTransparent:0.4],
161
203
  } mutableCopy];
162
-
163
- if(styleProps.decorationLine == DecorationUnderline) {
204
+
205
+ if (styleProps.decorationLine == DecorationUnderline) {
164
206
  newAttrs[NSUnderlineStyleAttributeName] = @(NSUnderlineStyleSingle);
165
207
  }
166
-
208
+
167
209
  // add a single space after the mention
168
210
  NSString *newText = [NSString stringWithFormat:@"%@ ", text];
169
211
  NSRange rangeToBeReplaced = [_activeMentionRange rangeValue];
170
- [TextInsertionUtils replaceText:newText at:rangeToBeReplaced additionalAttributes:nullptr input:_input withSelection:YES];
171
-
212
+ [TextInsertionUtils replaceText:newText
213
+ at:rangeToBeReplaced
214
+ additionalAttributes:nullptr
215
+ input:_input
216
+ withSelection:YES];
217
+
172
218
  // THEN, add the attributes to not apply them on the space
173
- [_input->textView.textStorage addAttributes:newAttrs range:NSMakeRange(rangeToBeReplaced.location, text.length)];
174
-
219
+ [_input->textView.textStorage
220
+ addAttributes:newAttrs
221
+ range:NSMakeRange(rangeToBeReplaced.location, text.length)];
222
+
175
223
  // mention editing should finish
176
224
  [self removeActiveMentionRange];
177
-
225
+
178
226
  // unlock editing
179
227
  _blockMentionEditing = NO;
180
228
  }
181
229
 
182
230
  - (void)addMentionAtRange:(NSRange)range params:(MentionParams *)params {
183
231
  _blockMentionEditing = YES;
184
-
185
- MentionStyleProps *styleProps = [_input->config mentionStylePropsForIndicator:params.indicator];
186
-
232
+
233
+ MentionStyleProps *styleProps =
234
+ [_input->config mentionStylePropsForIndicator:params.indicator];
235
+
187
236
  NSMutableDictionary *newAttrs = [@{
188
- MentionAttributeName: params,
189
- NSForegroundColorAttributeName: styleProps.color,
190
- NSUnderlineColorAttributeName: styleProps.color,
191
- NSStrikethroughColorAttributeName: styleProps.color,
192
- NSBackgroundColorAttributeName: [styleProps.backgroundColor colorWithAlphaIfNotTransparent:0.4],
237
+ MentionAttributeName : params,
238
+ NSForegroundColorAttributeName : styleProps.color,
239
+ NSUnderlineColorAttributeName : styleProps.color,
240
+ NSStrikethroughColorAttributeName : styleProps.color,
241
+ NSBackgroundColorAttributeName :
242
+ [styleProps.backgroundColor colorWithAlphaIfNotTransparent:0.4],
193
243
  } mutableCopy];
194
-
195
- if(styleProps.decorationLine == DecorationUnderline) {
244
+
245
+ if (styleProps.decorationLine == DecorationUnderline) {
196
246
  newAttrs[NSUnderlineStyleAttributeName] = @(NSUnderlineStyleSingle);
197
247
  }
198
-
248
+
199
249
  [_input->textView.textStorage addAttributes:newAttrs range:range];
200
-
250
+
201
251
  _blockMentionEditing = NO;
202
252
  }
203
253
 
204
254
  - (void)startMentionWithIndicator:(NSString *)indicator {
205
255
  NSRange currentRange = _input->textView.selectedRange;
206
-
256
+
207
257
  BOOL addSpaceBefore = NO;
208
258
  BOOL addSpaceAfter = NO;
209
-
210
- if(currentRange.location > 0) {
211
- unichar charBefore = [_input->textView.textStorage.string characterAtIndex:(currentRange.location - 1)];
212
- if(![[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:charBefore]) {
259
+
260
+ if (currentRange.location > 0) {
261
+ unichar charBefore = [_input->textView.textStorage.string
262
+ characterAtIndex:(currentRange.location - 1)];
263
+ if (![[NSCharacterSet whitespaceAndNewlineCharacterSet]
264
+ characterIsMember:charBefore]) {
213
265
  addSpaceBefore = YES;
214
266
  }
215
267
  }
216
-
217
- if(currentRange.location + currentRange.length < _input->textView.textStorage.string.length) {
218
- unichar charAfter = [_input->textView.textStorage.string characterAtIndex:(currentRange.location + currentRange.length)];
219
- if(![[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:charAfter]) {
268
+
269
+ if (currentRange.location + currentRange.length <
270
+ _input->textView.textStorage.string.length) {
271
+ unichar charAfter = [_input->textView.textStorage.string
272
+ characterAtIndex:(currentRange.location + currentRange.length)];
273
+ if (![[NSCharacterSet whitespaceAndNewlineCharacterSet]
274
+ characterIsMember:charAfter]) {
220
275
  addSpaceAfter = YES;
221
276
  }
222
277
  }
223
-
224
- NSString *finalString = [NSString stringWithFormat:@"%@%@%@",
225
- addSpaceBefore ? @" " : @"",
226
- indicator,
227
- addSpaceAfter ? @" " : @""
228
- ];
229
-
230
- NSRange newSelect = NSMakeRange(currentRange.location + finalString.length + (addSpaceAfter ? -1 : 0), 0);
231
-
232
- if(currentRange.length == 0) {
233
- [TextInsertionUtils insertText:finalString at:currentRange.location additionalAttributes:nullptr input:_input withSelection:NO];
278
+
279
+ NSString *finalString =
280
+ [NSString stringWithFormat:@"%@%@%@", addSpaceBefore ? @" " : @"",
281
+ indicator, addSpaceAfter ? @" " : @""];
282
+
283
+ NSRange newSelect = NSMakeRange(
284
+ currentRange.location + finalString.length + (addSpaceAfter ? -1 : 0), 0);
285
+
286
+ if (currentRange.length == 0) {
287
+ [TextInsertionUtils insertText:finalString
288
+ at:currentRange.location
289
+ additionalAttributes:nullptr
290
+ input:_input
291
+ withSelection:NO];
234
292
  } else {
235
- [TextInsertionUtils replaceText:finalString at:currentRange additionalAttributes:nullptr input:_input withSelection:NO];
293
+ [TextInsertionUtils replaceText:finalString
294
+ at:currentRange
295
+ additionalAttributes:nullptr
296
+ input:_input
297
+ withSelection:NO];
236
298
  }
237
-
299
+
238
300
  [_input->textView reactFocus];
239
301
  _input->textView.selectedRange = newSelect;
240
302
  }
@@ -242,46 +304,53 @@ static NSString *const MentionAttributeName = @"MentionAttributeName";
242
304
  // handles removing no longer valid mentions
243
305
  - (void)handleExistingMentions {
244
306
  // unfortunately whole text needs to be checked for them
245
- // checking the modified words doesn't work because mention's text can have any number of spaces, which makes one mention any number of words long
246
-
247
- NSRange wholeText = NSMakeRange(0, _input->textView.textStorage.string.length);
307
+ // checking the modified words doesn't work because mention's text can have
308
+ // any number of spaces, which makes one mention any number of words long
309
+
310
+ NSRange wholeText =
311
+ NSMakeRange(0, _input->textView.textStorage.string.length);
248
312
  // get menntions in ascending range.location order
249
- NSArray<StylePair *> *mentions = [[self findAllOccurences:wholeText] sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
250
- NSRange range1 = [((StylePair *)obj1).rangeValue rangeValue];
251
- NSRange range2 = [((StylePair *)obj2).rangeValue rangeValue];
252
- if(range1.location < range2.location) {
253
- return NSOrderedAscending;
254
- } else {
255
- return NSOrderedDescending;
256
- }
257
- }];
258
-
313
+ NSArray<StylePair *> *mentions = [[self findAllOccurences:wholeText]
314
+ sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1,
315
+ id _Nonnull obj2) {
316
+ NSRange range1 = [((StylePair *)obj1).rangeValue rangeValue];
317
+ NSRange range2 = [((StylePair *)obj2).rangeValue rangeValue];
318
+ if (range1.location < range2.location) {
319
+ return NSOrderedAscending;
320
+ } else {
321
+ return NSOrderedDescending;
322
+ }
323
+ }];
324
+
259
325
  // set of ranges to have their mentions removed - aren't valid anymore
260
326
  NSMutableSet<NSValue *> *rangesToRemove = [[NSMutableSet alloc] init];
261
-
262
- for(NSInteger i = 0; i < mentions.count; i++) {
327
+
328
+ for (NSInteger i = 0; i < mentions.count; i++) {
263
329
  StylePair *mention = mentions[i];
264
330
  NSRange currentRange = [mention.rangeValue rangeValue];
265
331
  NSString *currentText = ((MentionParams *)mention.styleValue).text;
266
- // check locations with the previous mention if it exists - if they got merged they need to be removed
267
- if(i > 0) {
268
- NSRange prevRange = [((StylePair*)mentions[i-1]).rangeValue rangeValue];
332
+ // check locations with the previous mention if it exists - if they got
333
+ // merged they need to be removed
334
+ if (i > 0) {
335
+ NSRange prevRange =
336
+ [((StylePair *)mentions[i - 1]).rangeValue rangeValue];
269
337
  // mentions merged - both need to go out
270
- if(prevRange.location + prevRange.length == currentRange.location) {
338
+ if (prevRange.location + prevRange.length == currentRange.location) {
271
339
  [rangesToRemove addObject:[NSValue valueWithRange:prevRange]];
272
340
  [rangesToRemove addObject:[NSValue valueWithRange:currentRange]];
273
341
  continue;
274
342
  }
275
343
  }
276
-
344
+
277
345
  // check for text, any modifications to it makes mention invalid
278
- NSString *existingText = [_input->textView.textStorage.string substringWithRange:currentRange];
279
- if(![existingText isEqualToString:currentText]) {
346
+ NSString *existingText =
347
+ [_input->textView.textStorage.string substringWithRange:currentRange];
348
+ if (![existingText isEqualToString:currentText]) {
280
349
  [rangesToRemove addObject:[NSValue valueWithRange:currentRange]];
281
350
  }
282
351
  }
283
-
284
- for(NSValue *value in rangesToRemove) {
352
+
353
+ for (NSValue *value in rangesToRemove) {
285
354
  [self removeAttributes:[value rangeValue]];
286
355
  }
287
356
  }
@@ -289,98 +358,124 @@ static NSString *const MentionAttributeName = @"MentionAttributeName";
289
358
  // manages active mention range, which in turn emits proper onMention event
290
359
  - (void)manageMentionEditing {
291
360
  // no actions performed when block is active
292
- if(_blockMentionEditing) {
361
+ if (_blockMentionEditing) {
293
362
  return;
294
363
  }
295
364
 
296
365
  // we don't take longer selections into consideration
297
- if(_input->textView.selectedRange.length > 0) {
366
+ if (_input->textView.selectedRange.length > 0) {
298
367
  [self removeActiveMentionRange];
299
368
  return;
300
369
  }
301
-
370
+
302
371
  // get the text (and its range) that could be an editable mention
303
372
  NSArray *mentionCandidate = [self getMentionCandidate];
304
- if(mentionCandidate == nullptr) {
373
+ if (mentionCandidate == nullptr) {
305
374
  [self removeActiveMentionRange];
306
375
  return;
307
376
  }
308
377
  NSString *candidateText = mentionCandidate[0];
309
378
  NSRange candidateRange = [(NSValue *)mentionCandidate[1] rangeValue];
310
-
311
- // get style classes that the mention shouldn't be recognized in, together with other mentions
312
- NSArray *conflicts = _input->conflictingStyles[@([MentionStyle getStyleType])];
379
+
380
+ // get style classes that the mention shouldn't be recognized in, together
381
+ // with other mentions
382
+ NSArray *conflicts =
383
+ _input->conflictingStyles[@([MentionStyle getStyleType])];
313
384
  NSArray *blocks = _input->blockingStyles[@([MentionStyle getStyleType])];
314
- NSArray *allConflicts = [[conflicts arrayByAddingObjectsFromArray:blocks] arrayByAddingObject:@([MentionStyle getStyleType])];
385
+ NSArray *allConflicts = [[conflicts arrayByAddingObjectsFromArray:blocks]
386
+ arrayByAddingObject:@([MentionStyle getStyleType])];
315
387
  BOOL conflictingStyle = NO;
316
-
317
- for(NSNumber *styleType in allConflicts) {
388
+
389
+ for (NSNumber *styleType in allConflicts) {
318
390
  id<BaseStyleProtocol> styleClass = _input->stylesDict[styleType];
319
- if(styleClass != nullptr && [styleClass anyOccurence:candidateRange]) {
391
+ if (styleClass != nullptr && [styleClass anyOccurence:candidateRange]) {
320
392
  conflictingStyle = YES;
321
393
  break;
322
394
  }
323
395
  }
324
-
396
+
325
397
  // if any of the conflicting styles were present, don't edit the mention
326
- if(conflictingStyle) {
398
+ if (conflictingStyle) {
327
399
  [self removeActiveMentionRange];
328
400
  return;
329
401
  }
330
-
402
+
331
403
  // everything checks out - we are indeed editing a mention
332
404
  [self setActiveMentionRange:candidateRange text:candidateText];
333
405
  }
334
406
 
335
407
  // used to fix mentions' typing attributes
336
408
  - (void)manageMentionTypingAttributes {
337
- // same as with links, mentions' typing attributes need to be constantly removed whenever we are somewhere near
409
+ // same as with links, mentions' typing attributes need to be constantly
410
+ // removed whenever we are somewhere near
338
411
  BOOL removeAttrs = NO;
339
412
  MentionParams *params;
340
-
341
- if(_input->textView.selectedRange.length == 0) {
413
+
414
+ if (_input->textView.selectedRange.length == 0) {
342
415
  // check before
343
- if(_input->textView.selectedRange.location >= 1) {
344
- if([self detectStyle:NSMakeRange(_input->textView.selectedRange.location - 1, 1)]) {
416
+ if (_input->textView.selectedRange.location >= 1) {
417
+ if ([self detectStyle:NSMakeRange(
418
+ _input->textView.selectedRange.location - 1,
419
+ 1)]) {
345
420
  removeAttrs = YES;
346
- params = [self getMentionParamsAt:_input->textView.selectedRange.location - 1];
421
+ params = [self
422
+ getMentionParamsAt:_input->textView.selectedRange.location - 1];
347
423
  }
348
424
  }
349
425
  // check after
350
- if(_input->textView.selectedRange.location < _input->textView.textStorage.length) {
351
- if([self detectStyle:NSMakeRange(_input->textView.selectedRange.location, 1)]) {
426
+ if (_input->textView.selectedRange.location <
427
+ _input->textView.textStorage.length) {
428
+ if ([self detectStyle:NSMakeRange(_input->textView.selectedRange.location,
429
+ 1)]) {
352
430
  removeAttrs = YES;
353
- params = [self getMentionParamsAt:_input->textView.selectedRange.location];
431
+ params =
432
+ [self getMentionParamsAt:_input->textView.selectedRange.location];
354
433
  }
355
434
  }
356
435
  } else {
357
- if([self anyOccurence:_input->textView.selectedRange]) {
436
+ if ([self anyOccurence:_input->textView.selectedRange]) {
358
437
  removeAttrs = YES;
359
438
  }
360
439
  }
361
-
362
- if(removeAttrs) {
363
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
364
- newTypingAttrs[NSForegroundColorAttributeName] = [_input->config primaryColor];
365
- newTypingAttrs[NSUnderlineColorAttributeName] = [_input->config primaryColor];
366
- newTypingAttrs[NSStrikethroughColorAttributeName] = [_input->config primaryColor];
440
+
441
+ if (removeAttrs) {
442
+ NSMutableDictionary *newTypingAttrs =
443
+ [_input->textView.typingAttributes mutableCopy];
444
+ newTypingAttrs[NSForegroundColorAttributeName] =
445
+ [_input->config primaryColor];
446
+ newTypingAttrs[NSUnderlineColorAttributeName] =
447
+ [_input->config primaryColor];
448
+ newTypingAttrs[NSStrikethroughColorAttributeName] =
449
+ [_input->config primaryColor];
367
450
  [newTypingAttrs removeObjectForKey:NSBackgroundColorAttributeName];
368
- if([self stylePropsWithParams:params].decorationLine == DecorationUnderline) {
451
+ if ([self stylePropsWithParams:params].decorationLine ==
452
+ DecorationUnderline) {
369
453
  [newTypingAttrs removeObjectForKey:NSUnderlineStyleAttributeName];
370
454
  }
371
455
  _input->textView.typingAttributes = newTypingAttrs;
372
456
  }
373
457
  }
374
458
 
375
- // replacing whole input (that starts with a mention) with a manually typed letter improperly applies mention's attributes to all the following text
376
- - (BOOL)handleLeadingMentionReplacement:(NSRange)range replacementText:(NSString *)text {
459
+ // replacing whole input (that starts with a mention) with a manually typed
460
+ // letter improperly applies mention's attributes to all the following text
461
+ - (BOOL)handleLeadingMentionReplacement:(NSRange)range
462
+ replacementText:(NSString *)text {
377
463
  // whole textView range gets replaced with a single letter
378
- if(_input->textView.textStorage.string.length > 0 && NSEqualRanges(range, NSMakeRange(0, _input->textView.textStorage.string.length)) && text.length == 1) {
464
+ if (_input->textView.textStorage.string.length > 0 &&
465
+ NSEqualRanges(
466
+ range, NSMakeRange(0, _input->textView.textStorage.string.length)) &&
467
+ text.length == 1) {
379
468
  // first character detection is enough for the removal to be done
380
- if([self detectStyle:NSMakeRange(0, 1)]) {
381
- [self removeAttributes:NSMakeRange(0, _input->textView.textStorage.string.length)];
469
+ if ([self detectStyle:NSMakeRange(0, 1)]) {
470
+ [self
471
+ removeAttributes:NSMakeRange(
472
+ 0, _input->textView.textStorage.string.length)];
382
473
  // do the replacing manually
383
- [TextInsertionUtils replaceText:text at:range additionalAttributes:nullptr input:_input withSelection:YES];
474
+ [TextInsertionUtils replaceText:text
475
+ at:range
476
+ additionalAttributes:nullptr
477
+ input:_input
478
+ withSelection:YES];
384
479
  return YES;
385
480
  }
386
481
  }
@@ -391,19 +486,18 @@ static NSString *const MentionAttributeName = @"MentionAttributeName";
391
486
  - (MentionParams *)getMentionParamsAt:(NSUInteger)location {
392
487
  NSRange mentionRange = NSMakeRange(0, 0);
393
488
  NSRange inputRange = NSMakeRange(0, _input->textView.textStorage.length);
394
-
489
+
395
490
  // don't search at the very end of input
396
491
  NSUInteger searchLocation = location;
397
- if(searchLocation == _input->textView.textStorage.length) {
492
+ if (searchLocation == _input->textView.textStorage.length) {
398
493
  return nullptr;
399
494
  }
400
-
401
- MentionParams *value = [_input->textView.textStorage
402
- attribute:MentionAttributeName
403
- atIndex:searchLocation
404
- longestEffectiveRange: &mentionRange
405
- inRange:inputRange
406
- ];
495
+
496
+ MentionParams *value =
497
+ [_input->textView.textStorage attribute:MentionAttributeName
498
+ atIndex:searchLocation
499
+ longestEffectiveRange:&mentionRange
500
+ inRange:inputRange];
407
501
  return value;
408
502
  }
409
503
 
@@ -415,23 +509,21 @@ static NSString *const MentionAttributeName = @"MentionAttributeName";
415
509
  - (NSRange)getFullMentionRangeAt:(NSUInteger)location {
416
510
  NSRange mentionRange = NSMakeRange(0, 0);
417
511
  NSRange inputRange = NSMakeRange(0, _input->textView.textStorage.length);
418
-
512
+
419
513
  // get the previous index if possible when at the very end of input
420
514
  NSUInteger searchLocation = location;
421
- if(searchLocation == _input->textView.textStorage.length) {
422
- if(searchLocation == 0) {
515
+ if (searchLocation == _input->textView.textStorage.length) {
516
+ if (searchLocation == 0) {
423
517
  return mentionRange;
424
518
  } else {
425
519
  searchLocation = searchLocation - 1;
426
520
  }
427
521
  }
428
-
429
- [_input->textView.textStorage
430
- attribute:MentionAttributeName
431
- atIndex:searchLocation
432
- longestEffectiveRange: &mentionRange
433
- inRange:inputRange
434
- ];
522
+
523
+ [_input->textView.textStorage attribute:MentionAttributeName
524
+ atIndex:searchLocation
525
+ longestEffectiveRange:&mentionRange
526
+ inRange:inputRange];
435
527
  return mentionRange;
436
528
  }
437
529
 
@@ -441,103 +533,125 @@ static NSString *const MentionAttributeName = @"MentionAttributeName";
441
533
  return [_input->config mentionStylePropsForIndicator:params.indicator];
442
534
  }
443
535
 
444
- // finds if any word/words around current selection are eligible to be edited as mentions
445
- // since we allow for a single space inside an edited mention, we have take both current and the previous word into account
536
+ // finds if any word/words around current selection are eligible to be edited as
537
+ // mentions since we allow for a single space inside an edited mention, we have
538
+ // take both current and the previous word into account
446
539
  - (NSArray *)getMentionCandidate {
447
540
  NSDictionary *currentWord, *previousWord;
448
541
  NSString *currentWordText, *previousWordText, *finalText;
449
542
  NSValue *currentWordRange, *previousWordRange;
450
543
  NSRange finalRange;
451
-
544
+
452
545
  // word at the current selection
453
- currentWord = [WordsUtils getCurrentWord:_input->textView.textStorage.string range:_input->textView.selectedRange];
454
- if(currentWord != nullptr ) {
546
+ currentWord = [WordsUtils getCurrentWord:_input->textView.textStorage.string
547
+ range:_input->textView.selectedRange];
548
+ if (currentWord != nullptr) {
455
549
  currentWordText = (NSString *)[currentWord objectForKey:@"word"];
456
550
  currentWordRange = (NSValue *)[currentWord objectForKey:@"range"];
457
551
  }
458
-
459
- if(currentWord != nullptr) {
552
+
553
+ if (currentWord != nullptr) {
460
554
  // current word exists
461
555
  unichar currentFirstChar = [currentWordText characterAtIndex:0];
462
-
463
- if([[_input->config mentionIndicators] containsObject:@(currentFirstChar)]) {
464
- // current word exists and has a mention indicator; no need to check for the previous word
556
+
557
+ if ([[_input->config mentionIndicators]
558
+ containsObject:@(currentFirstChar)]) {
559
+ // current word exists and has a mention indicator; no need to check for
560
+ // the previous word
465
561
  finalText = currentWordText;
466
562
  finalRange = [currentWordRange rangeValue];
467
563
  } else {
468
- // current word exists but no traces of mention indicator; get the previous word
469
-
470
- NSInteger previousWordSearchLocation = [currentWordRange rangeValue].location - 1;
471
- if(previousWordSearchLocation < 0) {
564
+ // current word exists but no traces of mention indicator; get the
565
+ // previous word
566
+
567
+ NSInteger previousWordSearchLocation =
568
+ [currentWordRange rangeValue].location - 1;
569
+ if (previousWordSearchLocation < 0) {
472
570
  // previous word can't exist
473
571
  return nullptr;
474
572
  }
475
-
476
- unichar separatorChar = [_input->textView.textStorage.string characterAtIndex:previousWordSearchLocation];
477
- if(![[NSCharacterSet whitespaceCharacterSet] characterIsMember:separatorChar]) {
478
- // we want to check for the previous word ONLY if the separating character was a space
479
- // newlines don't make it
573
+
574
+ unichar separatorChar = [_input->textView.textStorage.string
575
+ characterAtIndex:previousWordSearchLocation];
576
+ if (![[NSCharacterSet whitespaceCharacterSet]
577
+ characterIsMember:separatorChar]) {
578
+ // we want to check for the previous word ONLY if the separating
579
+ // character was a space newlines don't make it
480
580
  return nullptr;
481
581
  }
482
-
483
- previousWord = [WordsUtils getCurrentWord:_input->textView.textStorage.string range:NSMakeRange(previousWordSearchLocation, 0)];
484
-
485
- if(previousWord != nullptr) {
582
+
583
+ previousWord = [WordsUtils
584
+ getCurrentWord:_input->textView.textStorage.string
585
+ range:NSMakeRange(previousWordSearchLocation, 0)];
586
+
587
+ if (previousWord != nullptr) {
486
588
  // previous word exists; get its properties
487
589
  previousWordText = (NSString *)[previousWord objectForKey:@"word"];
488
590
  previousWordRange = (NSValue *)[previousWord objectForKey:@"range"];
489
-
591
+
490
592
  // check for the mention indicators in the previous word
491
593
  unichar previousFirstChar = [previousWordText characterAtIndex:0];
492
-
493
- if([[_input->config mentionIndicators] containsObject:@(previousFirstChar) ]) {
494
- // previous word has a proper mention indicator: treat both words as an editable mention
495
- finalText = [NSString stringWithFormat:@"%@ %@", previousWordText, currentWordText];
594
+
595
+ if ([[_input->config mentionIndicators]
596
+ containsObject:@(previousFirstChar)]) {
597
+ // previous word has a proper mention indicator: treat both words as
598
+ // an editable mention
599
+ finalText = [NSString
600
+ stringWithFormat:@"%@ %@", previousWordText, currentWordText];
496
601
  // range length is both words' lengths + 1 for a space between them
497
- finalRange = NSMakeRange(
498
- [previousWordRange rangeValue].location,
499
- [previousWordRange rangeValue].length + [currentWordRange rangeValue].length + 1
500
- );
602
+ finalRange =
603
+ NSMakeRange([previousWordRange rangeValue].location,
604
+ [previousWordRange rangeValue].length +
605
+ [currentWordRange rangeValue].length + 1);
501
606
  } else {
502
607
  // neither current nor previous words have a mention indicator
503
608
  return nullptr;
504
609
  }
505
610
  } else {
506
- // previous word doesn't exist and no mention indicators in the current word
611
+ // previous word doesn't exist and no mention indicators in the current
612
+ // word
507
613
  return nullptr;
508
614
  }
509
615
  }
510
616
  } else {
511
617
  // current word doesn't exist; try getting the previous one
512
-
513
- NSInteger previousWordSearchLocation = _input->textView.selectedRange.location - 1;
514
- if(previousWordSearchLocation < 0) {
618
+
619
+ NSInteger previousWordSearchLocation =
620
+ _input->textView.selectedRange.location - 1;
621
+ if (previousWordSearchLocation < 0) {
515
622
  // previous word can't exist
516
623
  return nullptr;
517
624
  }
518
-
519
- unichar separatorChar = [_input->textView.textStorage.string characterAtIndex:previousWordSearchLocation];
520
- if(![[NSCharacterSet whitespaceCharacterSet] characterIsMember:separatorChar]) {
521
- // we want to check for the previous word ONLY if the separating character was a space
522
- // newlines don't make it
625
+
626
+ unichar separatorChar = [_input->textView.textStorage.string
627
+ characterAtIndex:previousWordSearchLocation];
628
+ if (![[NSCharacterSet whitespaceCharacterSet]
629
+ characterIsMember:separatorChar]) {
630
+ // we want to check for the previous word ONLY if the separating character
631
+ // was a space newlines don't make it
523
632
  return nullptr;
524
633
  }
525
-
526
- previousWord = [WordsUtils getCurrentWord:_input->textView.textStorage.string range:NSMakeRange(previousWordSearchLocation, 0)];
527
-
528
- if(previousWord != nullptr) {
634
+
635
+ previousWord =
636
+ [WordsUtils getCurrentWord:_input->textView.textStorage.string
637
+ range:NSMakeRange(previousWordSearchLocation, 0)];
638
+
639
+ if (previousWord != nullptr) {
529
640
  // previous word exists; get its properties
530
641
  previousWordText = (NSString *)[previousWord objectForKey:@"word"];
531
642
  previousWordRange = (NSValue *)[previousWord objectForKey:@"range"];
532
-
643
+
533
644
  // check for the mention indicators in the previous word
534
645
  unichar previousFirstChar = [previousWordText characterAtIndex:0];
535
-
536
- if([[_input->config mentionIndicators] containsObject:@(previousFirstChar)]) {
537
- // previous word has a proper mention indicator; treat previous word + a space as a editable mention
646
+
647
+ if ([[_input->config mentionIndicators]
648
+ containsObject:@(previousFirstChar)]) {
649
+ // previous word has a proper mention indicator; treat previous word + a
650
+ // space as a editable mention
538
651
  finalText = [NSString stringWithFormat:@"%@ ", previousWordText];
539
652
  // the range length is previous word length + 1 for a space
540
- finalRange = NSMakeRange([previousWordRange rangeValue].location, [previousWordRange rangeValue].length + 1);
653
+ finalRange = NSMakeRange([previousWordRange rangeValue].location,
654
+ [previousWordRange rangeValue].length + 1);
541
655
  } else {
542
656
  // no current word, previous has no mention indicators
543
657
  return nullptr;
@@ -547,22 +661,26 @@ static NSString *const MentionAttributeName = @"MentionAttributeName";
547
661
  return nullptr;
548
662
  }
549
663
  }
550
-
551
- return @[finalText, [NSValue valueWithRange:finalRange]];
664
+
665
+ return @[ finalText, [NSValue valueWithRange:finalRange] ];
552
666
  }
553
667
 
554
- // both used for setting the active mention range + indicator and fires proper onMention event
668
+ // both used for setting the active mention range + indicator and fires proper
669
+ // onMention event
555
670
  - (void)setActiveMentionRange:(NSRange)range text:(NSString *)text {
556
- NSString *indicatorString = [NSString stringWithFormat:@"%C", [text characterAtIndex:0]];
557
- NSString *textString = [text substringWithRange:NSMakeRange(1, text.length - 1)];
671
+ NSString *indicatorString =
672
+ [NSString stringWithFormat:@"%C", [text characterAtIndex:0]];
673
+ NSString *textString =
674
+ [text substringWithRange:NSMakeRange(1, text.length - 1)];
558
675
  _activeMentionIndicator = indicatorString;
559
676
  _activeMentionRange = [NSValue valueWithRange:range];
560
677
  [_input emitOnMentionEvent:indicatorString text:textString];
561
678
  }
562
679
 
563
- // removes stored mention range + indicator, which means that we no longer edit a mention and onMention event gets fired
680
+ // removes stored mention range + indicator, which means that we no longer edit
681
+ // a mention and onMention event gets fired
564
682
  - (void)removeActiveMentionRange {
565
- if(_activeMentionIndicator != nullptr && _activeMentionRange != nullptr) {
683
+ if (_activeMentionIndicator != nullptr && _activeMentionRange != nullptr) {
566
684
  NSString *indicatorCopy = [_activeMentionIndicator copy];
567
685
  _activeMentionIndicator = nullptr;
568
686
  _activeMentionRange = nullptr;
@@ -571,4 +689,3 @@ static NSString *const MentionAttributeName = @"MentionAttributeName";
571
689
  }
572
690
 
573
691
  @end
574
-