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
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#import "EnrichedTextInputView.h"
|
|
2
|
+
#import "ImageAttachment.h"
|
|
3
|
+
#import "MediaAttachment.h"
|
|
4
|
+
#import "OccurenceUtils.h"
|
|
5
|
+
#import "StyleHeaders.h"
|
|
6
|
+
#import "TextInsertionUtils.h"
|
|
7
|
+
|
|
8
|
+
// custom NSAttributedStringKey to differentiate the image
|
|
9
|
+
static NSString *const ImageAttributeName = @"ImageAttributeName";
|
|
10
|
+
|
|
11
|
+
@implementation ImageStyle {
|
|
12
|
+
EnrichedTextInputView *_input;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
+ (StyleType)getStyleType {
|
|
16
|
+
return Image;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
+ (BOOL)isParagraphStyle {
|
|
20
|
+
return NO;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
- (instancetype)initWithInput:(id)input {
|
|
24
|
+
self = [super init];
|
|
25
|
+
_input = (EnrichedTextInputView *)input;
|
|
26
|
+
return self;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
- (void)applyStyle:(NSRange)range {
|
|
30
|
+
// no-op for image
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
- (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
|
|
34
|
+
// no-op for image
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
- (void)addTypingAttributes {
|
|
38
|
+
// no-op for image
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
- (void)removeAttributes:(NSRange)range {
|
|
42
|
+
[_input->textView.textStorage beginEditing];
|
|
43
|
+
[_input->textView.textStorage removeAttribute:ImageAttributeName range:range];
|
|
44
|
+
[_input->textView.textStorage removeAttribute:NSAttachmentAttributeName
|
|
45
|
+
range:range];
|
|
46
|
+
[_input->textView.textStorage endEditing];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
- (void)removeTypingAttributes {
|
|
50
|
+
NSMutableDictionary *currentAttributes =
|
|
51
|
+
[_input->textView.typingAttributes mutableCopy];
|
|
52
|
+
[currentAttributes removeObjectForKey:ImageAttributeName];
|
|
53
|
+
[currentAttributes removeObjectForKey:NSAttachmentAttributeName];
|
|
54
|
+
_input->textView.typingAttributes = currentAttributes;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
- (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
|
|
58
|
+
return [value isKindOfClass:[ImageData class]];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
- (BOOL)anyOccurence:(NSRange)range {
|
|
62
|
+
return [OccurenceUtils any:ImageAttributeName
|
|
63
|
+
withInput:_input
|
|
64
|
+
inRange:range
|
|
65
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
66
|
+
return [self styleCondition:value:range];
|
|
67
|
+
}];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
- (BOOL)detectStyle:(NSRange)range {
|
|
71
|
+
if (range.length >= 1) {
|
|
72
|
+
return [OccurenceUtils detect:ImageAttributeName
|
|
73
|
+
withInput:_input
|
|
74
|
+
inRange:range
|
|
75
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
76
|
+
return [self styleCondition:value:range];
|
|
77
|
+
}];
|
|
78
|
+
} else {
|
|
79
|
+
return [OccurenceUtils detect:ImageAttributeName
|
|
80
|
+
withInput:_input
|
|
81
|
+
atIndex:range.location
|
|
82
|
+
checkPrevious:YES
|
|
83
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
84
|
+
return [self styleCondition:value:range];
|
|
85
|
+
}];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
- (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
|
|
90
|
+
return [OccurenceUtils all:ImageAttributeName
|
|
91
|
+
withInput:_input
|
|
92
|
+
inRange:range
|
|
93
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
94
|
+
return [self styleCondition:value:range];
|
|
95
|
+
}];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
- (ImageData *)getImageDataAt:(NSUInteger)location {
|
|
99
|
+
NSRange imageRange = NSMakeRange(0, 0);
|
|
100
|
+
NSRange inputRange = NSMakeRange(0, _input->textView.textStorage.length);
|
|
101
|
+
|
|
102
|
+
// don't search at the very end of input
|
|
103
|
+
NSUInteger searchLocation = location;
|
|
104
|
+
if (searchLocation == _input->textView.textStorage.length) {
|
|
105
|
+
return nullptr;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
ImageData *imageData =
|
|
109
|
+
[_input->textView.textStorage attribute:ImageAttributeName
|
|
110
|
+
atIndex:searchLocation
|
|
111
|
+
longestEffectiveRange:&imageRange
|
|
112
|
+
inRange:inputRange];
|
|
113
|
+
|
|
114
|
+
return imageData;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
- (void)addImageAtRange:(NSRange)range
|
|
118
|
+
imageData:(ImageData *)imageData
|
|
119
|
+
withSelection:(BOOL)withSelection {
|
|
120
|
+
if (!imageData)
|
|
121
|
+
return;
|
|
122
|
+
|
|
123
|
+
ImageAttachment *attachment =
|
|
124
|
+
[[ImageAttachment alloc] initWithImageData:imageData];
|
|
125
|
+
attachment.delegate = _input;
|
|
126
|
+
|
|
127
|
+
NSDictionary *attributes =
|
|
128
|
+
@{NSAttachmentAttributeName : attachment, ImageAttributeName : imageData};
|
|
129
|
+
|
|
130
|
+
// Use the Object Replacement Character for Image.
|
|
131
|
+
// This tells TextKit "something non-text goes here".
|
|
132
|
+
NSString *placeholderChar = @"\uFFFC";
|
|
133
|
+
|
|
134
|
+
if (range.length == 0) {
|
|
135
|
+
[TextInsertionUtils insertText:placeholderChar
|
|
136
|
+
at:range.location
|
|
137
|
+
additionalAttributes:attributes
|
|
138
|
+
input:_input
|
|
139
|
+
withSelection:withSelection];
|
|
140
|
+
} else {
|
|
141
|
+
[TextInsertionUtils replaceText:placeholderChar
|
|
142
|
+
at:range
|
|
143
|
+
additionalAttributes:attributes
|
|
144
|
+
input:_input
|
|
145
|
+
withSelection:withSelection];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
- (void)addImage:(NSString *)uri width:(CGFloat)width height:(CGFloat)height {
|
|
150
|
+
ImageData *data = [[ImageData alloc] init];
|
|
151
|
+
data.uri = uri;
|
|
152
|
+
data.width = width;
|
|
153
|
+
data.height = height;
|
|
154
|
+
|
|
155
|
+
[self addImageAtRange:_input->textView.selectedRange
|
|
156
|
+
imageData:data
|
|
157
|
+
withSelection:YES];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@end
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
#import "
|
|
1
|
+
#import "ColorExtension.h"
|
|
2
2
|
#import "EnrichedTextInputView.h"
|
|
3
3
|
#import "FontExtension.h"
|
|
4
4
|
#import "OccurenceUtils.h"
|
|
5
5
|
#import "ParagraphsUtils.h"
|
|
6
|
-
#import "
|
|
6
|
+
#import "StyleHeaders.h"
|
|
7
7
|
|
|
8
8
|
@implementation InlineCodeStyle {
|
|
9
9
|
EnrichedTextInputView *_input;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
+ (StyleType)getStyleType {
|
|
12
|
+
+ (StyleType)getStyleType {
|
|
13
|
+
return InlineCode;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
+ (BOOL)isParagraphStyle {
|
|
17
|
+
return NO;
|
|
18
|
+
}
|
|
13
19
|
|
|
14
20
|
- (instancetype)initWithInput:(id)input {
|
|
15
21
|
self = [super init];
|
|
@@ -19,48 +25,76 @@
|
|
|
19
25
|
|
|
20
26
|
- (void)applyStyle:(NSRange)range {
|
|
21
27
|
BOOL isStylePresent = [self detectStyle:range];
|
|
22
|
-
if(range.length >= 1) {
|
|
23
|
-
isStylePresent ? [self removeAttributes:range]
|
|
28
|
+
if (range.length >= 1) {
|
|
29
|
+
isStylePresent ? [self removeAttributes:range]
|
|
30
|
+
: [self addAttributes:range withTypingAttr:YES];
|
|
24
31
|
} else {
|
|
25
32
|
isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
|
|
26
33
|
}
|
|
27
34
|
}
|
|
28
35
|
|
|
29
|
-
- (void)addAttributes:(NSRange)range {
|
|
36
|
+
- (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
|
|
30
37
|
// we don't want to apply inline code to newline characters, it looks bad
|
|
31
|
-
NSArray *nonNewlineRanges =
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
NSArray *nonNewlineRanges =
|
|
39
|
+
[ParagraphsUtils getNonNewlineRangesIn:_input->textView range:range];
|
|
40
|
+
|
|
41
|
+
for (NSValue *value in nonNewlineRanges) {
|
|
34
42
|
NSRange currentRange = [value rangeValue];
|
|
35
43
|
[_input->textView.textStorage beginEditing];
|
|
36
44
|
|
|
37
|
-
[_input->textView.textStorage
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
[_input->textView.textStorage
|
|
46
|
+
addAttribute:NSBackgroundColorAttributeName
|
|
47
|
+
value:[[_input->config inlineCodeBgColor]
|
|
48
|
+
colorWithAlphaIfNotTransparent:0.4]
|
|
49
|
+
range:currentRange];
|
|
50
|
+
[_input->textView.textStorage
|
|
51
|
+
addAttribute:NSForegroundColorAttributeName
|
|
52
|
+
value:[_input->config inlineCodeFgColor]
|
|
53
|
+
range:currentRange];
|
|
54
|
+
[_input->textView.textStorage
|
|
55
|
+
addAttribute:NSUnderlineColorAttributeName
|
|
56
|
+
value:[_input->config inlineCodeFgColor]
|
|
57
|
+
range:currentRange];
|
|
58
|
+
[_input->textView.textStorage
|
|
59
|
+
addAttribute:NSStrikethroughColorAttributeName
|
|
60
|
+
value:[_input->config inlineCodeFgColor]
|
|
61
|
+
range:currentRange];
|
|
62
|
+
[_input->textView.textStorage
|
|
63
|
+
enumerateAttribute:NSFontAttributeName
|
|
64
|
+
inRange:currentRange
|
|
65
|
+
options:0
|
|
66
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
67
|
+
BOOL *_Nonnull stop) {
|
|
68
|
+
UIFont *font = (UIFont *)value;
|
|
69
|
+
if (font != nullptr) {
|
|
70
|
+
UIFont *newFont = [[[_input->config monospacedFont]
|
|
71
|
+
withFontTraits:font] setSize:font.pointSize];
|
|
72
|
+
[_input->textView.textStorage
|
|
73
|
+
addAttribute:NSFontAttributeName
|
|
74
|
+
value:newFont
|
|
75
|
+
range:range];
|
|
76
|
+
}
|
|
77
|
+
}];
|
|
78
|
+
|
|
51
79
|
[_input->textView.textStorage endEditing];
|
|
52
80
|
}
|
|
53
81
|
}
|
|
54
82
|
|
|
55
83
|
- (void)addTypingAttributes {
|
|
56
|
-
NSMutableDictionary *newTypingAttrs =
|
|
57
|
-
|
|
58
|
-
newTypingAttrs[
|
|
59
|
-
|
|
60
|
-
newTypingAttrs[
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
84
|
+
NSMutableDictionary *newTypingAttrs =
|
|
85
|
+
[_input->textView.typingAttributes mutableCopy];
|
|
86
|
+
newTypingAttrs[NSBackgroundColorAttributeName] =
|
|
87
|
+
[[_input->config inlineCodeBgColor] colorWithAlphaIfNotTransparent:0.4];
|
|
88
|
+
newTypingAttrs[NSForegroundColorAttributeName] =
|
|
89
|
+
[_input->config inlineCodeFgColor];
|
|
90
|
+
newTypingAttrs[NSUnderlineColorAttributeName] =
|
|
91
|
+
[_input->config inlineCodeFgColor];
|
|
92
|
+
newTypingAttrs[NSStrikethroughColorAttributeName] =
|
|
93
|
+
[_input->config inlineCodeFgColor];
|
|
94
|
+
UIFont *currentFont = (UIFont *)newTypingAttrs[NSFontAttributeName];
|
|
95
|
+
if (currentFont != nullptr) {
|
|
96
|
+
newTypingAttrs[NSFontAttributeName] = [[[_input->config monospacedFont]
|
|
97
|
+
withFontTraits:currentFont] setSize:currentFont.pointSize];
|
|
64
98
|
}
|
|
65
99
|
_input->textView.typingAttributes = newTypingAttrs;
|
|
66
100
|
}
|
|
@@ -68,100 +102,131 @@
|
|
|
68
102
|
- (void)removeAttributes:(NSRange)range {
|
|
69
103
|
[_input->textView.textStorage beginEditing];
|
|
70
104
|
|
|
71
|
-
[_input->textView.textStorage removeAttribute:NSBackgroundColorAttributeName
|
|
72
|
-
|
|
73
|
-
[_input->textView.textStorage addAttribute:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
105
|
+
[_input->textView.textStorage removeAttribute:NSBackgroundColorAttributeName
|
|
106
|
+
range:range];
|
|
107
|
+
[_input->textView.textStorage addAttribute:NSForegroundColorAttributeName
|
|
108
|
+
value:[_input->config primaryColor]
|
|
109
|
+
range:range];
|
|
110
|
+
[_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName
|
|
111
|
+
value:[_input->config primaryColor]
|
|
112
|
+
range:range];
|
|
113
|
+
[_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName
|
|
114
|
+
value:[_input->config primaryColor]
|
|
115
|
+
range:range];
|
|
116
|
+
[_input->textView.textStorage
|
|
117
|
+
enumerateAttribute:NSFontAttributeName
|
|
118
|
+
inRange:range
|
|
119
|
+
options:0
|
|
120
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
121
|
+
BOOL *_Nonnull stop) {
|
|
122
|
+
UIFont *font = (UIFont *)value;
|
|
123
|
+
if (font != nullptr) {
|
|
124
|
+
UIFont *newFont = [[[_input->config primaryFont]
|
|
125
|
+
withFontTraits:font] setSize:font.pointSize];
|
|
126
|
+
[_input->textView.textStorage addAttribute:NSFontAttributeName
|
|
127
|
+
value:newFont
|
|
128
|
+
range:range];
|
|
129
|
+
}
|
|
130
|
+
}];
|
|
131
|
+
|
|
85
132
|
[_input->textView.textStorage endEditing];
|
|
86
133
|
}
|
|
87
134
|
|
|
88
135
|
- (void)removeTypingAttributes {
|
|
89
|
-
NSMutableDictionary *newTypingAttrs =
|
|
136
|
+
NSMutableDictionary *newTypingAttrs =
|
|
137
|
+
[_input->textView.typingAttributes mutableCopy];
|
|
90
138
|
[newTypingAttrs removeObjectForKey:NSBackgroundColorAttributeName];
|
|
91
|
-
newTypingAttrs[NSForegroundColorAttributeName] =
|
|
139
|
+
newTypingAttrs[NSForegroundColorAttributeName] =
|
|
140
|
+
[_input->config primaryColor];
|
|
92
141
|
newTypingAttrs[NSUnderlineColorAttributeName] = [_input->config primaryColor];
|
|
93
|
-
newTypingAttrs[NSStrikethroughColorAttributeName] =
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
142
|
+
newTypingAttrs[NSStrikethroughColorAttributeName] =
|
|
143
|
+
[_input->config primaryColor];
|
|
144
|
+
UIFont *currentFont = (UIFont *)newTypingAttrs[NSFontAttributeName];
|
|
145
|
+
if (currentFont != nullptr) {
|
|
146
|
+
newTypingAttrs[NSFontAttributeName] = [[[_input->config primaryFont]
|
|
147
|
+
withFontTraits:currentFont] setSize:currentFont.pointSize];
|
|
97
148
|
}
|
|
98
149
|
_input->textView.typingAttributes = newTypingAttrs;
|
|
99
150
|
}
|
|
100
151
|
|
|
101
152
|
// making sure no newlines get inline code style, it looks bad
|
|
102
153
|
- (void)handleNewlines {
|
|
103
|
-
for(int i = 0; i < _input->textView.textStorage.string.length; i++) {
|
|
104
|
-
if([[NSCharacterSet newlineCharacterSet]
|
|
154
|
+
for (int i = 0; i < _input->textView.textStorage.string.length; i++) {
|
|
155
|
+
if ([[NSCharacterSet newlineCharacterSet]
|
|
156
|
+
characterIsMember:[_input->textView.textStorage.string
|
|
157
|
+
characterAtIndex:i]]) {
|
|
105
158
|
NSRange mockRange = NSMakeRange(0, 0);
|
|
106
|
-
// can't use detect style because it intentionally doesn't take newlines
|
|
107
|
-
|
|
108
|
-
|
|
159
|
+
// can't use detect style because it intentionally doesn't take newlines
|
|
160
|
+
// into consideration
|
|
161
|
+
UIColor *bgColor =
|
|
162
|
+
[_input->textView.textStorage attribute:NSBackgroundColorAttributeName
|
|
163
|
+
atIndex:i
|
|
164
|
+
effectiveRange:&mockRange];
|
|
165
|
+
if ([self styleCondition:bgColor:NSMakeRange(i, 1)]) {
|
|
109
166
|
[self removeAttributes:NSMakeRange(i, 1)];
|
|
110
167
|
}
|
|
111
168
|
}
|
|
112
169
|
}
|
|
113
170
|
}
|
|
114
171
|
|
|
115
|
-
// emojis don't retain monospace font attribute so we check for the background
|
|
116
|
-
|
|
172
|
+
// emojis don't retain monospace font attribute so we check for the background
|
|
173
|
+
// color if there is no mention
|
|
174
|
+
- (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
|
|
117
175
|
UIColor *bgColor = (UIColor *)value;
|
|
118
176
|
MentionStyle *mStyle = _input->stylesDict[@([MentionStyle getStyleType])];
|
|
119
177
|
return bgColor != nullptr && mStyle != nullptr && ![mStyle detectStyle:range];
|
|
120
178
|
}
|
|
121
179
|
|
|
122
180
|
- (BOOL)detectStyle:(NSRange)range {
|
|
123
|
-
if(range.length >= 1) {
|
|
181
|
+
if (range.length >= 1) {
|
|
124
182
|
// detect only in non-newline characters
|
|
125
|
-
NSArray *nonNewlineRanges =
|
|
126
|
-
|
|
183
|
+
NSArray *nonNewlineRanges =
|
|
184
|
+
[ParagraphsUtils getNonNewlineRangesIn:_input->textView range:range];
|
|
185
|
+
if (nonNewlineRanges.count == 0) {
|
|
127
186
|
return NO;
|
|
128
187
|
}
|
|
129
|
-
|
|
188
|
+
|
|
130
189
|
BOOL detected = YES;
|
|
131
|
-
for(NSValue *value in nonNewlineRanges) {
|
|
190
|
+
for (NSValue *value in nonNewlineRanges) {
|
|
132
191
|
NSRange currentRange = [value rangeValue];
|
|
133
|
-
BOOL currentDetected =
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
192
|
+
BOOL currentDetected =
|
|
193
|
+
[OccurenceUtils detect:NSBackgroundColorAttributeName
|
|
194
|
+
withInput:_input
|
|
195
|
+
inRange:currentRange
|
|
196
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
197
|
+
return [self styleCondition:value:range];
|
|
198
|
+
}];
|
|
138
199
|
detected = detected && currentDetected;
|
|
139
200
|
}
|
|
140
|
-
|
|
201
|
+
|
|
141
202
|
return detected;
|
|
142
203
|
} else {
|
|
143
|
-
return [OccurenceUtils detect:NSBackgroundColorAttributeName
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
204
|
+
return [OccurenceUtils detect:NSBackgroundColorAttributeName
|
|
205
|
+
withInput:_input
|
|
206
|
+
atIndex:range.location
|
|
207
|
+
checkPrevious:NO
|
|
208
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
209
|
+
return [self styleCondition:value:range];
|
|
210
|
+
}];
|
|
148
211
|
}
|
|
149
212
|
}
|
|
150
213
|
|
|
151
214
|
- (BOOL)anyOccurence:(NSRange)range {
|
|
152
|
-
return [OccurenceUtils any:NSBackgroundColorAttributeName
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
215
|
+
return [OccurenceUtils any:NSBackgroundColorAttributeName
|
|
216
|
+
withInput:_input
|
|
217
|
+
inRange:range
|
|
218
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
219
|
+
return [self styleCondition:value:range];
|
|
220
|
+
}];
|
|
157
221
|
}
|
|
158
222
|
|
|
159
223
|
- (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
|
|
160
|
-
return [OccurenceUtils all:NSBackgroundColorAttributeName
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
224
|
+
return [OccurenceUtils all:NSBackgroundColorAttributeName
|
|
225
|
+
withInput:_input
|
|
226
|
+
inRange:range
|
|
227
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
228
|
+
return [self styleCondition:value:range];
|
|
229
|
+
}];
|
|
165
230
|
}
|
|
166
231
|
|
|
167
232
|
@end
|
|
@@ -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 ItalicStyle {
|
|
7
7
|
EnrichedTextInputView *_input;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
+ (StyleType)getStyleType {
|
|
10
|
+
+ (StyleType)getStyleType {
|
|
11
|
+
return Italic;
|
|
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 setItalic];
|
|
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 setItalic];
|
|
46
60
|
_input->textView.typingAttributes = newTypingAttrs;
|
|
47
61
|
}
|
|
@@ -49,62 +63,74 @@
|
|
|
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 removeItalic];
|
|
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 removeItalic];
|
|
69
90
|
_input->textView.typingAttributes = newTypingAttrs;
|
|
70
91
|
}
|
|
71
92
|
}
|
|
72
93
|
|
|
73
|
-
- (BOOL)styleCondition:(id _Nullable)value
|
|
94
|
+
- (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
|
|
74
95
|
UIFont *font = (UIFont *)value;
|
|
75
96
|
return font != nullptr && [font isItalic];
|
|
76
97
|
}
|
|
77
98
|
|
|
78
99
|
- (BOOL)detectStyle:(NSRange)range {
|
|
79
|
-
if(range.length >= 1) {
|
|
80
|
-
return [OccurenceUtils detect:NSFontAttributeName
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
if (range.length >= 1) {
|
|
101
|
+
return [OccurenceUtils detect:NSFontAttributeName
|
|
102
|
+
withInput:_input
|
|
103
|
+
inRange:range
|
|
104
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
105
|
+
return [self styleCondition:value:range];
|
|
106
|
+
}];
|
|
85
107
|
} else {
|
|
86
|
-
return [OccurenceUtils detect:NSFontAttributeName
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
108
|
+
return [OccurenceUtils detect:NSFontAttributeName
|
|
109
|
+
withInput:_input
|
|
110
|
+
atIndex:range.location
|
|
111
|
+
checkPrevious:NO
|
|
112
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
113
|
+
return [self styleCondition:value:range];
|
|
114
|
+
}];
|
|
91
115
|
}
|
|
92
116
|
}
|
|
93
117
|
|
|
94
118
|
- (BOOL)anyOccurence:(NSRange)range {
|
|
95
|
-
return [OccurenceUtils any:NSFontAttributeName
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
119
|
+
return [OccurenceUtils any:NSFontAttributeName
|
|
120
|
+
withInput:_input
|
|
121
|
+
inRange:range
|
|
122
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
123
|
+
return [self styleCondition:value:range];
|
|
124
|
+
}];
|
|
100
125
|
}
|
|
101
126
|
|
|
102
127
|
- (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
|
|
103
|
-
return [OccurenceUtils all:NSFontAttributeName
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
128
|
+
return [OccurenceUtils all:NSFontAttributeName
|
|
129
|
+
withInput:_input
|
|
130
|
+
inRange:range
|
|
131
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
132
|
+
return [self styleCondition:value:range];
|
|
133
|
+
}];
|
|
108
134
|
}
|
|
109
135
|
|
|
110
136
|
@end
|