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,21 +1,27 @@
1
- #import "StyleHeaders.h"
2
1
  #import "EnrichedTextInputView.h"
3
2
  #import "OccurenceUtils.h"
3
+ #import "StyleHeaders.h"
4
4
  #import "TextInsertionUtils.h"
5
5
  #import "UIView+React.h"
6
6
  #import "WordsUtils.h"
7
7
 
8
- // custom NSAttributedStringKeys to differentiate manually added and automatically detected links
8
+ // custom NSAttributedStringKeys to differentiate manually added and
9
+ // automatically detected links
9
10
  static NSString *const ManualLinkAttributeName = @"ManualLinkAttributeName";
10
- static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName";
11
+ static NSString *const AutomaticLinkAttributeName =
12
+ @"AutomaticLinkAttributeName";
11
13
 
12
14
  @implementation LinkStyle {
13
15
  EnrichedTextInputView *_input;
14
16
  }
15
17
 
16
- + (StyleType)getStyleType { return Link; }
18
+ + (StyleType)getStyleType {
19
+ return Link;
20
+ }
17
21
 
18
- + (BOOL)isParagraphStyle { return NO; }
22
+ + (BOOL)isParagraphStyle {
23
+ return NO;
24
+ }
19
25
 
20
26
  - (instancetype)initWithInput:(id)input {
21
27
  self = [super init];
@@ -27,7 +33,7 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
27
33
  // no-op for links
28
34
  }
29
35
 
