react-native-enriched 0.1.6 → 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 (123) hide show
  1. package/README.md +4 -14
  2. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +4 -1
  3. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +2 -1
  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/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +0 -45
  7. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +111 -2
  8. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +9 -3
  9. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +2 -0
  10. package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +1 -1
  11. package/android/src/main/java/com/swmansion/enriched/events/OnRequestHtmlResultEvent.kt +33 -0
  12. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +6 -0
  13. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +6 -0
  14. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +42 -1
  15. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +6 -0
  16. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +6 -0
  17. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +6 -0
  18. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +135 -9
  19. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +6 -0
  20. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +5 -0
  21. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +6 -0
  22. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +6 -0
  23. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +6 -0
  24. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +13 -3
  25. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +5 -0
  26. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +5 -0
  27. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +6 -0
  28. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +4 -0
  29. package/android/src/main/java/com/swmansion/enriched/spans/utils/ForceRedrawSpan.kt +13 -0
  30. package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +80 -9
  31. package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +1 -0
  32. package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +188 -5
  33. package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +57 -30
  34. package/android/src/main/java/com/swmansion/enriched/utils/AsyncDrawable.kt +91 -0
  35. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +24 -13
  36. package/android/src/main/java/com/swmansion/enriched/utils/ResourceManager.kt +26 -0
  37. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +3 -0
  38. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +6 -6
  39. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +6 -6
  40. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +19 -19
  41. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +40 -51
  42. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +13 -15
  43. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +23 -21
  44. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +35 -36
  45. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +4 -4
  46. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +13 -14
  47. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/conversions.h +12 -13
  48. package/android/src/main/res/drawable/broken_image.xml +10 -0
  49. package/ios/EnrichedTextInputView.h +27 -12
  50. package/ios/EnrichedTextInputView.mm +906 -547
  51. package/ios/attachments/ImageAttachment.h +10 -0
  52. package/ios/attachments/ImageAttachment.mm +34 -0
  53. package/ios/attachments/MediaAttachment.h +23 -0
  54. package/ios/attachments/MediaAttachment.mm +31 -0
  55. package/ios/config/InputConfig.h +12 -6
  56. package/ios/config/InputConfig.mm +71 -33
  57. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
  58. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
  59. package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +0 -45
  60. package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +41 -4
  61. package/ios/inputParser/InputParser.h +5 -5
  62. package/ios/inputParser/InputParser.mm +867 -333
  63. package/ios/inputTextView/InputTextView.h +1 -1
  64. package/ios/inputTextView/InputTextView.mm +100 -59
  65. package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +11 -9
  66. package/ios/internals/EnrichedTextInputViewShadowNode.h +28 -24
  67. package/ios/internals/EnrichedTextInputViewShadowNode.mm +64 -47
  68. package/ios/internals/EnrichedTextInputViewState.h +3 -1
  69. package/ios/styles/BlockQuoteStyle.mm +192 -142
  70. package/ios/styles/BoldStyle.mm +96 -62
  71. package/ios/styles/CodeBlockStyle.mm +304 -0
  72. package/ios/styles/H1Style.mm +10 -3
  73. package/ios/styles/H2Style.mm +10 -3
  74. package/ios/styles/H3Style.mm +10 -3
  75. package/ios/styles/HeadingStyleBase.mm +129 -84
  76. package/ios/styles/ImageStyle.mm +160 -0
  77. package/ios/styles/InlineCodeStyle.mm +149 -84
  78. package/ios/styles/ItalicStyle.mm +77 -51
  79. package/ios/styles/LinkStyle.mm +353 -224
  80. package/ios/styles/MentionStyle.mm +434 -220
  81. package/ios/styles/OrderedListStyle.mm +172 -105
  82. package/ios/styles/StrikethroughStyle.mm +53 -34
  83. package/ios/styles/UnderlineStyle.mm +69 -45
  84. package/ios/styles/UnorderedListStyle.mm +170 -105
  85. package/ios/utils/BaseStyleProtocol.h +3 -2
  86. package/ios/utils/ColorExtension.mm +7 -5
  87. package/ios/utils/FontExtension.mm +42 -27
  88. package/ios/utils/ImageData.h +10 -0
  89. package/ios/utils/ImageData.mm +4 -0
  90. package/ios/utils/LayoutManagerExtension.h +1 -1
  91. package/ios/utils/LayoutManagerExtension.mm +334 -109
  92. package/ios/utils/MentionParams.h +0 -1
  93. package/ios/utils/MentionStyleProps.h +1 -1
  94. package/ios/utils/MentionStyleProps.mm +27 -20
  95. package/ios/utils/OccurenceUtils.h +42 -38
  96. package/ios/utils/OccurenceUtils.mm +177 -107
  97. package/ios/utils/ParagraphAttributesUtils.h +6 -1
  98. package/ios/utils/ParagraphAttributesUtils.mm +152 -41
  99. package/ios/utils/ParagraphsUtils.h +2 -1
  100. package/ios/utils/ParagraphsUtils.mm +40 -26
  101. package/ios/utils/StringExtension.h +1 -1
  102. package/ios/utils/StringExtension.mm +19 -16
  103. package/ios/utils/StyleHeaders.h +35 -11
  104. package/ios/utils/TextInsertionUtils.h +13 -2
  105. package/ios/utils/TextInsertionUtils.mm +38 -20
  106. package/ios/utils/WordsUtils.h +2 -1
  107. package/ios/utils/WordsUtils.mm +32 -22
  108. package/ios/utils/ZeroWidthSpaceUtils.h +3 -1
  109. package/ios/utils/ZeroWidthSpaceUtils.mm +153 -75
  110. package/lib/module/EnrichedTextInput.js +41 -3
  111. package/lib/module/EnrichedTextInput.js.map +1 -1
  112. package/lib/module/EnrichedTextInputNativeComponent.ts +17 -5
  113. package/lib/module/normalizeHtmlStyle.js +0 -4
  114. package/lib/module/normalizeHtmlStyle.js.map +1 -1
  115. package/lib/typescript/src/EnrichedTextInput.d.ts +2 -5
  116. package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
  117. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +7 -5
  118. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
  119. package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +1 -1
  120. package/package.json +8 -1
  121. package/src/EnrichedTextInput.tsx +48 -7
  122. package/src/EnrichedTextInputNativeComponent.ts +17 -5
  123. package/src/normalizeHtmlStyle.ts +0 -4
