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.
- package/README.md +4 -14
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +4 -1
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +2 -1
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +0 -45
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +111 -2
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +9 -3
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +2 -0
- package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/events/OnRequestHtmlResultEvent.kt +33 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +42 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +135 -9
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +13 -3
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/spans/utils/ForceRedrawSpan.kt +13 -0
- package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +80 -9
- package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +188 -5
- package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +57 -30
- package/android/src/main/java/com/swmansion/enriched/utils/AsyncDrawable.kt +91 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +24 -13
- package/android/src/main/java/com/swmansion/enriched/utils/ResourceManager.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +3 -0
- package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +6 -6
- package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +6 -6
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +19 -19
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +40 -51
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +13 -15
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +23 -21
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +35 -36
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +4 -4
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +13 -14
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/conversions.h +12 -13
- package/android/src/main/res/drawable/broken_image.xml +10 -0
- package/ios/EnrichedTextInputView.h +27 -12
- package/ios/EnrichedTextInputView.mm +906 -547
- package/ios/attachments/ImageAttachment.h +10 -0
- package/ios/attachments/ImageAttachment.mm +34 -0
- package/ios/attachments/MediaAttachment.h +23 -0
- package/ios/attachments/MediaAttachment.mm +31 -0
- package/ios/config/InputConfig.h +12 -6
- package/ios/config/InputConfig.mm +71 -33
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +0 -45
- package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +41 -4
- package/ios/inputParser/InputParser.h +5 -5
- package/ios/inputParser/InputParser.mm +867 -333
- package/ios/inputTextView/InputTextView.h +1 -1
- package/ios/inputTextView/InputTextView.mm +100 -59
- package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +11 -9
- package/ios/internals/EnrichedTextInputViewShadowNode.h +28 -24
- package/ios/internals/EnrichedTextInputViewShadowNode.mm +64 -47
- package/ios/internals/EnrichedTextInputViewState.h +3 -1
- package/ios/styles/BlockQuoteStyle.mm +192 -142
- package/ios/styles/BoldStyle.mm +96 -62
- package/ios/styles/CodeBlockStyle.mm +304 -0
- package/ios/styles/H1Style.mm +10 -3
- package/ios/styles/H2Style.mm +10 -3
- package/ios/styles/H3Style.mm +10 -3
- package/ios/styles/HeadingStyleBase.mm +129 -84
- package/ios/styles/ImageStyle.mm +160 -0
- package/ios/styles/InlineCodeStyle.mm +149 -84
- package/ios/styles/ItalicStyle.mm +77 -51
- package/ios/styles/LinkStyle.mm +353 -224
- package/ios/styles/MentionStyle.mm +434 -220
- package/ios/styles/OrderedListStyle.mm +172 -105
- package/ios/styles/StrikethroughStyle.mm +53 -34
- package/ios/styles/UnderlineStyle.mm +69 -45
- package/ios/styles/UnorderedListStyle.mm +170 -105
- package/ios/utils/BaseStyleProtocol.h +3 -2
- package/ios/utils/ColorExtension.mm +7 -5
- package/ios/utils/FontExtension.mm +42 -27
- package/ios/utils/ImageData.h +10 -0
- package/ios/utils/ImageData.mm +4 -0
- package/ios/utils/LayoutManagerExtension.h +1 -1
- package/ios/utils/LayoutManagerExtension.mm +334 -109
- package/ios/utils/MentionParams.h +0 -1
- package/ios/utils/MentionStyleProps.h +1 -1
- package/ios/utils/MentionStyleProps.mm +27 -20
- package/ios/utils/OccurenceUtils.h +42 -38
- package/ios/utils/OccurenceUtils.mm +177 -107
- package/ios/utils/ParagraphAttributesUtils.h +6 -1
- package/ios/utils/ParagraphAttributesUtils.mm +152 -41
- package/ios/utils/ParagraphsUtils.h +2 -1
- package/ios/utils/ParagraphsUtils.mm +40 -26
- package/ios/utils/StringExtension.h +1 -1
- package/ios/utils/StringExtension.mm +19 -16
- package/ios/utils/StyleHeaders.h +35 -11
- package/ios/utils/TextInsertionUtils.h +13 -2
- package/ios/utils/TextInsertionUtils.mm +38 -20
- package/ios/utils/WordsUtils.h +2 -1
- package/ios/utils/WordsUtils.mm +32 -22
- package/ios/utils/ZeroWidthSpaceUtils.h +3 -1
- package/ios/utils/ZeroWidthSpaceUtils.mm +153 -75
- package/lib/module/EnrichedTextInput.js +41 -3
- package/lib/module/EnrichedTextInput.js.map +1 -1
- package/lib/module/EnrichedTextInputNativeComponent.ts +17 -5
- package/lib/module/normalizeHtmlStyle.js +0 -4
- package/lib/module/normalizeHtmlStyle.js.map +1 -1
- package/lib/typescript/src/EnrichedTextInput.d.ts +2 -5
- package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +7 -5
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +1 -1
- package/package.json +8 -1
- package/src/EnrichedTextInput.tsx +48 -7
- package/src/EnrichedTextInputNativeComponent.ts +17 -5
- package/src/normalizeHtmlStyle.ts +0 -4
|
@@ -1,136 +1,184 @@
|
|
|
1
|
-
#import "
|
|
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 {
|
|
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] +
|
|
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]
|
|
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 =
|
|
37
|
-
|
|
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,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
|
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(
|
|
103
|
+
_input->textView.selectedRange = NSMakeRange(
|
|
104
|
+
preModificationRange.location, preModificationRange.length + offset);
|
|
76
105
|
}
|
|
77
|
-
|
|
106
|
+
|
|
78
107
|
// also add typing attributes
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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 =
|
|
94
|
-
|
|
95
|
-
|
|
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
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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 =
|
|
109
|
-
|
|
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
|
|
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
|
|
126
|
-
|
|
127
|
-
|
|
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
|
|
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
|
|
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
|
|
189
|
+
- (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
|
|
142
190
|
NSParagraphStyle *pStyle = (NSParagraphStyle *)value;
|
|
143
|
-
return pStyle != nullptr && pStyle.headIndent == [self getHeadIndent] &&
|
|
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
|
|
149
|
-
|
|
150
|
-
|
|
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
|
|
155
|
-
|
|
156
|
-
|
|
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
|
|
164
|
-
|
|
165
|
-
|
|
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
|
|
172
|
-
|
|
173
|
-
|
|
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
|
|
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]
|
|
237
|
+
if ([[_input->config blockquoteColor]
|
|
238
|
+
isEqualToColor:[_input->config primaryColor]]) {
|
|
207
239
|
return;
|
|
208
240
|
}
|
|
209
|
-
|
|
210
|
-
NSRange wholeRange =
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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 = [
|
|
216
|
-
|
|
217
|
-
|
|
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
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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
|
}
|
package/ios/styles/BoldStyle.mm
CHANGED
|
@@ -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 {
|
|
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]
|
|
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
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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 =
|
|
43
|
-
|
|
44
|
-
|
|
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
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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 =
|
|
66
|
-
|
|
67
|
-
|
|
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]) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
} else if(type ==
|
|
79
|
-
if(![_input->config
|
|
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
|
-
|
|
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
|
|
114
|
+
- (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
|
|
89
115
|
UIFont *font = (UIFont *)value;
|
|
90
|
-
return font != nullptr && [font isBold] &&
|
|
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
|
|
96
|
-
|
|
97
|
-
|
|
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
|
|
102
|
-
|
|
103
|
-
|
|
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
|
|
111
|
-
|
|
112
|
-
|
|
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
|
|
119
|
-
|
|
120
|
-
|
|
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
|