30
- - (void)addAttributes:(NSRange)range {
36
+ - (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
31
37
  // no-op for links
32
38
  }
33
39
 
@@ -39,25 +45,39 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
39
45
  - (void)removeAttributes:(NSRange)range {
40
46
  NSArray<StylePair *> *links = [self findAllOccurences:range];
41
47
  [_input->textView.textStorage beginEditing];
42
- for(StylePair *pair in links) {
43
- NSRange linkRange = [self getFullLinkRangeAt:[pair.rangeValue rangeValue].location];
44
- [_input->textView.textStorage removeAttribute:ManualLinkAttributeName range:linkRange];
45
- [_input->textView.textStorage removeAttribute:AutomaticLinkAttributeName range:linkRange];
46
- [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName value:[_input->config primaryColor] range:linkRange];
47
- [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName value:[_input->config primaryColor] range:linkRange];
48
- [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName value:[_input->config primaryColor] range:linkRange];
49
- if([_input->config linkDecorationLine] == DecorationUnderline) {
50
- [_input->textView.textStorage removeAttribute:NSUnderlineStyleAttributeName range:linkRange];
48
+ for (StylePair *pair in links) {
49
+ NSRange linkRange =
50
+ [self getFullLinkRangeAt:[pair.rangeValue rangeValue].location];
51
+ [_input->textView.textStorage removeAttribute:ManualLinkAttributeName
52
+ range:linkRange];
53
+ [_input->textView.textStorage removeAttribute:AutomaticLinkAttributeName
54
+ range:linkRange];
55
+ [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName
56
+ value:[_input->config primaryColor]
57
+ range:linkRange];
58
+ [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName
59
+ value:[_input->config primaryColor]
60
+ range:linkRange];
61
+ [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName
62
+ value:[_input->config primaryColor]
63
+ range:linkRange];
64
+ if ([_input->config linkDecorationLine] == DecorationUnderline) {
65
+ [_input->textView.textStorage
66
+ removeAttribute:NSUnderlineStyleAttributeName
67
+ range:linkRange];
51
68
  }
52
69
  }
53
70
  [_input->textView.textStorage endEditing];
54
-
71
+
55
72
  // adjust typing attributes as well
56
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
57
- newTypingAttrs[NSForegroundColorAttributeName] = [_input->config primaryColor];
73
+ NSMutableDictionary *newTypingAttrs =
74
+ [_input->textView.typingAttributes mutableCopy];
75
+ newTypingAttrs[NSForegroundColorAttributeName] =
76
+ [_input->config primaryColor];
58
77
  newTypingAttrs[NSUnderlineColorAttributeName] = [_input->config primaryColor];
59
- newTypingAttrs[NSStrikethroughColorAttributeName] = [_input->config primaryColor];
60
- if([_input->config linkDecorationLine] == DecorationUnderline) {
78
+ newTypingAttrs[NSStrikethroughColorAttributeName] =
79
+ [_input->config primaryColor];
80
+ if ([_input->config linkDecorationLine] == DecorationUnderline) {
61
81
  [newTypingAttrs removeObjectForKey:NSUnderlineStyleAttributeName];
62
82
  }
63
83
  _input->textView.typingAttributes = newTypingAttrs;
@@ -65,41 +85,56 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
65
85
 
66
86
  // used for conflicts, we have to remove the whole link
67
87
  - (void)removeTypingAttributes {
68
- NSRange linkRange = [self getFullLinkRangeAt:_input->textView.selectedRange.location];
88
+ NSRange linkRange =
89
+ [self getFullLinkRangeAt:_input->textView.selectedRange.location];
69
90
  [_input->textView.textStorage beginEditing];
70
- [_input->textView.textStorage removeAttribute:ManualLinkAttributeName range:linkRange];
71
- [_input->textView.textStorage removeAttribute:AutomaticLinkAttributeName range:linkRange];
72
- [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName value:[_input->config primaryColor] range:linkRange];
73
- [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName value:[_input->config primaryColor] range:linkRange];
74
- [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName value:[_input->config primaryColor] range:linkRange];
75
- if([_input->config linkDecorationLine] == DecorationUnderline) {
76
- [_input->textView.textStorage removeAttribute:NSUnderlineStyleAttributeName range:linkRange];
91
+ [_input->textView.textStorage removeAttribute:ManualLinkAttributeName
92
+ range:linkRange];
93
+ [_input->textView.textStorage removeAttribute:AutomaticLinkAttributeName
94
+ range:linkRange];
95
+ [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName
96
+ value:[_input->config primaryColor]
97
+ range:linkRange];
98
+ [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName
99
+ value:[_input->config primaryColor]
100
+ range:linkRange];
101
+ [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName
102
+ value:[_input->config primaryColor]
103
+ range:linkRange];
104
+ if ([_input->config linkDecorationLine] == DecorationUnderline) {
105
+ [_input->textView.textStorage removeAttribute:NSUnderlineStyleAttributeName
106
+ range:linkRange];
77
107
  }
78
108
  [_input->textView.textStorage endEditing];
79
-
109
+
80
110
  // adjust typing attributes as well
81
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
82
- newTypingAttrs[NSForegroundColorAttributeName] = [_input->config primaryColor];
111
+ NSMutableDictionary *newTypingAttrs =
112
+ [_input->textView.typingAttributes mutableCopy];
113
+ newTypingAttrs[NSForegroundColorAttributeName] =
114
+ [_input->config primaryColor];
83
115
  newTypingAttrs[NSUnderlineColorAttributeName] = [_input->config primaryColor];
84
- newTypingAttrs[NSStrikethroughColorAttributeName] = [_input->config primaryColor];
85
- if([_input->config linkDecorationLine] == DecorationUnderline) {
116
+ newTypingAttrs[NSStrikethroughColorAttributeName] =
117
+ [_input->config primaryColor];
118
+ if ([_input->config linkDecorationLine] == DecorationUnderline) {
86
119
  [newTypingAttrs removeObjectForKey:NSUnderlineStyleAttributeName];
87
120
  }
88
121
  _input->textView.typingAttributes = newTypingAttrs;
89
122
  }
90
123
 
91
- - (BOOL)styleCondition:(id _Nullable)value :(NSRange)range {
124
+ - (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
92
125
  NSString *linkValue = (NSString *)value;
93
126
  return linkValue != nullptr;
94
127
  }
95
128
 
96
129
  - (BOOL)detectStyle:(NSRange)range {
97
- if(range.length >= 1) {
98
- BOOL onlyLinks = [OccurenceUtils detectMultiple:@[ManualLinkAttributeName, AutomaticLinkAttributeName] withInput:_input inRange:range
99
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
100
- return [self styleCondition:value :range];
101
- }
102
- ];
130
+ if (range.length >= 1) {
131
+ BOOL onlyLinks = [OccurenceUtils
132
+ detectMultiple:@[ ManualLinkAttributeName, AutomaticLinkAttributeName ]
133
+ withInput:_input
134
+ inRange:range
135
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
136
+ return [self styleCondition:value:range];
137
+ }];
103
138
  return onlyLinks ? [self isSingleLinkIn:range] : NO;
104
139
  } else {
105
140
  return [self getLinkDataAt:range.location] != nullptr;
@@ -107,67 +142,90 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
107
142
  }
108
143
 
109
144
  - (BOOL)anyOccurence:(NSRange)range {
110
- return [OccurenceUtils anyMultiple:@[ManualLinkAttributeName, AutomaticLinkAttributeName] withInput:_input inRange:range
111
- withCondition:^BOOL(id _Nullable value, NSRange range) {
112
- return [self styleCondition:value :range];
113
- }
114
- ];
145
+ return [OccurenceUtils
146
+ anyMultiple:@[ ManualLinkAttributeName, AutomaticLinkAttributeName ]
147
+ withInput:_input
148
+ inRange:range
149
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
150
+ return [self styleCondition:value:range];
151
+ }];
115
152
  }
116
153
 
117
154
  - (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
118
- return [OccurenceUtils allMultiple:@[ManualLinkAttributeName, AutomaticLinkAttributeName] withInput:_input inRange:range
119
- withCondition:^BOOL(id _Nullable value, NSRange range) {
120
- return [self styleCondition:value :range];
121
- }
122
- ];
155
+ return [OccurenceUtils
156
+ allMultiple:@[ ManualLinkAttributeName, AutomaticLinkAttributeName ]
157
+ withInput:_input
158
+ inRange:range
159
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
160
+ return [self styleCondition:value:range];
161
+ }];
123
162
  }
124
163
 
125
164
  // MARK: - Public non-standard methods
126
165
 
127
- - (void)addLink:(NSString*)text url:(NSString*)url range:(NSRange)range manual:(BOOL)manual {
128
- NSString *currentText = [_input->textView.textStorage.string substringWithRange:range];
129
-
130
- NSMutableDictionary<NSAttributedStringKey, id> *newAttrs = [[NSMutableDictionary<NSAttributedStringKey, id> alloc] init];
166
+ - (void)addLink:(NSString *)text
167
+ url:(NSString *)url
168
+ range:(NSRange)range
169
+ manual:(BOOL)manual
170
+ withSelection:(BOOL)withSelection {
171
+ NSString *currentText =
172
+ [_input->textView.textStorage.string substringWithRange:range];
173
+
174
+ NSMutableDictionary<NSAttributedStringKey, id> *newAttrs =
175
+ [[NSMutableDictionary<NSAttributedStringKey, id> alloc] init];
131
176
  newAttrs[NSForegroundColorAttributeName] = [_input->config linkColor];
132
177
  newAttrs[NSUnderlineColorAttributeName] = [_input->config linkColor];
133
178
  newAttrs[NSStrikethroughColorAttributeName] = [_input->config linkColor];
134
- if([_input->config linkDecorationLine] == DecorationUnderline) {
179
+ if ([_input->config linkDecorationLine] == DecorationUnderline) {
135
180
  newAttrs[NSUnderlineStyleAttributeName] = @(NSUnderlineStyleSingle);
136
181
  }
137
- if(manual) {
182
+ if (manual) {
138
183
  newAttrs[ManualLinkAttributeName] = [url copy];
139
184
  } else {
140
185
  newAttrs[AutomaticLinkAttributeName] = [url copy];
141
186
  }
142
-
143
- if(range.length == 0) {
187
+
188
+ if (range.length == 0) {
144
189
  // insert link
145
- [TextInsertionUtils insertText:text at:range.location additionalAttributes:newAttrs input:_input withSelection:YES];
146
- } else if([currentText isEqualToString:text]) {
190
+ [TextInsertionUtils insertText:text
191
+ at:range.location
192
+ additionalAttributes:newAttrs
193
+ input:_input
194
+ withSelection:withSelection];
195
+ } else if ([currentText isEqualToString:text]) {
147
196
  // apply link attributes
148
197
  [_input->textView.textStorage addAttributes:newAttrs range:range];
149
- // TextInsertionUtils take care of the selection but here we have to manually set it behind the link
150
- // ONLY with manual links, automatic ones don't need the selection fix
151
- if(manual) {
198
+ // TextInsertionUtils take care of the selection but here we have to
199
+ // manually set it behind the link ONLY with manual links, automatic ones
200
+ // don't need the selection fix
201
+ if (manual && withSelection) {
152
202
  [_input->textView reactFocus];
153
- _input->textView.selectedRange = NSMakeRange(range.location + text.length, 0);
203
+ _input->textView.selectedRange =
204
+ NSMakeRange(range.location + text.length, 0);
154
205
  }
155
206
  } else {
156
207
  // replace text with link
157
- [TextInsertionUtils replaceText:text at:range additionalAttributes:newAttrs input:_input withSelection:YES];
208
+ [TextInsertionUtils replaceText:text
209
+ at:range
210
+ additionalAttributes:newAttrs
211
+ input:_input
212
+ withSelection:withSelection];
158
213
  }
159
-
214
+
160
215
  // mandatory connected links check
161
- NSDictionary *currentWord = [WordsUtils getCurrentWord:_input->textView.textStorage.string range:_input->textView.selectedRange];
162
- if(currentWord != nullptr) {
216
+ NSDictionary *currentWord =
217
+ [WordsUtils getCurrentWord:_input->textView.textStorage.string
218
+ range:_input->textView.selectedRange];
219
+ if (currentWord != nullptr) {
163
220
  // get word properties
164
221
  NSString *wordText = (NSString *)[currentWord objectForKey:@"word"];
165
222
  NSValue *wordRangeValue = (NSValue *)[currentWord objectForKey:@"range"];
166
- if(wordText != nullptr && wordRangeValue != nullptr) {
167
- [self removeConnectedLinksIfNeeded:wordText range:[wordRangeValue rangeValue]];
223
+ if (wordText != nullptr && wordRangeValue != nullptr) {
224
+ [self removeConnectedLinksIfNeeded:wordText
225
+ range:[wordRangeValue rangeValue]];
168
226
  }
169
227
  }
170
-
228
+
171
229
  [self manageLinkTypingAttributes];
172
230
  }
173
231
 
@@ -176,36 +234,37 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
176
234
  NSRange manualLinkRange = NSMakeRange(0, 0);
177
235
  NSRange automaticLinkRange = NSMakeRange(0, 0);
178
236
  NSRange inputRange = NSMakeRange(0, _input->textView.textStorage.length);
179
-
237
+
180
238
  // don't search at the very end of input
181
239
  NSUInteger searchLocation = location;
182
- if(searchLocation == _input->textView.textStorage.length) {
240
+ if (searchLocation == _input->textView.textStorage.length) {
183
241
  return nullptr;
184
242
  }
185
-
186
- NSString *manualUrl = [_input->textView.textStorage
187
- attribute:ManualLinkAttributeName
188
- atIndex:searchLocation
189
- longestEffectiveRange: &manualLinkRange
190
- inRange:inputRange
191
- ];
192
- NSString *automaticUrl = [_input->textView.textStorage
193
- attribute:AutomaticLinkAttributeName
194
- atIndex:searchLocation
195
- longestEffectiveRange: &automaticLinkRange
196
- inRange:inputRange
197
- ];
198
-
199
- if((manualUrl == nullptr && automaticUrl == nullptr) || (manualLinkRange.length == 0 && automaticLinkRange.length == 0)) {
243
+
244
+ NSString *manualUrl =
245
+ [_input->textView.textStorage attribute:ManualLinkAttributeName
246
+ atIndex:searchLocation
247
+ longestEffectiveRange:&manualLinkRange
248
+ inRange:inputRange];
249
+ NSString *automaticUrl =
250
+ [_input->textView.textStorage attribute:AutomaticLinkAttributeName
251
+ atIndex:searchLocation
252
+ longestEffectiveRange:&automaticLinkRange
253
+ inRange:inputRange];
254
+
255
+ if ((manualUrl == nullptr && automaticUrl == nullptr) ||
256
+ (manualLinkRange.length == 0 && automaticLinkRange.length == 0)) {
200
257
  return nullptr;
201
258
  }
202
-
259
+
203
260
  NSString *linkUrl = manualUrl == nullptr ? automaticUrl : manualUrl;
204
- NSRange linkRange = manualUrl == nullptr ? automaticLinkRange : manualLinkRange;
205
-
261
+ NSRange linkRange =
262
+ manualUrl == nullptr ? automaticLinkRange : manualLinkRange;
263
+
206
264
  LinkData *data = [[LinkData alloc] init];
207
265
  data.url = linkUrl;
208
- data.text = [_input->textView.textStorage.string substringWithRange:linkRange];
266
+ data.text =
267
+ [_input->textView.textStorage.string substringWithRange:linkRange];
209
268
  return data;
210
269
  }
211
270
 
@@ -214,64 +273,71 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
214
273
  NSRange manualLinkRange = NSMakeRange(0, 0);
215
274
  NSRange automaticLinkRange = NSMakeRange(0, 0);
216
275
  NSRange inputRange = NSMakeRange(0, _input->textView.textStorage.length);
217
-
276
+
218
277
  // get the previous index if possible when at the very end of input
219
278
  NSUInteger searchLocation = location;
220
- if(searchLocation == _input->textView.textStorage.length) {
221
- if(searchLocation == 0) {
279
+ if (searchLocation == _input->textView.textStorage.length) {
280
+ if (searchLocation == 0) {
222
281
  return NSMakeRange(0, 0);
223
282
  } else {
224
283
  searchLocation = searchLocation - 1;
225
284
  }
226
285
  }
227
-
228
- NSString *manualLink = [_input->textView.textStorage
229
- attribute:ManualLinkAttributeName
230
- atIndex:searchLocation
231
- longestEffectiveRange: &manualLinkRange
232
- inRange:inputRange
233
- ];
234
- NSString *automaticLink = [_input->textView.textStorage
235
- attribute:AutomaticLinkAttributeName
236
- atIndex:searchLocation
237
- longestEffectiveRange: &automaticLinkRange
238
- inRange:inputRange
239
- ];
240
-
286
+
287
+ NSString *manualLink =
288
+ [_input->textView.textStorage attribute:ManualLinkAttributeName
289
+ atIndex:searchLocation
290
+ longestEffectiveRange:&manualLinkRange
291
+ inRange:inputRange];
292
+ NSString *automaticLink =
293
+ [_input->textView.textStorage attribute:AutomaticLinkAttributeName
294
+ atIndex:searchLocation
295
+ longestEffectiveRange:&automaticLinkRange
296
+ inRange:inputRange];
297
+
241
298
  return manualLink == nullptr
242
- ? automaticLink == nullptr ? NSMakeRange(0, 0) : automaticLinkRange
243
- : manualLinkRange;
299
+ ? automaticLink == nullptr ? NSMakeRange(0, 0) : automaticLinkRange
300
+ : manualLinkRange;
244
301
  }
245
302
 
246
303
  - (void)manageLinkTypingAttributes {
247
- // link's typing attribtues need to be removed at ALL times whenever we have some link around
304
+ // link's typing attribtues need to be removed at ALL times whenever we have
305
+ // some link around
248
306
  BOOL removeAttrs = NO;
249
-
250
- if(_input->textView.selectedRange.length == 0) {
307
+
308
+ if (_input->textView.selectedRange.length == 0) {
251
309
  // check before
252
- if(_input->textView.selectedRange.location >= 1) {
253
- if([self detectStyle:NSMakeRange(_input->textView.selectedRange.location - 1, 1)]) {
310
+ if (_input->textView.selectedRange.location >= 1) {
311
+ if ([self detectStyle:NSMakeRange(
312
+ _input->textView.selectedRange.location - 1,
313
+ 1)]) {
254
314
  removeAttrs = YES;
255
315
  }
256
316
  }
257
317
  // check after
258
- if(_input->textView.selectedRange.location < _input->textView.textStorage.length) {
259
- if([self detectStyle:NSMakeRange(_input->textView.selectedRange.location, 1)]) {
318
+ if (_input->textView.selectedRange.location <
319
+ _input->textView.textStorage.length) {
320
+ if ([self detectStyle:NSMakeRange(_input->textView.selectedRange.location,
321
+ 1)]) {
260
322
  removeAttrs = YES;
261
323
  }
262
324
  }
263
325
  } else {
264
- if([self anyOccurence:_input->textView.selectedRange]) {
326
+ if ([self anyOccurence:_input->textView.selectedRange]) {
265
327
  removeAttrs = YES;
266
328
  }
267
329
  }
268
-
269
- if(removeAttrs) {
270
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
271
- newTypingAttrs[NSForegroundColorAttributeName] = [_input->config primaryColor];
272
- newTypingAttrs[NSUnderlineColorAttributeName] = [_input->config primaryColor];
273
- newTypingAttrs[NSStrikethroughColorAttributeName] = [_input->config primaryColor];
274
- if([_input->config linkDecorationLine] == DecorationUnderline) {
330
+
331
+ if (removeAttrs) {
332
+ NSMutableDictionary *newTypingAttrs =
333
+ [_input->textView.typingAttributes mutableCopy];
334
+ newTypingAttrs[NSForegroundColorAttributeName] =
335
+ [_input->config primaryColor];
336
+ newTypingAttrs[NSUnderlineColorAttributeName] =
337
+ [_input->config primaryColor];
338
+ newTypingAttrs[NSStrikethroughColorAttributeName] =
339
+ [_input->config primaryColor];
340
+ if ([_input->config linkDecorationLine] == DecorationUnderline) {
275
341
  [newTypingAttrs removeObjectForKey:NSUnderlineStyleAttributeName];
276
342
  }
277
343
  _input->textView.typingAttributes = newTypingAttrs;
@@ -280,84 +346,106 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
280
346
 
281
347
  // handles detecting and removing automatic links
282
348
  - (void)handleAutomaticLinks:(NSString *)word inRange:(NSRange)wordRange {
283
- InlineCodeStyle *inlineCodeStyle = [_input->stylesDict objectForKey:@([InlineCodeStyle getStyleType])];
284
- MentionStyle *mentionStyle = [_input->stylesDict objectForKey:@([MentionStyle getStyleType])];
285
- CodeBlockStyle *codeBlockStyle = [_input->stylesDict objectForKey:@([CodeBlockStyle getStyleType])];
286
-
349
+ InlineCodeStyle *inlineCodeStyle =
350
+ [_input->stylesDict objectForKey:@([InlineCodeStyle getStyleType])];
351
+ MentionStyle *mentionStyle =
352
+ [_input->stylesDict objectForKey:@([MentionStyle getStyleType])];
353
+ CodeBlockStyle *codeBlockStyle =
354
+ [_input->stylesDict objectForKey:@([CodeBlockStyle getStyleType])];
355
+
287
356
  if (inlineCodeStyle == nullptr || mentionStyle == nullptr) {
288
357
  return;
289
358
  }
290
-
359
+
291
360
  // we don't recognize links along mentions
292
361
  if ([mentionStyle anyOccurence:wordRange]) {
293
362
  return;
294
363
  }
295
-
364
+
296
365
  // we don't recognize links among inline code
297
366
  if ([inlineCodeStyle anyOccurence:wordRange]) {
298
367
  return;
299
368
  }
300
-
369
+
301
370
  // we don't recognize links in codeblocks
302
371
  if ([codeBlockStyle anyOccurence:wordRange]) {
303
372
  return;
304
373
  }
305
-
374
+
306
375
  // remove connected different links
307
376
  [self removeConnectedLinksIfNeeded:word range:wordRange];
308
-
377
+
309
378
  // we don't recognize automatic links along manual ones
310
379
  __block BOOL manualLinkPresent = NO;
311
- [_input->textView.textStorage enumerateAttribute:ManualLinkAttributeName inRange:wordRange options:0
312
- usingBlock:^(id value, NSRange range, BOOL *stop) {
313
- NSString *urlValue = (NSString *)value;
314
- if(urlValue != nullptr) {
315
- manualLinkPresent = YES;
316
- *stop = YES;
317
- }
318
- }];
319
- if(manualLinkPresent) {
380
+ [_input->textView.textStorage
381
+ enumerateAttribute:ManualLinkAttributeName
382
+ inRange:wordRange
383
+ options:0
384
+ usingBlock:^(id value, NSRange range, BOOL *stop) {
385
+ NSString *urlValue = (NSString *)value;
386
+ if (urlValue != nullptr) {
387
+ manualLinkPresent = YES;
388
+ *stop = YES;
389
+ }
390
+ }];
391
+ if (manualLinkPresent) {
320
392
  return;
321
393
  }
322
-
323
- NSRegularExpression *fullRegex = [NSRegularExpression regularExpressionWithPattern:@"http(s)?:\\/\\/www\\.[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"
324
- options:0
325
- error:nullptr
326
- ];
327
- NSRegularExpression *wwwRegex = [NSRegularExpression regularExpressionWithPattern:@"www\\.[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"
328
- options:0
329
- error:nullptr
330
- ];
331
- NSRegularExpression *bareRegex = [NSRegularExpression regularExpressionWithPattern:@"[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"
332
- options:0
333
- error:nullptr
334
- ];
335
-
394
+
395
+ NSRegularExpression *fullRegex = [NSRegularExpression
396
+ regularExpressionWithPattern:@"http(s)?:\\/\\/"
397
+ @"www\\.[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-"
398
+ @"z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"
399
+ options:0
400
+ error:nullptr];
401
+ NSRegularExpression *wwwRegex = [NSRegularExpression
402
+ regularExpressionWithPattern:@"www\\.[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-"
403
+ @"z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"
404
+ options:0
405
+ error:nullptr];
406
+ NSRegularExpression *bareRegex = [NSRegularExpression
407
+ regularExpressionWithPattern:@"[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-z]{2,"
408
+ @"6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"
409
+ options:0
410
+ error:nullptr];
411
+
336
412
  NSString *regexPassedUrl = nullptr;
337
-
338
- if ([fullRegex numberOfMatchesInString:word options:0 range:NSMakeRange(0, word.length)]) {
413
+
414
+ if ([fullRegex numberOfMatchesInString:word
415
+ options:0
416
+ range:NSMakeRange(0, word.length)]) {
339
417
  regexPassedUrl = word;
340
- } else if ([wwwRegex numberOfMatchesInString:word options:0 range:NSMakeRange(0, word.length)]) {
418
+ } else if ([wwwRegex numberOfMatchesInString:word
419
+ options:0
420
+ range:NSMakeRange(0, word.length)]) {
341
421
  regexPassedUrl = word;
342
- } else if ([bareRegex numberOfMatchesInString:word options:0 range:NSMakeRange(0, word.length)]) {
422
+ } else if ([bareRegex numberOfMatchesInString:word
423
+ options:0
424
+ range:NSMakeRange(0, word.length)]) {
343
425
  regexPassedUrl = word;
344
426
  } else if ([self anyOccurence:wordRange]) {
345
- // there was some automatic link (because anyOccurence is true and we are sure there are no manual links)
346
- // still, it didn't pass any regex - needs to be removed
427
+ // there was some automatic link (because anyOccurence is true and we are
428
+ // sure there are no manual links) still, it didn't pass any regex - needs
429
+ // to be removed
347
430
  [self removeAttributes:wordRange];
348
431
  }
349
-
350
- if(regexPassedUrl != nullptr) {
432
+
433
+ if (regexPassedUrl != nullptr) {
351
434
  // add style only if needed
352
435
  BOOL addStyle = YES;
353
- if([self detectStyle:wordRange]) {
436
+ if ([self detectStyle:wordRange]) {
354
437
  LinkData *currentData = [self getLinkDataAt:wordRange.location];
355
- if(currentData != nullptr && currentData.url != nullptr && [currentData.url isEqualToString:regexPassedUrl]) {
438
+ if (currentData != nullptr && currentData.url != nullptr &&
439
+ [currentData.url isEqualToString:regexPassedUrl]) {
356
440
  addStyle = NO;
357
441
  }
358
442
  }
359
- if(addStyle) {
360
- [self addLink:word url:regexPassedUrl range:wordRange manual:NO];
443
+ if (addStyle) {
444
+ [self addLink:word
445
+ url:regexPassedUrl
446
+ range:wordRange
447
+ manual:NO
448
+ withSelection:NO];
361
449
  // emit onLinkDetected if style was added
362
450
  [_input emitOnLinkDetectedEvent:word url:regexPassedUrl range:wordRange];
363
451
  }
@@ -371,57 +459,83 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
371
459
  __block NSString *manualLinkMaxValue = @"";
372
460
  __block NSInteger manualLinkMinIdx = -1;
373
461
  __block NSInteger manualLinkMaxIdx = -1;
374
-
375
- [_input->textView.textStorage enumerateAttribute:ManualLinkAttributeName inRange:wordRange options:0
376
- usingBlock:^(id value, NSRange range, BOOL *stop) {
377
- NSString *urlValue = (NSString *)value;
378
- if (urlValue != nullptr) {
379
- NSInteger linkMin = range.location;
380
- NSInteger linkMax = range.location + range.length - 1;
381
- if (manualLinkMinIdx == -1 || linkMin < manualLinkMinIdx) {
382
- manualLinkMinIdx = linkMin;
383
- manualLinkMinValue = value;
384
- }
385
- if (manualLinkMaxIdx == -1 || linkMax > manualLinkMaxIdx) {
386
- manualLinkMaxIdx = linkMax;
387
- manualLinkMaxValue = value;
388
- }
389
- }
390
- }];
391
-
462
+
463
+ [_input->textView.textStorage
464
+ enumerateAttribute:ManualLinkAttributeName
465
+ inRange:wordRange
466
+ options:0
467
+ usingBlock:^(id value, NSRange range, BOOL *stop) {
468
+ NSString *urlValue = (NSString *)value;
469
+ if (urlValue != nullptr) {
470
+ NSInteger linkMin = range.location;
471
+ NSInteger linkMax = range.location + range.length - 1;
472
+ if (manualLinkMinIdx == -1 || linkMin < manualLinkMinIdx) {
473
+ manualLinkMinIdx = linkMin;
474
+ manualLinkMinValue = value;
475
+ }
476
+ if (manualLinkMaxIdx == -1 || linkMax > manualLinkMaxIdx) {
477
+ manualLinkMaxIdx = linkMax;
478
+ manualLinkMaxValue = value;
479
+ }
480
+ }
481
+ }];
482
+
392
483
  // no manual links
393
- if(manualLinkMinIdx == -1 || manualLinkMaxIdx == -1) {
484
+ if (manualLinkMinIdx == -1 || manualLinkMaxIdx == -1) {
394
485
  return;
395
486
  }
396
-
487
+
397
488
  // heuristic for refreshing manual links:
398
489
  // we update the Manual attribute between the bounds of existing ones
399
490
  // we do that only if the bounds point to the same url
400
- // this way manual link gets "extended" only if some characters were added inside it
401
- if([manualLinkMinValue isEqualToString:manualLinkMaxValue]) {
402
- NSRange newRange = NSMakeRange(manualLinkMinIdx, manualLinkMaxIdx - manualLinkMinIdx + 1);
403
- [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName value:[_input->config linkColor] range:newRange];
404
- [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName value:[_input->config linkColor] range:newRange];
405
- [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName value:[_input->config linkColor] range:newRange];
406
- if([_input->config linkDecorationLine] == DecorationUnderline) {
407
- [_input->textView.textStorage addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:newRange];
491
+ // this way manual link gets "extended" only if some characters were added
492
+ // inside it
493
+ if ([manualLinkMinValue isEqualToString:manualLinkMaxValue]) {
494
+ NSRange newRange =
495
+ NSMakeRange(manualLinkMinIdx, manualLinkMaxIdx - manualLinkMinIdx + 1);
496
+ [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName
497
+ value:[_input->config linkColor]
498
+ range:newRange];
499
+ [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName
500
+ value:[_input->config linkColor]
501
+ range:newRange];
502
+ [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName
503
+ value:[_input->config linkColor]
504
+ range:newRange];
505
+ if ([_input->config linkDecorationLine] == DecorationUnderline) {
506
+ [_input->textView.textStorage addAttribute:NSUnderlineStyleAttributeName
507
+ value:@(NSUnderlineStyleSingle)
508
+ range:newRange];
408
509
  }
409
- [_input->textView.textStorage addAttribute:ManualLinkAttributeName value:manualLinkMinValue range:newRange];
510
+ [_input->textView.textStorage addAttribute:ManualLinkAttributeName
511
+ value:manualLinkMinValue
512
+ range:newRange];
410
513
  }
411
-
514
+
412
515
  // link typing attributes need to be fixed after these changes
413
516
  [self manageLinkTypingAttributes];
414
517
  }
415
518
 
416
- // replacing whole input (that starts with a link) with a manually typed letter improperly applies link's attributes to all the following text
417
- - (BOOL)handleLeadingLinkReplacement:(NSRange)range replacementText:(NSString *)text {
519
+ // replacing whole input (that starts with a link) with a manually typed letter
520
+ // improperly applies link's attributes to all the following text
521
+ - (BOOL)handleLeadingLinkReplacement:(NSRange)range
522
+ replacementText:(NSString *)text {
418
523
  // whole textView range gets replaced with a single letter
419
- if(_input->textView.textStorage.string.length > 0 && NSEqualRanges(range, NSMakeRange(0, _input->textView.textStorage.string.length)) && text.length == 1) {
524
+ if (_input->textView.textStorage.string.length > 0 &&
525
+ NSEqualRanges(
526
+ range, NSMakeRange(0, _input->textView.textStorage.string.length)) &&
527
+ text.length == 1) {
420
528
  // first character detection is enough for the removal to be done
421
- if([self detectStyle:NSMakeRange(0, 1)]) {
422
- [self removeAttributes:NSMakeRange(0, _input->textView.textStorage.string.length)];
529
+ if ([self detectStyle:NSMakeRange(0, 1)]) {
530
+ [self
531
+ removeAttributes:NSMakeRange(
532
+ 0, _input->textView.textStorage.string.length)];
423
533
  // do the replacing manually
424
- [TextInsertionUtils replaceText:text at:range additionalAttributes:nullptr input:_input withSelection:YES];
534
+ [TextInsertionUtils replaceText:text
535
+ at:range
536
+ additionalAttributes:nullptr
537
+ input:_input
538
+ withSelection:YES];
425
539
  return YES;
426
540
  }
427
541
  }
@@ -437,32 +551,39 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
437
551
  }
438
552
 
439
553
  - (void)removeConnectedLinksIfNeeded:(NSString *)word range:(NSRange)wordRange {
440
- BOOL anyAutomatic = [OccurenceUtils any:AutomaticLinkAttributeName withInput:_input inRange:wordRange
441
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
442
- return [self styleCondition:value :range];
443
- }
444
- ];
445
- BOOL anyManual = [OccurenceUtils any:ManualLinkAttributeName withInput:_input inRange:wordRange
446
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
447
- return [self styleCondition:value :range];
448
- }
449
- ];
450
-
554
+ BOOL anyAutomatic =
555
+ [OccurenceUtils any:AutomaticLinkAttributeName
556
+ withInput:_input
557
+ inRange:wordRange
558
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
559
+ return [self styleCondition:value:range];
560
+ }];
561
+ BOOL anyManual =
562
+ [OccurenceUtils any:ManualLinkAttributeName
563
+ withInput:_input
564
+ inRange:wordRange
565
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
566
+ return [self styleCondition:value:range];
567
+ }];
568
+
451
569
  // both manual and automatic links are somewhere - delete!
452
- if(anyAutomatic && anyManual) {
570
+ if (anyAutomatic && anyManual) {
453
571
  [self removeAttributes:wordRange];
454
572
  [self manageLinkTypingAttributes];
455
573
  }
456
-
457
- // we are now sure there is only one type of link there - and make sure it covers the whole word
458
- BOOL onlyLinks = [OccurenceUtils detectMultiple:@[ManualLinkAttributeName, AutomaticLinkAttributeName] withInput:_input inRange:wordRange
459
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
460
- return [self styleCondition:value :range];
461
- }
462
- ];
463
-
574
+
575
+ // we are now sure there is only one type of link there - and make sure it
576
+ // covers the whole word
577
+ BOOL onlyLinks = [OccurenceUtils
578
+ detectMultiple:@[ ManualLinkAttributeName, AutomaticLinkAttributeName ]
579
+ withInput:_input
580
+ inRange:wordRange
581
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
582
+ return [self styleCondition:value:range];
583
+ }];
584
+
464
585
  // only one link might be present!
465
- if(onlyLinks && ![self isSingleLinkIn:wordRange]) {
586
+ if (onlyLinks && ![self isSingleLinkIn:wordRange]) {
466
587
  [self removeAttributes:wordRange];
467
588
  [self manageLinkTypingAttributes];
468
589
  }