@@ -1,19 +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
+ }
21
+
22
+ + (BOOL)isParagraphStyle {
23
+ return NO;
24
+ }
17
25
 
18
26
  - (instancetype)initWithInput:(id)input {
19
27
  self = [super init];
@@ -25,7 +33,7 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
25
33
  // no-op for links
26
34
  }
27
35
 
28
- - (void)addAttributes:(NSRange)range {
36
+ - (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
29
37
  // no-op for links
30
38
  }
31
39
 
@@ -37,25 +45,39 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
37
45
  - (void)removeAttributes:(NSRange)range {
38
46
  NSArray<StylePair *> *links = [self findAllOccurences:range];
39
47
  [_input->textView.textStorage beginEditing];
40
- for(StylePair *pair in links) {
41
- NSRange linkRange = [self getFullLinkRangeAt:[pair.rangeValue rangeValue].location];
42
- [_input->textView.textStorage removeAttribute:ManualLinkAttributeName range:linkRange];
43
- [_input->textView.textStorage removeAttribute:AutomaticLinkAttributeName range:linkRange];
44
- [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName value:[_input->config primaryColor] range:linkRange];
45
- [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName value:[_input->config primaryColor] range:linkRange];
46
- [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName value:[_input->config primaryColor] range:linkRange];
47
- if([_input->config linkDecorationLine] == DecorationUnderline) {
48
- [_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];
49
68
  }
50
69
  }
51
70
  [_input->textView.textStorage endEditing];
52
-
71
+
53
72
  // adjust typing attributes as well
54
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
55
- newTypingAttrs[NSForegroundColorAttributeName] = [_input->config primaryColor];
73
+ NSMutableDictionary *newTypingAttrs =
74
+ [_input->textView.typingAttributes mutableCopy];
75
+ newTypingAttrs[NSForegroundColorAttributeName] =
76
+ [_input->config primaryColor];
56
77
  newTypingAttrs[NSUnderlineColorAttributeName] = [_input->config primaryColor];
57
- newTypingAttrs[NSStrikethroughColorAttributeName] = [_input->config primaryColor];
58
- if([_input->config linkDecorationLine] == DecorationUnderline) {
78
+ newTypingAttrs[NSStrikethroughColorAttributeName] =
79
+ [_input->config primaryColor];
80
+ if ([_input->config linkDecorationLine] == DecorationUnderline) {
59
81
  [newTypingAttrs removeObjectForKey:NSUnderlineStyleAttributeName];
60
82
  }
61
83
  _input->textView.typingAttributes = newTypingAttrs;
@@ -63,41 +85,56 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
63
85
 
64
86
  // used for conflicts, we have to remove the whole link
65
87
  - (void)removeTypingAttributes {
66
- NSRange linkRange = [self getFullLinkRangeAt:_input->textView.selectedRange.location];
88
+ NSRange linkRange =
89
+ [self getFullLinkRangeAt:_input->textView.selectedRange.location];
67
90
  [_input->textView.textStorage beginEditing];
68
- [_input->textView.textStorage removeAttribute:ManualLinkAttributeName range:linkRange];
69
- [_input->textView.textStorage removeAttribute:AutomaticLinkAttributeName range:linkRange];
70
- [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName value:[_input->config primaryColor] range:linkRange];
71
- [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName value:[_input->config primaryColor] range:linkRange];
72
- [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName value:[_input->config primaryColor] range:linkRange];
73
- if([_input->config linkDecorationLine] == DecorationUnderline) {
74
- [_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];
75
107
  }
76
108
  [_input->textView.textStorage endEditing];
77
-
109
+
78
110
  // adjust typing attributes as well
79
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
80
- newTypingAttrs[NSForegroundColorAttributeName] = [_input->config primaryColor];
111
+ NSMutableDictionary *newTypingAttrs =
112
+ [_input->textView.typingAttributes mutableCopy];
113
+ newTypingAttrs[NSForegroundColorAttributeName] =
114
+ [_input->config primaryColor];
81
115
  newTypingAttrs[NSUnderlineColorAttributeName] = [_input->config primaryColor];
82
- newTypingAttrs[NSStrikethroughColorAttributeName] = [_input->config primaryColor];
83
- if([_input->config linkDecorationLine] == DecorationUnderline) {
116
+ newTypingAttrs[NSStrikethroughColorAttributeName] =
117
+ [_input->config primaryColor];
118
+ if ([_input->config linkDecorationLine] == DecorationUnderline) {
84
119
  [newTypingAttrs removeObjectForKey:NSUnderlineStyleAttributeName];
85
120
  }
86
121
  _input->textView.typingAttributes = newTypingAttrs;
87
122
  }
88
123
 
89
- - (BOOL)styleCondition:(id _Nullable)value :(NSRange)range {
124
+ - (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
90
125
  NSString *linkValue = (NSString *)value;
91
126
  return linkValue != nullptr;
92
127
  }
93
128
 
94
129
  - (BOOL)detectStyle:(NSRange)range {
95
- if(range.length >= 1) {
96
- BOOL onlyLinks = [OccurenceUtils detectMultiple:@[ManualLinkAttributeName, AutomaticLinkAttributeName] withInput:_input inRange:range
97
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
98
- return [self styleCondition:value :range];
99
- }
100
- ];
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
+ }];
101
138
  return onlyLinks ? [self isSingleLinkIn:range] : NO;
102
139
  } else {
103
140
  return [self getLinkDataAt:range.location] != nullptr;
@@ -105,67 +142,90 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
105
142
  }
106
143
 
107
144
  - (BOOL)anyOccurence:(NSRange)range {
108
- return [OccurenceUtils anyMultiple:@[ManualLinkAttributeName, AutomaticLinkAttributeName] withInput:_input inRange:range
109
- withCondition:^BOOL(id _Nullable value, NSRange range) {
110
- return [self styleCondition:value :range];
111
- }
112
- ];
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
+ }];
113
152
  }
114
153
 
115
154
  - (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
116
- return [OccurenceUtils allMultiple:@[ManualLinkAttributeName, AutomaticLinkAttributeName] withInput:_input inRange:range
117
- withCondition:^BOOL(id _Nullable value, NSRange range) {
118
- return [self styleCondition:value :range];
119
- }
120
- ];
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
+ }];
121
162
  }
