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,136 +1,184 @@
1
- #import "StyleHeaders.h"
1
+ #import "ColorExtension.h"
2
2
  #import "EnrichedTextInputView.h"
3
3
  #import "OccurenceUtils.h"
4
4
  #import "ParagraphsUtils.h"
5
+ #import "StyleHeaders.h"
5
6
  #import "TextInsertionUtils.h"
6
- #import "ColorExtension.h"
7
7
 
8
8
  @implementation BlockQuoteStyle {
9
9
  EnrichedTextInputView *_input;
10
+ NSArray *_stylesToExclude;
10
11
  }
11
12
 
12
- + (StyleType)getStyleType { return BlockQuote; }
13
+ + (StyleType)getStyleType {
14
+ return BlockQuote;
15
+ }
16
+
17
+ + (BOOL)isParagraphStyle {
18
+ return YES;
19
+ }
13
20
 
14
21
  - (instancetype)initWithInput:(id)input {
15
22
  self = [super init];
16
23
  _input = (EnrichedTextInputView *)input;
24
+ _stylesToExclude = @[ @(InlineCode), @(Mention), @(Link) ];
17
25
  return self;
18
26
  }
19
27
 
20
28
  - (CGFloat)getHeadIndent {
21
29
  // rectangle width + gap
22
- return [_input->config blockquoteBorderWidth] + [_input->config blockquoteGapWidth];
30
+ return [_input->config blockquoteBorderWidth] +
31
+ [_input->config blockquoteGapWidth];
23
32
  }
24
33
 
25
34
  // the range will already be the full paragraph/s range