122
163
 
123
164
  // MARK: - Public non-standard methods
124
165
 
125
- - (void)addLink:(NSString*)text url:(NSString*)url range:(NSRange)range manual:(BOOL)manual {
126
- NSString *currentText = [_input->textView.textStorage.string substringWithRange:range];
127
-
128
- 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];
129
176
  newAttrs[NSForegroundColorAttributeName] = [_input->config linkColor];
130
177
  newAttrs[NSUnderlineColorAttributeName] = [_input->config linkColor];
131
178
  newAttrs[NSStrikethroughColorAttributeName] = [_input->config linkColor];
132
- if([_input->config linkDecorationLine] == DecorationUnderline) {
179
+ if ([_input->config linkDecorationLine] == DecorationUnderline) {
133
180
  newAttrs[NSUnderlineStyleAttributeName] = @(NSUnderlineStyleSingle);
134
181
  }
135
- if(manual) {
182
+ if (manual) {
136
183
  newAttrs[ManualLinkAttributeName] = [url copy];
137
184
  } else {
138
185
  newAttrs[AutomaticLinkAttributeName] = [url copy];
139
186
  }
140
-
141
- if(range.length == 0) {
187
+
188
+ if (range.length == 0) {
142
189
  // insert link
143
- [TextInsertionUtils insertText:text at:range.location additionalAttributes:newAttrs input:_input withSelection:YES];
144
- } 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]) {
145
196
  // apply link attributes
146
197
  [_input->textView.textStorage addAttributes:newAttrs range:range];
147
- // TextInsertionUtils take care of the selection but here we have to manually set it behind the link
148
- // ONLY with manual links, automatic ones don't need the selection fix
149
- 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) {
150
202
  [_input->textView reactFocus];
151
- _input->textView.selectedRange = NSMakeRange(range.location + text.length, 0);
203
+ _input->textView.selectedRange =
204
+ NSMakeRange(range.location + text.length, 0);
152
205
  }
153
206
  } else {
154
207
  // replace text with link
155
- [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];
156
213
  }
157
-
214
+
158
215
  // mandatory connected links check
159
- NSDictionary *currentWord = [WordsUtils getCurrentWord:_input->textView.textStorage.string range:_input->textView.selectedRange];
160
- if(currentWord != nullptr) {
216
+ NSDictionary *currentWord =
217
+ [WordsUtils getCurrentWord:_input->textView.textStorage.string
218
+ range:_input->textView.selectedRange];
219
+ if (currentWord != nullptr) {
161
220
  // get word properties
162
221
  NSString *wordText = (NSString *)[currentWord objectForKey:@"word"];
163
222
  NSValue *wordRangeValue = (NSValue *)[currentWord objectForKey:@"range"];
164
- if(wordText != nullptr && wordRangeValue != nullptr) {
165
- [self removeConnectedLinksIfNeeded:wordText range:[wordRangeValue rangeValue]];
223
+ if (wordText != nullptr && wordRangeValue != nullptr) {
224
+ [self removeConnectedLinksIfNeeded:wordText
225
+ range:[wordRangeValue rangeValue]];
166
226
  }
167
227
  }
168
-
228
+
169
229
  [self manageLinkTypingAttributes];
170
230
  }
171
231
 
@@ -174,36 +234,37 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
174
234
  NSRange manualLinkRange = NSMakeRange(0, 0);
175
235
  NSRange automaticLinkRange = NSMakeRange(0, 0);
176
236
  NSRange inputRange = NSMakeRange(0, _input->textView.textStorage.length);
177
-
237
+
178
238
  // don't search at the very end of input
179
239
  NSUInteger searchLocation = location;
180
- if(searchLocation == _input->textView.textStorage.length) {
240
+ if (searchLocation == _input->textView.textStorage.length) {
181
241
  return nullptr;
182
242
  }
183
-
184
- NSString *manualUrl = [_input->textView.textStorage
185
- attribute:ManualLinkAttributeName
186
- atIndex:searchLocation
187
- longestEffectiveRange: &manualLinkRange
188
- inRange:inputRange
189
- ];
190
- NSString *automaticUrl = [_input->textView.textStorage
191
- attribute:AutomaticLinkAttributeName
192
- atIndex:searchLocation
193
- longestEffectiveRange: &automaticLinkRange
194
- inRange:inputRange
195
- ];
196
-
197
- 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)) {
198
257
  return nullptr;
199
258
  }