26
35
  - (void)applyStyle:(NSRange)range {
27
36
  BOOL isStylePresent = [self detectStyle:range];
28
- if(range.length >= 1) {
29
- isStylePresent ? [self removeAttributes:range] : [self addAttributes:range];
37
+ if (range.length >= 1) {
38
+ isStylePresent ? [self removeAttributes:range]
39
+ : [self addAttributes:range withTypingAttr:YES];
30
40
  } else {
31
41
  isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
32
42
  }
33
43
  }
34
44
 
35
- - (void)addAttributes:(NSRange)range {
36
- NSArray *paragraphs = [ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView range:range];
37
- // if we fill empty lines with zero width spaces, we need to offset later ranges
45
+ - (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
46
+ NSArray *paragraphs =
47
+ [ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView
48
+ range:range];
49
+ // if we fill empty lines with zero width spaces, we need to offset later
50
+ // ranges
38
51
  NSInteger offset = 0;
39
52
  NSRange preModificationRange = _input->textView.selectedRange;
40
-
53
+
41
54
  // to not emit any space filling selection/text changes
42
55
  _input->blockEmitting = YES;
43
-
44
- for(NSValue *value in paragraphs) {
45
- NSRange pRange = NSMakeRange([value rangeValue].location + offset, [value rangeValue].length);
46
-
47
- // length 0 with first line, length 1 and newline with some empty lines in the middle
48
- if(pRange.length == 0 ||
49
- (pRange.length == 1 &&
50
- [[NSCharacterSet newlineCharacterSet] characterIsMember: [_input->textView.textStorage.string characterAtIndex:pRange.location]])
51
- ) {
52
- [TextInsertionUtils insertText:@"\u200B" at:pRange.location additionalAttributes:nullptr input:_input withSelection:NO];
56
+
57
+ for (NSValue *value in paragraphs) {
58
+ NSRange pRange = NSMakeRange([value rangeValue].location + offset,
59
+ [value rangeValue].length);
60
+
61
+ // length 0 with first line, length 1 and newline with some empty lines in
62
+ // the middle
63
+ if (pRange.length == 0 ||
64
+ (pRange.length == 1 &&
65
+ [[NSCharacterSet newlineCharacterSet]
66
+ characterIsMember:[_input->textView.textStorage.string
67
+ characterAtIndex:pRange.location]])) {
68
+ [TextInsertionUtils insertText:@"\u200B"
69
+ at:pRange.location
70
+ additionalAttributes:nullptr
71
+ input:_input
72
+ withSelection:NO];
53
73
  pRange = NSMakeRange(pRange.location, pRange.length + 1);
54
74
  offset += 1;
55
75
  }
56
-
57
- [_input->textView.textStorage enumerateAttribute:NSParagraphStyleAttributeName inRange:pRange options:0
58
- usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
59
- NSMutableParagraphStyle *pStyle = [(NSParagraphStyle *)value mutableCopy];
60
- pStyle.headIndent = [self getHeadIndent];
61
- pStyle.firstLineHeadIndent = [self getHeadIndent];
62
- [_input->textView.textStorage addAttribute:NSParagraphStyleAttributeName value:pStyle range:range];
63
- }
64
- ];
76
+
77
+ [_input->textView.textStorage
78
+ enumerateAttribute:NSParagraphStyleAttributeName
79
+ inRange:pRange
80
+ options:0
81
+ usingBlock:^(id _Nullable value, NSRange range,
82
+ BOOL *_Nonnull stop) {
83
+ NSMutableParagraphStyle *pStyle =
84
+ [(NSParagraphStyle *)value mutableCopy];
85
+ pStyle.headIndent = [self getHeadIndent];
86
+ pStyle.firstLineHeadIndent = [self getHeadIndent];
87
+ [_input->textView.textStorage
88
+ addAttribute:NSParagraphStyleAttributeName
89
+ value:pStyle
90
+ range:range];
91
+ }];
65
92
  }
66
-
93
+
67
94
  // back to emitting
68
95
  _input->blockEmitting = NO;
69
-
70
- if(preModificationRange.length == 0) {
71
- // fix selection if only one line was possibly made a list and filled with a space
96
+
97
+ if (preModificationRange.length == 0) {
98
+ // fix selection if only one line was possibly made a list and filled with a
99
+ // space
72
100
  _input->textView.selectedRange = preModificationRange;
73
101
  } else {
74
102
  // in other cases, fix the selection with newly made offsets
75
- _input->textView.selectedRange = NSMakeRange(preModificationRange.location, preModificationRange.length + offset);
103
+ _input->textView.selectedRange = NSMakeRange(
104
+ preModificationRange.location, preModificationRange.length + offset);
76
105
  }
77
-
106
+
78
107
  // also add typing attributes
79
- NSMutableDictionary *typingAttrs = [_input->textView.typingAttributes mutableCopy];
80
- NSMutableParagraphStyle *pStyle = [typingAttrs[NSParagraphStyleAttributeName] mutableCopy];
81
- pStyle.headIndent = [self getHeadIndent];
82
- pStyle.firstLineHeadIndent = [self getHeadIndent];
83
- typingAttrs[NSParagraphStyleAttributeName] = pStyle;
84
- _input->textView.typingAttributes = typingAttrs;
108
+ if (withTypingAttr) {
109
+ NSMutableDictionary *typingAttrs =
110
+ [_input->textView.typingAttributes mutableCopy];
111
+ NSMutableParagraphStyle *pStyle =
112
+ [typingAttrs[NSParagraphStyleAttributeName] mutableCopy];
113
+ pStyle.headIndent = [self getHeadIndent];
114
+ pStyle.firstLineHeadIndent = [self getHeadIndent];
115
+ typingAttrs[NSParagraphStyleAttributeName] = pStyle;
116
+ _input->textView.typingAttributes = typingAttrs;
117
+ }
85
118
  }
86
119
 
87
120
  // does pretty much the same as addAttributes
88
121
  - (void)addTypingAttributes {
89
- [self addAttributes:_input->textView.selectedRange];
122
+ [self addAttributes:_input->textView.selectedRange withTypingAttr:YES];
90
123
  }
91
124
 
92
125
  - (void)removeAttributes:(NSRange)range {
93
- NSArray *paragraphs = [ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView range:range];
94
-
95
- for(NSValue *value in paragraphs) {
126
+ NSArray *paragraphs =
127
+ [ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView
128
+ range:range];
129
+
130
+ for (NSValue *value in paragraphs) {
96
131
  NSRange pRange = [value rangeValue];
97
- [_input->textView.textStorage enumerateAttribute:NSParagraphStyleAttributeName inRange:pRange options:0
98
- usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
99
- NSMutableParagraphStyle *pStyle = [(NSParagraphStyle *)value mutableCopy];
100
- pStyle.headIndent = 0;
101
- pStyle.firstLineHeadIndent = 0;
102
- [_input->textView.textStorage addAttribute:NSParagraphStyleAttributeName value:pStyle range:range];
103
- }
104
- ];
132
+ [_input->textView.textStorage
133
+ enumerateAttribute:NSParagraphStyleAttributeName
134
+ inRange:pRange
135
+ options:0
136
+ usingBlock:^(id _Nullable value, NSRange range,
137
+ BOOL *_Nonnull stop) {
138
+ NSMutableParagraphStyle *pStyle =
139
+ [(NSParagraphStyle *)value mutableCopy];
140
+ pStyle.headIndent = 0;
141
+ pStyle.firstLineHeadIndent = 0;
142
+ [_input->textView.textStorage
143
+ addAttribute:NSParagraphStyleAttributeName
144
+ value:pStyle
145
+ range:range];
146
+ }];
105
147
  }
106
-
148
+
107
149
  // also remove typing attributes
108
- NSMutableDictionary *typingAttrs = [_input->textView.typingAttributes mutableCopy];
109
- NSMutableParagraphStyle *pStyle = [typingAttrs[NSParagraphStyleAttributeName] mutableCopy];
150
+ NSMutableDictionary *typingAttrs =
151
+ [_input->textView.typingAttributes mutableCopy];
152
+ NSMutableParagraphStyle *pStyle =
153
+ [typingAttrs[NSParagraphStyleAttributeName] mutableCopy];
110
154
  pStyle.headIndent = 0;
111
155
  pStyle.firstLineHeadIndent = 0;
112
156
  typingAttrs[NSParagraphStyleAttributeName] = pStyle;
113
157
  _input->textView.typingAttributes = typingAttrs;
114
158
  }
115
159
 
116
- // needed for the sake of style conflicts, needs to do exactly the same as removeAttribtues
160
+ // needed for the sake of style conflicts, needs to do exactly the same as
161
+ // removeAttribtues
117
162
  - (void)removeTypingAttributes {
118
163
  [self removeAttributes:_input->textView.selectedRange];
119
164
  }
120
165
 
121
166
  - (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text {
122
- if([self detectStyle:_input->textView.selectedRange] && text.length == 0) {
167
+ if ([self detectStyle:_input->textView.selectedRange] && text.length == 0) {
123
168
  // backspace while the style is active
124
-
125
- NSRange paragraphRange = [_input->textView.textStorage.string paragraphRangeForRange:_input->textView.selectedRange];
126
-
127
- if(NSEqualRanges(_input->textView.selectedRange, NSMakeRange(0, 0))) {
169
+
170
+ NSRange paragraphRange = [_input->textView.textStorage.string
171
+ paragraphRangeForRange:_input->textView.selectedRange];
172
+
173
+ if (NSEqualRanges(_input->textView.selectedRange, NSMakeRange(0, 0))) {
128
174
  // a backspace on the very first input's line quote
129
- // it doesn't run textVieDidChange so we need to manually remove attributes
175
+ // it doesn't run textVieDidChange so we need to manually remove
176
+ // attributes
130
177
  [self removeAttributes:paragraphRange];
131
178
  return YES;
132
- } else if(range.location == paragraphRange.location - 1) {
133
- // same case in other lines; here, the removed range location will be exactly 1 less than paragraph range location
179
+ } else if (range.location == paragraphRange.location - 1) {
180
+ // same case in other lines; here, the removed range location will be
181
+ // exactly 1 less than paragraph range location
134
182
  [self removeAttributes:paragraphRange];
135
183
  return YES;
136
184
  }
@@ -138,104 +186,106 @@
138
186
  return NO;
139
187
  }
140
188
 
141
- - (BOOL)styleCondition:(id _Nullable)value :(NSRange)range {
189
+ - (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
142
190
  NSParagraphStyle *pStyle = (NSParagraphStyle *)value;
143
- return pStyle != nullptr && pStyle.headIndent == [self getHeadIndent] && pStyle.firstLineHeadIndent == [self getHeadIndent] && pStyle.textLists.count == 0;
191
+ return pStyle != nullptr && pStyle.headIndent == [self getHeadIndent] &&
192
+ pStyle.firstLineHeadIndent == [self getHeadIndent] &&
193
+ pStyle.textLists.count == 0;
144
194
  }
145
195
 
146
196
  - (BOOL)detectStyle:(NSRange)range {
147
- if(range.length >= 1) {
148
- return [OccurenceUtils detect:NSParagraphStyleAttributeName withInput:_input inRange:range
149
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
150
- return [self styleCondition:value :range];
151
- }
152
- ];
197
+ if (range.length >= 1) {
198
+ return [OccurenceUtils detect:NSParagraphStyleAttributeName
199
+ withInput:_input
200
+ inRange:range
201
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
202
+ return [self styleCondition:value:range];
203
+ }];
153
204
  } else {
154
- return [OccurenceUtils detect:NSParagraphStyleAttributeName withInput:_input atIndex:range.location checkPrevious:YES
155
- withCondition:^BOOL(id _Nullable value, NSRange range) {
156
- return [self styleCondition:value :range];
157
- }
158
- ];
205
+ return [OccurenceUtils detect:NSParagraphStyleAttributeName
206
+ withInput:_input
207
+ atIndex:range.location
208
+ checkPrevious:YES
209
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
210
+ return [self styleCondition:value:range];
211
+ }];
159
212
  }
160
213
  }
161
214
 
162
215
  - (BOOL)anyOccurence:(NSRange)range {
163
- return [OccurenceUtils any:NSParagraphStyleAttributeName withInput:_input inRange:range
164
- withCondition:^BOOL(id _Nullable value, NSRange range) {
165
- return [self styleCondition:value :range];
166
- }
167
- ];
216
+ return [OccurenceUtils any:NSParagraphStyleAttributeName
217
+ withInput:_input
218
+ inRange:range
219
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
220
+ return [self styleCondition:value:range];
221
+ }];
168
222
  }
169
223
 
170
224
  - (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
171
- return [OccurenceUtils all:NSParagraphStyleAttributeName withInput:_input inRange:range
172
- withCondition:^BOOL(id _Nullable value, NSRange range) {
173
- return [self styleCondition:value :range];
174
- }
175
- ];
176
- }
177
-
178
- // gets ranges that aren't link, mention or inline code
179
- - (NSArray *)getProperColorRangesIn:(NSRange)range {
180
- LinkStyle *linkStyle = _input->stylesDict[@([LinkStyle getStyleType])];
181
- MentionStyle *mentionStyle = _input->stylesDict[@([MentionStyle getStyleType])];
182
- InlineCodeStyle *codeStyle = _input->stylesDict[@([InlineCodeStyle getStyleType])];
183
-
184
- NSMutableArray *newRanges = [[NSMutableArray alloc] init];
185
- int lastRangeLocation = range.location;
186
-
187
- for(int i = range.location; i < range.location + range.length; i++) {
188
- NSRange currentRange = NSMakeRange(i, 1);
189
- if([linkStyle detectStyle:currentRange] || [mentionStyle detectStyle:currentRange] || [codeStyle detectStyle:currentRange]) {
190
- if(i - lastRangeLocation > 0) {
191
- [newRanges addObject:[NSValue valueWithRange:NSMakeRange(lastRangeLocation, i - lastRangeLocation)]];
192
- }
193
- lastRangeLocation = i+1;
194
- }
195
- }
196
- if(lastRangeLocation < range.location + range.length) {
197
- [newRanges addObject:[NSValue valueWithRange:NSMakeRange(lastRangeLocation, range.location + range.length - lastRangeLocation)]];
198
- }
199
-
200
- return newRanges;
225
+ return [OccurenceUtils all:NSParagraphStyleAttributeName
226
+ withInput:_input
227
+ inRange:range
228
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
229
+ return [self styleCondition:value:range];
230
+ }];
201
231
  }
202
232
 
203
233
  // general checkup correcting blockquote color
204
- // since links, mentions and inline code affects coloring, the checkup gets done only outside of them
234
+ // since links, mentions and inline code affects coloring, the checkup gets done
235
+ // only outside of them
205
236
  - (void)manageBlockquoteColor {
206
- if([[_input->config blockquoteColor] isEqualToColor:[_input->config primaryColor]]) {
237
+ if ([[_input->config blockquoteColor]
238
+ isEqualToColor:[_input->config primaryColor]]) {
207
239
  return;
208
240
  }
209
-
210
- NSRange wholeRange = NSMakeRange(0, _input->textView.textStorage.string.length);
211
-
212
- NSArray *paragraphs = [ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView range:wholeRange];
213
- for(NSValue *pValue in paragraphs) {
241
+
242
+ NSRange wholeRange =
243
+ NSMakeRange(0, _input->textView.textStorage.string.length);
244
+
245
+ NSArray *paragraphs =
246
+ [ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView
247
+ range:wholeRange];
248
+ for (NSValue *pValue in paragraphs) {
214
249
  NSRange paragraphRange = [pValue rangeValue];
215
- NSArray *properRanges = [self getProperColorRangesIn:paragraphRange];
216
-
217
- for(NSValue *value in properRanges) {
250
+ NSArray *properRanges = [OccurenceUtils getRangesWithout:_stylesToExclude
251
+ withInput:_input
252
+ inRange:paragraphRange];
253
+
254
+ for (NSValue *value in properRanges) {
218
255
  NSRange currRange = [value rangeValue];
219
256
  BOOL selfDetected = [self detectStyle:currRange];
220
-
221
- [_input->textView.textStorage enumerateAttribute:NSForegroundColorAttributeName inRange:currRange options:0
222
- usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
223
- UIColor *newColor = nullptr;
224
- BOOL colorApplied = [(UIColor *)value isEqualToColor:[_input->config blockquoteColor]];
225
-
226
- if(colorApplied && !selfDetected) {
227
- newColor = [_input->config primaryColor];
228
- } else if(!colorApplied && selfDetected) {
229
- newColor = [_input->config blockquoteColor];
230
- }
231
-
232
- if(newColor != nullptr) {
233
- [_input->textView.textStorage addAttribute:NSForegroundColorAttributeName value:newColor range:currRange];
234
- [_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName value:newColor range:currRange];
235
- [_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName value:newColor range:currRange];
236
- }
237
- }
238
- ];
257
+
258
+ [_input->textView.textStorage
259
+ enumerateAttribute:NSForegroundColorAttributeName
260
+ inRange:currRange
261
+ options:0
262
+ usingBlock:^(id _Nullable value, NSRange range,
263
+ BOOL *_Nonnull stop) {
264
+ UIColor *newColor = nullptr;
265
+ BOOL colorApplied = [(UIColor *)value
266
+ isEqualToColor:[_input->config blockquoteColor]];
267
+
268
+ if (colorApplied && !selfDetected) {
269
+ newColor = [_input->config primaryColor];
270
+ } else if (!colorApplied && selfDetected) {
271
+ newColor = [_input->config blockquoteColor];
272
+ }
273
+
274
+ if (newColor != nullptr) {
275
+ [_input->textView.textStorage
276
+ addAttribute:NSForegroundColorAttributeName
277
+ value:newColor
278
+ range:currRange];
279
+ [_input->textView.textStorage
280
+ addAttribute:NSUnderlineColorAttributeName
281
+ value:newColor
282
+ range:currRange];
283
+ [_input->textView.textStorage
284
+ addAttribute:NSStrikethroughColorAttributeName
285
+ value:newColor
286
+ range:currRange];
287
+ }
288
+ }];
239
289
  }
240
290
  }
241
291
  }
@@ -1,13 +1,19 @@
1
- #import "StyleHeaders.h"
2
1
  #import "EnrichedTextInputView.h"
3
2
  #import "FontExtension.h"
4
3
  #import "OccurenceUtils.h"
4
+ #import "StyleHeaders.h"
5
5
 
6
6
  @implementation BoldStyle {
7
7
  EnrichedTextInputView *_input;
8
8
  }
9
9
 
10
- + (StyleType)getStyleType { return Bold; }
10
+ + (StyleType)getStyleType {
11
+ return Bold;
12
+ }
13
+
14
+ + (BOOL)isParagraphStyle {
15
+ return NO;
16
+ }
11
17
 
12
18
  - (instancetype)initWithInput:(id)input {
13
19
  self = [super init];
@@ -17,31 +23,39 @@
17
23
 
18
24
  - (void)applyStyle:(NSRange)range {
19
25
  BOOL isStylePresent = [self detectStyle:range];
20
- if(range.length >= 1) {
21
- isStylePresent ? [self removeAttributes:range] : [self addAttributes:range];
26
+ if (range.length >= 1) {
27
+ isStylePresent ? [self removeAttributes:range]
28
+ : [self addAttributes:range withTypingAttr:YES];
22
29
  } else {
23
30
  isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
24
31
  }
25
32
  }
26
33
 
27
- - (void)addAttributes:(NSRange)range {
34
+ - (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
28
35
  [_input->textView.textStorage beginEditing];
29
- [_input->textView.textStorage enumerateAttribute:NSFontAttributeName inRange:range options:0
30
- usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
31
- UIFont *font = (UIFont *)value;
32
- if(font != nullptr) {
33
- UIFont *newFont = [font setBold];
34
- [_input->textView.textStorage addAttribute:NSFontAttributeName value:newFont range:range];
35
- }
36
- }
37
- ];
36
+ [_input->textView.textStorage
37
+ enumerateAttribute:NSFontAttributeName
38
+ inRange:range
39
+ options:0
40
+ usingBlock:^(id _Nullable value, NSRange range,
41
+ BOOL *_Nonnull stop) {
42
+ UIFont *font = (UIFont *)value;
43
+ if (font != nullptr) {
44
+ UIFont *newFont = [font setBold];
45
+ [_input->textView.textStorage addAttribute:NSFontAttributeName
46
+ value:newFont
47
+ range:range];
48
+ }
49
+ }];
38
50
  [_input->textView.textStorage endEditing];
39
51
  }
40
52
 
41
53
  - (void)addTypingAttributes {
42
- UIFont *currentFontAttr = (UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
43
- if(currentFontAttr != nullptr) {
44
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
54
+ UIFont *currentFontAttr =
55
+ (UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
56
+ if (currentFontAttr != nullptr) {
57
+ NSMutableDictionary *newTypingAttrs =
58
+ [_input->textView.typingAttributes mutableCopy];
45
59
  newTypingAttrs[NSFontAttributeName] = [currentFontAttr setBold];
46
60
  _input->textView.typingAttributes = newTypingAttrs;
47
61
  }
@@ -49,77 +63,97 @@
49
63
 
50
64
  - (void)removeAttributes:(NSRange)range {
51
65
  [_input->textView.textStorage beginEditing];
52
- [_input->textView.textStorage enumerateAttribute:NSFontAttributeName inRange:range options:0
53
- usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
54
- UIFont *font = (UIFont *)value;
55
- if(font != nullptr) {
56
- UIFont *newFont = [font removeBold];
57
- [_input->textView.textStorage addAttribute:NSFontAttributeName value:newFont range:range];
58
- }
59
- }
60
- ];
66
+ [_input->textView.textStorage
67
+ enumerateAttribute:NSFontAttributeName
68
+ inRange:range
69
+ options:0
70
+ usingBlock:^(id _Nullable value, NSRange range,
71
+ BOOL *_Nonnull stop) {
72
+ UIFont *font = (UIFont *)value;
73
+ if (font != nullptr) {
74
+ UIFont *newFont = [font removeBold];
75
+ [_input->textView.textStorage addAttribute:NSFontAttributeName
76
+ value:newFont
77
+ range:range];
78
+ }
79
+ }];
61
80
  [_input->textView.textStorage endEditing];
62
81
  }
63
82
 
64
83
  - (void)removeTypingAttributes {
65
- UIFont *currentFontAttr = (UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
66
- if(currentFontAttr != nullptr) {
67
- NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
84
+ UIFont *currentFontAttr =
85
+ (UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
86
+ if (currentFontAttr != nullptr) {
87
+ NSMutableDictionary *newTypingAttrs =
88
+ [_input->textView.typingAttributes mutableCopy];
68
89
  newTypingAttrs[NSFontAttributeName] = [currentFontAttr removeBold];
69
90
  _input->textView.typingAttributes = newTypingAttrs;
70
91
  }
71
92
  }
72
93
 
73
94
  - (BOOL)boldHeadingConflictsInRange:(NSRange)range type:(StyleType)type {
74
- if(type == H1) {
75
- if(![_input->config h1Bold]) { return NO; }
76
- } else if(type == H2) {
77
- if(![_input->config h2Bold]) { return NO; }
78
- } else if(type == H3) {
79
- if(![_input->config h3Bold]) { return NO; }
95
+ if (type == H1) {
96
+ if (![_input->config h1Bold]) {
97
+ return NO;
98
+ }
99
+ } else if (type == H2) {
100
+ if (![_input->config h2Bold]) {
101
+ return NO;
102
+ }
103
+ } else if (type == H3) {
104
+ if (![_input->config h3Bold]) {
105
+ return NO;
106
+ }
80
107
  }
81
-
108
+
82
109
  id<BaseStyleProtocol> headingStyle = _input->stylesDict[@(type)];
83
- return range.length > 0
84
- ? [headingStyle anyOccurence:range]
85
- : [headingStyle detectStyle:range];
110
+ return range.length > 0 ? [headingStyle anyOccurence:range]
111
+ : [headingStyle detectStyle:range];
86
112
  }
87
113
 
88
- - (BOOL)styleCondition:(id _Nullable)value :(NSRange)range {
114
+ - (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
89
115
  UIFont *font = (UIFont *)value;
90
- return font != nullptr && [font isBold] && ![self boldHeadingConflictsInRange:range type:H1] && ![self boldHeadingConflictsInRange:range type:H2] && ![self boldHeadingConflictsInRange:range type:H3];
116
+ return font != nullptr && [font isBold] &&
117
+ ![self boldHeadingConflictsInRange:range type:H1] &&
118
+ ![self boldHeadingConflictsInRange:range type:H2] &&
119
+ ![self boldHeadingConflictsInRange:range type:H3];
91
120
  }
92
121
 
93
122
  - (BOOL)detectStyle:(NSRange)range {
94
- if(range.length >= 1) {
95
- return [OccurenceUtils detect:NSFontAttributeName withInput:_input inRange:range
96
- withCondition: ^BOOL(id _Nullable value, NSRange range) {
97
- return [self styleCondition:value :range];
98
- }
99
- ];
123
+ if (range.length >= 1) {
124
+ return [OccurenceUtils detect:NSFontAttributeName
125
+ withInput:_input
126
+ inRange:range
127
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
128
+ return [self styleCondition:value:range];
129
+ }];
100
130
  } else {
101
- return [OccurenceUtils detect:NSFontAttributeName withInput:_input atIndex:range.location checkPrevious:NO
102
- withCondition:^BOOL(id _Nullable value, NSRange range) {
103
- return [self styleCondition:value :range];
104
- }
105
- ];
131
+ return [OccurenceUtils detect:NSFontAttributeName
132
+ withInput:_input
133
+ atIndex:range.location
134
+ checkPrevious:NO
135
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
136
+ return [self styleCondition:value:range];
137
+ }];
106
138
  }
107
139
  }
108
140
 
109
141
  - (BOOL)anyOccurence:(NSRange)range {
110
- return [OccurenceUtils any:NSFontAttributeName withInput:_input inRange:range
111
- withCondition:^BOOL(id _Nullable value, NSRange range) {
112
- return [self styleCondition:value :range];
113
- }
114
- ];
142
+ return [OccurenceUtils any:NSFontAttributeName
143
+ withInput:_input
144
+ inRange:range
145
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
146
+ return [self styleCondition:value:range];
147
+ }];
115
148
  }
116
149
 
117
150
  - (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
118
- return [OccurenceUtils all:NSFontAttributeName withInput:_input inRange:range
119
- withCondition:^BOOL(id _Nullable value, NSRange range) {
120
- return [self styleCondition:value :range];
121
- }
122
- ];
151
+ return [OccurenceUtils all:NSFontAttributeName
152
+ withInput:_input
153
+ inRange:range
154
+ withCondition:^BOOL(id _Nullable value, NSRange range) {
155
+ return [self styleCondition:value:range];
156
+ }];
123
157
  }
124
158
 
125
159
  @end