200
-
259
+
201
260
  NSString *linkUrl = manualUrl == nullptr ? automaticUrl : manualUrl;
202
- NSRange linkRange = manualUrl == nullptr ? automaticLinkRange : manualLinkRange;
203
-
261
+ NSRange linkRange =
262
+ manualUrl == nullptr ? automaticLinkRange : manualLinkRange;
263
+
204
264
  LinkData *data = [[LinkData alloc] init];
205
265
  data.url = linkUrl;
206
- data.text = [_input->textView.textStorage.string substringWithRange:linkRange];
266
+ data.text =
267
+ [_input->textView.textStorage.string substringWithRange:linkRange];
207
268
  return data;
208
269
  }
209
270
 
@@ -212,64 +273,71 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
212
273
  NSRange manualLinkRange = NSMakeRange(0, 0);
213
274
  NSRange automaticLinkRange = NSMakeRange(0, 0);
214
275
  NSRange inputRange = NSMakeRange(0, _input->textView.textStorage.length);
215
-
276
+
216
277
  // get the previous index if possible when at the very end of input
217
278
  NSUInteger searchLocation = location;
218
- if(searchLocation == _input->textView.textStorage.length) {
219
- if(searchLocation == 0) {
279
+ if (searchLocation == _input->textView.textStorage.length) {
280
+ if (searchLocation == 0) {
220
281
  return NSMakeRange(0, 0);
221
282
  } else {
222
283
  searchLocation = searchLocation - 1;
223
284
  }
224
285
  }
225
-
226
- NSString *manualLink = [_input->textView.textStorage
227
- attribute:ManualLinkAttributeName
228
- atIndex:searchLocation
229
- longestEffectiveRange: &manualLinkRange
230
- inRange:inputRange
231
- ];
232
- NSString *automaticLink = [_input->textView.textStorage
233
- attribute:AutomaticLinkAttributeName
234
- atIndex:searchLocation
235
- longestEffectiveRange: &automaticLinkRange
236
- inRange:inputRange
237
- ];
238
-
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
+
239
298
  return manualLink == nullptr
240
- ? automaticLink == nullptr ? NSMakeRange(0, 0) : automaticLinkRange
241
- : manualLinkRange;
299
+ ? automaticLink == nullptr ? NSMakeRange(0, 0) : automaticLinkRange
300
+ : manualLinkRange;
242
301
  }
243
302
 
244
303
  - (void)manageLinkTypingAttributes {
245
- // 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
246
306
  BOOL removeAttrs = NO;
247
-
248
- if(_input->textView.selectedRange.length == 0) {
307
+
308
+ if (_input->textView.selectedRange.length == 0) {
249
309
  // check before
250
- if(_input->textView.selectedRange.location >= 1) {
251
- 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)]) {
252
314
  removeAttrs = YES;
253
315
  }
254
316
  }
255
317
  // check after
256
- if(_input->textView.selectedRange.location < _input->textView.textStorage.length) {
257
- 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)]) {
258
322
  removeAttrs = YES;
259
323
  }
260
324
  }
261
325
  } else {
262
- if([self anyOccurence:_input->textView.selectedRange]) {
326
+ if ([self anyOccurence:_input->textView.selectedRange]) {
263
327
  removeAttrs = YES;
264
328
  }
265
329
  }
266
-
267
- if(removeAttrs) {
268
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
269
- newTypingAttrs[NSForegroundColorAttributeName] = [_input->config primaryColor];
270
- newTypingAttrs[NSUnderlineColorAttributeName] = [_input->config primaryColor];
271
- newTypingAttrs[NSStrikethroughColorAttributeName] = [_input->config primaryColor];
272
- 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) {
273
341
  [newTypingAttrs removeObjectForKey:NSUnderlineStyleAttributeName];
274
342
  }
275
343
  _input->textView.typingAttributes = newTypingAttrs;
@@ -278,78 +346,106 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
278
346
 
279
347
  // handles detecting and removing automatic links
280
348
  - (void)handleAutomaticLinks:(NSString *)word inRange:(NSRange)wordRange {
281
- InlineCodeStyle *inlineCodeStyle = [_input->stylesDict objectForKey:@([InlineCodeStyle getStyleType])];
282
- MentionStyle *mentionStyle = [_input->stylesDict objectForKey:@([MentionStyle getStyleType])];
283
-
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
+
284
356
  if (inlineCodeStyle == nullptr || mentionStyle == nullptr) {
285
357
  return;
286
358
  }
287
-
359
+
288
360
  // we don't recognize links along mentions
289
361
  if ([mentionStyle anyOccurence:wordRange]) {
290
362
  return;
291
363
  }
292
-
364
+
293
365
  // we don't recognize links among inline code
294
366
  if ([inlineCodeStyle anyOccurence:wordRange]) {
295
367
  return;
296
368
  }
297
-
369
+
370
+ // we don't recognize links in codeblocks
371
+ if ([codeBlockStyle anyOccurence:wordRange]) {
372
+ return;
373
+ }
374
+
298
375
  // remove connected different links
299
376
  [self removeConnectedLinksIfNeeded:word range:wordRange];
300
-
377
+
301
378
  // we don't recognize automatic links along manual ones
302
379
  __block BOOL manualLinkPresent = NO;
303
- [_input->textView.textStorage enumerateAttribute:ManualLinkAttributeName inRange:wordRange options:0
304
- usingBlock:^(id value, NSRange range, BOOL *stop) {
305
- NSString *urlValue = (NSString *)value;
306
- if(urlValue != nullptr) {
307
- manualLinkPresent = YES;
308
- *stop = YES;
309
- }
310
- }];
311
- 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) {
312
392
  return;
313
393
  }
314
-
315
- NSRegularExpression *fullRegex = [NSRegularExpression regularExpressionWithPattern:@"http(s)?:\\/\\/www\\.[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"
316
- options:0
317
- error:nullptr
318
- ];
319
- NSRegularExpression *wwwRegex = [NSRegularExpression regularExpressionWithPattern:@"www\\.[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"
320
- options:0
321
- error:nullptr
322
- ];
323
- NSRegularExpression *bareRegex = [NSRegularExpression regularExpressionWithPattern:@"[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)"
324
- options:0
325
- error:nullptr
326
- ];
327
-
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
+
328
412
  NSString *regexPassedUrl = nullptr;
329
-
330
- 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)]) {
331
417
  regexPassedUrl = word;
332
- } 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)]) {
333
421
  regexPassedUrl = word;
334
- } 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)]) {
335
425
  regexPassedUrl = word;
336
426
  } else if ([self anyOccurence:wordRange]) {
337
- // there was some automatic link (because anyOccurence is true and we are sure there are no manual links)
338
- // 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
339
430
  [self removeAttributes:wordRange];
340
431
  }
341
-
342
- if(regexPassedUrl != nullptr) {
432
+
433
+ if (regexPassedUrl != nullptr) {
343
434
  // add style only if needed
344
435
  BOOL addStyle = YES;
345
- if([self detectStyle:wordRange]) {
436
+ if ([self detectStyle:wordRange]) {
346
437
  LinkData *currentData = [self getLinkDataAt:wordRange.location];
347
- if(currentData != nullptr && currentData.url != nullptr && [currentData.url isEqualToString:regexPassedUrl]) {
438
+ if (currentData != nullptr && currentData.url != nullptr &&
439
+ [currentData.url isEqualToString:regexPassedUrl]) {
348
440
  addStyle = NO;
349
441
  }
350
442
  }
351
- if(addStyle) {
352
- [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];
353
449
  // emit onLinkDetected if style was added
354
450
  [_input emitOnLinkDetectedEvent:word url:regexPassedUrl range:wordRange];
355
451
  }
@@ -363,57 +459,83 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
363
459
  __block NSString *manualLinkMaxValue = @"";
364
460
  __block NSInteger manualLinkMinIdx = -1;
365
461
  __block NSInteger manualLinkMaxIdx = -1;
366
-
367
- [_input->textView.textStorage enumerateAttribute:ManualLinkAttributeName inRange:wordRange options:0
368
- usingBlock:^(id value, NSRange range, BOOL *stop) {
369
- NSString *urlValue = (NSString *)value;
370
- if (urlValue != nullptr) {
371
- NSInteger linkMin = range.location;
372
- NSInteger linkMax = range.location + range.length - 1;
373
- if (manualLinkMinIdx == -1 || linkMin < manualLinkMinIdx) {
374
- manualLinkMinIdx = linkMin;
375
- manualLinkMinValue = value;
376
- }
377
- if (manualLinkMaxIdx == -1 || linkMax > manualLinkMaxIdx) {
378
- manualLinkMaxIdx = linkMax;
379
- manualLinkMaxValue = value;
380
- }
381
- }
382
- }];
383
-
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
+
384
483
  // no manual links
385
- if(manualLinkMinIdx == -1 || manualLinkMaxIdx == -1) {
484
+ if (manualLinkMinIdx == -1 || manualLinkMaxIdx == -1) {
386
485
  return;
387
486
  }
388
-
487
+
389
488
  // heuristic for refreshing manual links:
390
489
  // we update the Manual attribute between the bounds of existing ones
391
490
  // we do that only if the bounds point to the same url
392
- // this way manual link gets "extended" only if some characters were added inside it
393
- if([manualLinkMinValue isEqualToString:manualLinkMaxValue]) {
394
- NSRange newRange = NSMakeRange(manualLinkMinIdx, manualLinkMaxIdx - manualLinkMinIdx + 1);
395
- [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName value:[_input->config linkColor] range:newRange];
396
- [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName value:[_input->config linkColor] range:newRange];
397
- [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName value:[_input->config linkColor] range:newRange];
398
- if([_input->config linkDecorationLine] == DecorationUnderline) {
399
- [_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];
400
509
  }
401
- [_input->textView.textStorage addAttribute:ManualLinkAttributeName value:manualLinkMinValue range:newRange];
510
+ [_input->textView.textStorage addAttribute:ManualLinkAttributeName
511
+ value:manualLinkMinValue
512
+ range:newRange];
402
513
  }
403
-
514
+
404
515
  // link typing attributes need to be fixed after these changes
405
516
  [self manageLinkTypingAttributes];
406
517
  }
407
518
 
408
- // replacing whole input (that starts with a link) with a manually typed letter improperly applies link's attributes to all the following text
409
- - (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 {
410
523
  // whole textView range gets replaced with a single letter
411
- 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) {
412
528
  // first character detection is enough for the removal to be done
413
- if([self detectStyle:NSMakeRange(0, 1)]) {
414
- [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)];
415
533
  // do the replacing manually
416
- [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];
417
539
  return YES;
418
540
  }
419
541
  }
@@ -429,32 +551,39 @@ static NSString *const AutomaticLinkAttributeName = @"AutomaticLinkAttributeName
429
551
  }
430
552
 
431
553
  - (void)removeConnectedLinksIfNeeded:(NSString *)word range:(NSRange)wordRange {
432
- BOOL anyAutomatic = [OccurenceUtils any:AutomaticLinkAttributeName withInput:_input inRange:wordRange
433
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
434
- return [self styleCondition:value :range];
435
- }
436
- ];
437
- BOOL anyManual = [OccurenceUtils any:ManualLinkAttributeName withInput:_input inRange:wordRange
438
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
439
- return [self styleCondition:value :range];
440
- }
441
- ];
442
-
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
+
443
569
  // both manual and automatic links are somewhere - delete!
444
- if(anyAutomatic && anyManual) {
570
+ if (anyAutomatic && anyManual) {
445
571
  [self removeAttributes:wordRange];
446
572
  [self manageLinkTypingAttributes];
447
573
  }
448
-
449
- // we are now sure there is only one type of link there - and make sure it covers the whole word
450
- BOOL onlyLinks = [OccurenceUtils detectMultiple:@[ManualLinkAttributeName, AutomaticLinkAttributeName] withInput:_input inRange:wordRange
451
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
452
- return [self styleCondition:value :range];
453
- }
454
- ];
455
-
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
+
456
585
  // only one link might be present!
457
- if(onlyLinks && ![self isSingleLinkIn:wordRange]) {
586
+ if (onlyLinks && ![self isSingleLinkIn:wordRange]) {
458
587
  [self removeAttributes:wordRange];
459
588
  [self manageLinkTypingAttributes];
460
589
  }