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,12 +1,18 @@
|
|
|
1
|
-
#import "StyleHeaders.h"
|
|
2
1
|
#import "EnrichedTextInputView.h"
|
|
3
2
|
#import "OccurenceUtils.h"
|
|
3
|
+
#import "StyleHeaders.h"
|
|
4
4
|
|
|
5
5
|
@implementation UnderlineStyle {
|
|
6
6
|
EnrichedTextInputView *_input;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
+ (StyleType)getStyleType {
|
|
9
|
+
+ (StyleType)getStyleType {
|
|
10
|
+
return Underline;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
+ (BOOL)isParagraphStyle {
|
|
14
|
+
return NO;
|
|
15
|
+
}
|
|
10
16
|
|
|
11
17
|
- (instancetype)initWithInput:(id)input {
|
|
12
18
|
self = [super init];
|
|
@@ -15,58 +21,68 @@
|
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
- (void)applyStyle:(NSRange)range {
|
|
18
|
-
BOOL isStylePresent = [self detectStyle:
|
|
19
|
-
if(range.length >= 1) {
|
|
20
|
-
isStylePresent ? [self removeAttributes:range]
|
|
24
|
+
BOOL isStylePresent = [self detectStyle:range];
|
|
25
|
+
if (range.length >= 1) {
|
|
26
|
+
isStylePresent ? [self removeAttributes:range]
|
|
27
|
+
: [self addAttributes:range withTypingAttr:YES];
|
|
21
28
|
} else {
|
|
22
29
|
isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
|
|
23
30
|
}
|
|
24
31
|
}
|
|
25
32
|
|
|
26
|
-
- (void)addAttributes:(NSRange)range {
|
|
27
|
-
[_input->textView.textStorage addAttribute:NSUnderlineStyleAttributeName
|
|
33
|
+
- (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
|
|
34
|
+
[_input->textView.textStorage addAttribute:NSUnderlineStyleAttributeName
|
|
35
|
+
value:@(NSUnderlineStyleSingle)
|
|
36
|
+
range:range];
|
|
28
37
|
}
|
|
29
38
|
|
|
30
39
|
- (void)addTypingAttributes {
|
|
31
|
-
NSMutableDictionary *newTypingAttrs =
|
|
40
|
+
NSMutableDictionary *newTypingAttrs =
|
|
41
|
+
[_input->textView.typingAttributes mutableCopy];
|
|
32
42
|
newTypingAttrs[NSUnderlineStyleAttributeName] = @(NSUnderlineStyleSingle);
|
|
33
43
|
_input->textView.typingAttributes = newTypingAttrs;
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
- (void)removeAttributes:(NSRange)range {
|
|
37
|
-
[_input->textView.textStorage removeAttribute:NSUnderlineStyleAttributeName
|
|
47
|
+
[_input->textView.textStorage removeAttribute:NSUnderlineStyleAttributeName
|
|
48
|
+
range:range];
|
|
38
49
|
}
|
|
39
50
|
|
|
40
51
|
- (void)removeTypingAttributes {
|
|
41
|
-
NSMutableDictionary *newTypingAttrs =
|
|
42
|
-
|
|
52
|
+
NSMutableDictionary *newTypingAttrs =
|
|
53
|
+
[_input->textView.typingAttributes mutableCopy];
|
|
54
|
+
[newTypingAttrs removeObjectForKey:NSUnderlineStyleAttributeName];
|
|
43
55
|
_input->textView.typingAttributes = newTypingAttrs;
|
|
44
56
|
}
|
|
45
57
|
|
|
46
58
|
- (BOOL)underlinedLinkConflictsInRange:(NSRange)range {
|
|
47
59
|
BOOL conflicted = NO;
|
|
48
|
-
if([_input->config linkDecorationLine] == DecorationUnderline) {
|
|
60
|
+
if ([_input->config linkDecorationLine] == DecorationUnderline) {
|
|
49
61
|
LinkStyle *linkStyle = _input->stylesDict[@([LinkStyle getStyleType])];
|
|
50
|
-
conflicted = range.length > 0
|
|
51
|
-
|
|
52
|
-
: [linkStyle detectStyle:range];
|
|
62
|
+
conflicted = range.length > 0 ? [linkStyle anyOccurence:range]
|
|
63
|
+
: [linkStyle detectStyle:range];
|
|
53
64
|
}
|
|
54
65
|
return conflicted;
|
|
55
66
|
}
|
|
56
67
|
|
|
57
68
|
- (BOOL)underlinedMentionConflictsInRange:(NSRange)range {
|
|
58
69
|
BOOL conflicted = NO;
|
|
59
|
-
MentionStyle *mentionStyle =
|
|
60
|
-
|
|
61
|
-
|
|
70
|
+
MentionStyle *mentionStyle =
|
|
71
|
+
_input->stylesDict[@([MentionStyle getStyleType])];
|
|
72
|
+
if (range.length == 0) {
|
|
73
|
+
if ([mentionStyle detectStyle:range]) {
|
|
62
74
|
MentionParams *params = [mentionStyle getMentionParamsAt:range.location];
|
|
63
|
-
conflicted =
|
|
75
|
+
conflicted =
|
|
76
|
+
[_input->config mentionStylePropsForIndicator:params.indicator]
|
|
77
|
+
.decorationLine == DecorationUnderline;
|
|
64
78
|
}
|
|
65
79
|
} else {
|
|
66
80
|
NSArray *occurences = [mentionStyle findAllOccurences:range];
|
|
67
|
-
for(StylePair *pair in occurences) {
|
|
68
|
-
MentionParams *params = [mentionStyle
|
|
69
|
-
|
|
81
|
+
for (StylePair *pair in occurences) {
|
|
82
|
+
MentionParams *params = [mentionStyle
|
|
83
|
+
getMentionParamsAt:[pair.rangeValue rangeValue].location];
|
|
84
|
+
if ([_input->config mentionStylePropsForIndicator:params.indicator]
|
|
85
|
+
.decorationLine == DecorationUnderline) {
|
|
70
86
|
conflicted = YES;
|
|
71
87
|
break;
|
|
72
88
|
}
|
|
@@ -75,41 +91,49 @@
|
|
|
75
91
|
return conflicted;
|
|
76
92
|
}
|
|
77
93
|
|
|
78
|
-
- (BOOL)styleCondition:(id _Nullable)value
|
|
94
|
+
- (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
|
|
79
95
|
NSNumber *underlineStyle = (NSNumber *)value;
|
|
80
|
-
return underlineStyle != nullptr &&
|
|
96
|
+
return underlineStyle != nullptr &&
|
|
97
|
+
[underlineStyle intValue] != NSUnderlineStyleNone &&
|
|
98
|
+
![self underlinedLinkConflictsInRange:range] &&
|
|
99
|
+
![self underlinedMentionConflictsInRange:range];
|
|
81
100
|
}
|
|
82
101
|
|
|
83
102
|
- (BOOL)detectStyle:(NSRange)range {
|
|
84
|
-
if(range.length >= 1) {
|
|
85
|
-
return [OccurenceUtils detect:NSUnderlineStyleAttributeName
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
103
|
+
if (range.length >= 1) {
|
|
104
|
+
return [OccurenceUtils detect:NSUnderlineStyleAttributeName
|
|
105
|
+
withInput:_input
|
|
106
|
+
inRange:range
|
|
107
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
108
|
+
return [self styleCondition:value:range];
|
|
109
|
+
}];
|
|
90
110
|
} else {
|
|
91
|
-
return [OccurenceUtils detect:NSUnderlineStyleAttributeName
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
111
|
+
return [OccurenceUtils detect:NSUnderlineStyleAttributeName
|
|
112
|
+
withInput:_input
|
|
113
|
+
atIndex:range.location
|
|
114
|
+
checkPrevious:NO
|
|
115
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
116
|
+
return [self styleCondition:value:range];
|
|
117
|
+
}];
|
|
96
118
|
}
|
|
97
119
|
}
|
|
98
120
|
|
|
99
121
|
- (BOOL)anyOccurence:(NSRange)range {
|
|
100
|
-
return [OccurenceUtils any:NSUnderlineStyleAttributeName
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
122
|
+
return [OccurenceUtils any:NSUnderlineStyleAttributeName
|
|
123
|
+
withInput:_input
|
|
124
|
+
inRange:range
|
|
125
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
126
|
+
return [self styleCondition:value:range];
|
|
127
|
+
}];
|
|
105
128
|
}
|
|
106
129
|
|
|
107
130
|
- (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
|
|
108
|
-
return [OccurenceUtils all:NSUnderlineStyleAttributeName
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
131
|
+
return [OccurenceUtils all:NSUnderlineStyleAttributeName
|
|
132
|
+
withInput:_input
|
|
133
|
+
inRange:range
|
|
134
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
135
|
+
return [self styleCondition:value:range];
|
|
136
|
+
}];
|
|
113
137
|
}
|
|
114
138
|
|
|
115
139
|
@end
|
|
@@ -1,20 +1,27 @@
|
|
|
1
|
-
#import "StyleHeaders.h"
|
|
2
1
|
#import "EnrichedTextInputView.h"
|
|
3
2
|
#import "FontExtension.h"
|
|
4
3
|
#import "OccurenceUtils.h"
|
|
5
4
|
#import "ParagraphsUtils.h"
|
|
5
|
+
#import "StyleHeaders.h"
|
|
6
6
|
#import "TextInsertionUtils.h"
|
|
7
7
|
|
|
8
8
|
@implementation UnorderedListStyle {
|
|
9
9
|
EnrichedTextInputView *_input;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
+ (StyleType)getStyleType {
|
|
12
|
+
+ (StyleType)getStyleType {
|
|
13
|
+
return UnorderedList;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
+ (BOOL)isParagraphStyle {
|
|
17
|
+
return YES;
|
|
18
|
+
}
|
|
13
19
|
|
|
14
20
|
- (CGFloat)getHeadIndent {
|
|
15
21
|
// lists are drawn manually
|
|
16
22
|
// margin before bullet + gap between bullet and paragraph
|
|
17
|
-
return [_input->config unorderedListMarginLeft] +
|
|
23
|
+
return [_input->config unorderedListMarginLeft] +
|
|
24
|
+
[_input->config unorderedListGapWidth];
|
|
18
25
|
}
|
|
19
26
|
|
|
20
27
|
- (instancetype)initWithInput:(id)input {
|
|
@@ -25,99 +32,135 @@
|
|
|
25
32
|
|
|
26
33
|
- (void)applyStyle:(NSRange)range {
|
|
27
34
|
BOOL isStylePresent = [self detectStyle:range];
|
|
28
|
-
if(range.length >= 1) {
|
|
29
|
-
isStylePresent ? [self removeAttributes:range]
|
|
35
|
+
if (range.length >= 1) {
|
|
36
|
+
isStylePresent ? [self removeAttributes:range]
|
|
37
|
+
: [self addAttributes:range withTypingAttr:YES];
|
|
30
38
|
} else {
|
|
31
39
|
isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
|
|
32
40
|
}
|
|
33
41
|
}
|
|
34
42
|
|
|
35
43
|
// we assume correct paragraph range is already given
|
|
36
|
-
- (void)addAttributes:(NSRange)range {
|
|
37
|
-
NSTextList *bullet =
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
- (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
|
|
45
|
+
NSTextList *bullet =
|
|
46
|
+
[[NSTextList alloc] initWithMarkerFormat:NSTextListMarkerDisc options:0];
|
|
47
|
+
NSArray *paragraphs =
|
|
48
|
+
[ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView
|
|
49
|
+
range:range];
|
|
50
|
+
// if we fill empty lines with zero width spaces, we need to offset later
|
|
51
|
+
// ranges
|
|
40
52
|
NSInteger offset = 0;
|
|
41
53
|
// needed for range adjustments
|
|
42
54
|
NSRange preModificationRange = _input->textView.selectedRange;
|
|
43
|
-
|
|
55
|
+
|
|
44
56
|
// let's not emit some weird selection changes or text/html changes
|
|
45
57
|
_input->blockEmitting = YES;
|
|
46
|
-
|
|
47
|
-
for(NSValue *value in paragraphs) {
|
|
58
|
+
|
|
59
|
+
for (NSValue *value in paragraphs) {
|
|
48
60
|
// take previous offsets into consideration
|
|
49
|
-
NSRange fixedRange = NSMakeRange([value rangeValue].location + offset,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
NSRange fixedRange = NSMakeRange([value rangeValue].location + offset,
|
|
62
|
+
[value rangeValue].length);
|
|
63
|
+
|
|
64
|
+
// length 0 with first line, length 1 and newline with some empty lines in
|
|
65
|
+
// the middle
|
|
66
|
+
if (fixedRange.length == 0 ||
|
|
67
|
+
(fixedRange.length == 1 &&
|
|
68
|
+
[[NSCharacterSet newlineCharacterSet]
|
|
69
|
+
characterIsMember:[_input->textView.textStorage.string
|
|
70
|
+
characterAtIndex:fixedRange.location]])) {
|
|
71
|
+
[TextInsertionUtils insertText:@"\u200B"
|
|
72
|
+
at:fixedRange.location
|
|
73
|
+
additionalAttributes:nullptr
|
|
74
|
+
input:_input
|
|
75
|
+
withSelection:NO];
|
|
57
76
|
fixedRange = NSMakeRange(fixedRange.location, fixedRange.length + 1);
|
|
58
77
|
offset += 1;
|
|
59
78
|
}
|
|
60
|
-
|
|
61
|
-
[_input->textView.textStorage
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
|
|
80
|
+
[_input->textView.textStorage
|
|
81
|
+
enumerateAttribute:NSParagraphStyleAttributeName
|
|
82
|
+
inRange:fixedRange
|
|
83
|
+
options:0
|
|
84
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
85
|
+
BOOL *_Nonnull stop) {
|
|
86
|
+
NSMutableParagraphStyle *pStyle =
|
|
87
|
+
[(NSParagraphStyle *)value mutableCopy];
|
|
88
|
+
pStyle.textLists = @[ bullet ];
|
|
89
|
+
pStyle.headIndent = [self getHeadIndent];
|
|
90
|
+
pStyle.firstLineHeadIndent = [self getHeadIndent];
|
|
91
|
+
[_input->textView.textStorage
|
|
92
|
+
addAttribute:NSParagraphStyleAttributeName
|
|
93
|
+
value:pStyle
|
|
94
|
+
range:range];
|
|
95
|
+
}];
|
|
70
96
|
}
|
|
71
|
-
|
|
97
|
+
|
|
72
98
|
// back to emitting
|
|
73
99
|
_input->blockEmitting = NO;
|
|
74
|
-
|
|
75
|
-
if(preModificationRange.length == 0) {
|
|
76
|
-
// fix selection if only one line was possibly made a list and filled with a
|
|
100
|
+
|
|
101
|
+
if (preModificationRange.length == 0) {
|
|
102
|
+
// fix selection if only one line was possibly made a list and filled with a
|
|
103
|
+
// space
|
|
77
104
|
_input->textView.selectedRange = preModificationRange;
|
|
78
105
|
} else {
|
|
79
106
|
// in other cases, fix the selection with newly made offsets
|
|
80
|
-
_input->textView.selectedRange = NSMakeRange(
|
|
107
|
+
_input->textView.selectedRange = NSMakeRange(
|
|
108
|
+
preModificationRange.location, preModificationRange.length + offset);
|
|
81
109
|
}
|
|
82
|
-
|
|
110
|
+
|
|
83
111
|
// also add typing attributes
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
112
|
+
if (withTypingAttr) {
|
|
113
|
+
NSMutableDictionary *typingAttrs =
|
|
114
|
+
[_input->textView.typingAttributes mutableCopy];
|
|
115
|
+
NSMutableParagraphStyle *pStyle =
|
|
116
|
+
[typingAttrs[NSParagraphStyleAttributeName] mutableCopy];
|
|
117
|
+
pStyle.textLists = @[ bullet ];
|
|
118
|
+
pStyle.headIndent = [self getHeadIndent];
|
|
119
|
+
pStyle.firstLineHeadIndent = [self getHeadIndent];
|
|
120
|
+
typingAttrs[NSParagraphStyleAttributeName] = pStyle;
|
|
121
|
+
_input->textView.typingAttributes = typingAttrs;
|
|
122
|
+
}
|
|
91
123
|
}
|
|
92
124
|
|
|
93
125
|
// does pretty much the same as normal addAttributes, just need to get the range
|
|
94
126
|
- (void)addTypingAttributes {
|
|
95
|
-
[self addAttributes:_input->textView.selectedRange];
|
|
127
|
+
[self addAttributes:_input->textView.selectedRange withTypingAttr:YES];
|
|
96
128
|
}
|
|
97
129
|
|
|
98
130
|
- (void)removeAttributes:(NSRange)range {
|
|
99
|
-
NSArray *paragraphs =
|
|
100
|
-
|
|
131
|
+
NSArray *paragraphs =
|
|
132
|
+
[ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView
|
|
133
|
+
range:range];
|
|
134
|
+
|
|
101
135
|
[_input->textView.textStorage beginEditing];
|
|
102
|
-
|
|
103
|
-
for(NSValue *value in paragraphs) {
|
|
136
|
+
|
|
137
|
+
for (NSValue *value in paragraphs) {
|
|
104
138
|
NSRange range = [value rangeValue];
|
|
105
|
-
[_input->textView.textStorage
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
139
|
+
[_input->textView.textStorage
|
|
140
|
+
enumerateAttribute:NSParagraphStyleAttributeName
|
|
141
|
+
inRange:range
|
|
142
|
+
options:0
|
|
143
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
144
|
+
BOOL *_Nonnull stop) {
|
|
145
|
+
NSMutableParagraphStyle *pStyle =
|
|
146
|
+
[(NSParagraphStyle *)value mutableCopy];
|
|
147
|
+
pStyle.textLists = @[];
|
|
148
|
+
pStyle.headIndent = 0;
|
|
149
|
+
pStyle.firstLineHeadIndent = 0;
|
|
150
|
+
[_input->textView.textStorage
|
|
151
|
+
addAttribute:NSParagraphStyleAttributeName
|
|
152
|
+
value:pStyle
|
|
153
|
+
range:range];
|
|
154
|
+
}];
|
|
114
155
|
}
|
|
115
|
-
|
|
156
|
+
|
|
116
157
|
[_input->textView.textStorage endEditing];
|
|
117
|
-
|
|
158
|
+
|
|
118
159
|
// also remove typing attributes
|
|
119
|
-
NSMutableDictionary *typingAttrs =
|
|
120
|
-
|
|
160
|
+
NSMutableDictionary *typingAttrs =
|
|
161
|
+
[_input->textView.typingAttributes mutableCopy];
|
|
162
|
+
NSMutableParagraphStyle *pStyle =
|
|
163
|
+
[typingAttrs[NSParagraphStyleAttributeName] mutableCopy];
|
|
121
164
|
pStyle.textLists = @[];
|
|
122
165
|
pStyle.headIndent = 0;
|
|
123
166
|
pStyle.firstLineHeadIndent = 0;
|
|
@@ -125,24 +168,28 @@
|
|
|
125
168
|
_input->textView.typingAttributes = typingAttrs;
|
|
126
169
|
}
|
|
127
170
|
|
|
128
|
-
// needed for the sake of style conflicts, needs to do exactly the same as
|
|
171
|
+
// needed for the sake of style conflicts, needs to do exactly the same as
|
|
172
|
+
// removeAttribtues
|
|
129
173
|
- (void)removeTypingAttributes {
|
|
130
174
|
[self removeAttributes:_input->textView.selectedRange];
|
|
131
175
|
}
|
|
132
176
|
|
|
133
177
|
- (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text {
|
|
134
|
-
if([self detectStyle:_input->textView.selectedRange] && text.length == 0) {
|
|
178
|
+
if ([self detectStyle:_input->textView.selectedRange] && text.length == 0) {
|
|
135
179
|
// backspace while the style is active
|
|
136
|
-
|
|
137
|
-
NSRange paragraphRange = [_input->textView.textStorage.string
|
|
138
|
-
|
|
139
|
-
|
|
180
|
+
|
|
181
|
+
NSRange paragraphRange = [_input->textView.textStorage.string
|
|
182
|
+
paragraphRangeForRange:_input->textView.selectedRange];
|
|
183
|
+
|
|
184
|
+
if (NSEqualRanges(_input->textView.selectedRange, NSMakeRange(0, 0))) {
|
|
140
185
|
// a backspace on the very first input's line list point
|
|
141
|
-
// it doesn't run textVieDidChange so we need to manually remove
|
|
186
|
+
// it doesn't run textVieDidChange so we need to manually remove
|
|
187
|
+
// attributes
|
|
142
188
|
[self removeAttributes:paragraphRange];
|
|
143
189
|
return YES;
|
|
144
|
-
} else if(range.location == paragraphRange.location - 1) {
|
|
145
|
-
// same case in other lines; here, the removed range location will be
|
|
190
|
+
} else if (range.location == paragraphRange.location - 1) {
|
|
191
|
+
// same case in other lines; here, the removed range location will be
|
|
192
|
+
// exactly 1 less than paragraph range location
|
|
146
193
|
[self removeAttributes:paragraphRange];
|
|
147
194
|
return YES;
|
|
148
195
|
}
|
|
@@ -150,24 +197,36 @@
|
|
|
150
197
|
return NO;
|
|
151
198
|
}
|
|
152
199
|
|
|
153
|
-
- (BOOL)tryHandlingListShorcutInRange:(NSRange)range
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
200
|
+
- (BOOL)tryHandlingListShorcutInRange:(NSRange)range
|
|
201
|
+
replacementText:(NSString *)text {
|
|
202
|
+
NSRange paragraphRange =
|
|
203
|
+
[_input->textView.textStorage.string paragraphRangeForRange:range];
|
|
204
|
+
// space was added - check if we are both at the paragraph beginning + 1
|
|
205
|
+
// character (which we want to be a dash)
|
|
206
|
+
if ([text isEqualToString:@" "] &&
|
|
207
|
+
range.location - 1 == paragraphRange.location) {
|
|
208
|
+
unichar charBefore = [_input->textView.textStorage.string
|
|
209
|
+
characterAtIndex:range.location - 1];
|
|
210
|
+
if (charBefore == '-') {
|
|
159
211
|
// we got a match - add a list if possible
|
|
160
|
-
if([_input handleStyleBlocksAndConflicts:[[self class] getStyleType]
|
|
212
|
+
if ([_input handleStyleBlocksAndConflicts:[[self class] getStyleType]
|
|
213
|
+
range:paragraphRange]) {
|
|
161
214
|
// don't emit during the replacing
|
|
162
215
|
_input->blockEmitting = YES;
|
|
163
|
-
|
|
216
|
+
|
|
164
217
|
// remove the dash
|
|
165
|
-
[TextInsertionUtils replaceText:@""
|
|
166
|
-
|
|
218
|
+
[TextInsertionUtils replaceText:@""
|
|
219
|
+
at:NSMakeRange(paragraphRange.location, 1)
|
|
220
|
+
additionalAttributes:nullptr
|
|
221
|
+
input:_input
|
|
222
|
+
withSelection:YES];
|
|
223
|
+
|
|
167
224
|
_input->blockEmitting = NO;
|
|
168
|
-
|
|
225
|
+
|
|
169
226
|
// add attributes on the dashless paragraph
|
|
170
|
-
[self addAttributes:NSMakeRange(paragraphRange.location,
|
|
227
|
+
[self addAttributes:NSMakeRange(paragraphRange.location,
|
|
228
|
+
paragraphRange.length - 1)
|
|
229
|
+
withTypingAttr:YES];
|
|
171
230
|
return YES;
|
|
172
231
|
}
|
|
173
232
|
}
|
|
@@ -175,41 +234,47 @@
|
|
|
175
234
|
return NO;
|
|
176
235
|
}
|
|
177
236
|
|
|
178
|
-
- (BOOL)styleCondition:(id _Nullable)value
|
|
237
|
+
- (BOOL)styleCondition:(id _Nullable)value:(NSRange)range {
|
|
179
238
|
NSParagraphStyle *paragraph = (NSParagraphStyle *)value;
|
|
180
|
-
return paragraph != nullptr && paragraph.textLists.count == 1 &&
|
|
239
|
+
return paragraph != nullptr && paragraph.textLists.count == 1 &&
|
|
240
|
+
paragraph.textLists.firstObject.markerFormat == NSTextListMarkerDisc;
|
|
181
241
|
}
|
|
182
242
|
|
|
183
243
|
- (BOOL)detectStyle:(NSRange)range {
|
|
184
|
-
if(range.length >= 1) {
|
|
185
|
-
return [OccurenceUtils detect:NSParagraphStyleAttributeName
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
244
|
+
if (range.length >= 1) {
|
|
245
|
+
return [OccurenceUtils detect:NSParagraphStyleAttributeName
|
|
246
|
+
withInput:_input
|
|
247
|
+
inRange:range
|
|
248
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
249
|
+
return [self styleCondition:value:range];
|
|
250
|
+
}];
|
|
190
251
|
} else {
|
|
191
|
-
return [OccurenceUtils detect:NSParagraphStyleAttributeName
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
252
|
+
return [OccurenceUtils detect:NSParagraphStyleAttributeName
|
|
253
|
+
withInput:_input
|
|
254
|
+
atIndex:range.location
|
|
255
|
+
checkPrevious:YES
|
|
256
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
257
|
+
return [self styleCondition:value:range];
|
|
258
|
+
}];
|
|
196
259
|
}
|
|
197
260
|
}
|
|
198
261
|
|
|
199
262
|
- (BOOL)anyOccurence:(NSRange)range {
|
|
200
|
-
return [OccurenceUtils any:NSParagraphStyleAttributeName
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
263
|
+
return [OccurenceUtils any:NSParagraphStyleAttributeName
|
|
264
|
+
withInput:_input
|
|
265
|
+
inRange:range
|
|
266
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
267
|
+
return [self styleCondition:value:range];
|
|
268
|
+
}];
|
|
205
269
|
}
|
|
206
270
|
|
|
207
271
|
- (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
|
|
208
|
-
return [OccurenceUtils all:NSParagraphStyleAttributeName
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
272
|
+
return [OccurenceUtils all:NSParagraphStyleAttributeName
|
|
273
|
+
withInput:_input
|
|
274
|
+
inRange:range
|
|
275
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
276
|
+
return [self styleCondition:value:range];
|
|
277
|
+
}];
|
|
213
278
|
}
|
|
214
279
|
|
|
215
280
|
@end
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#pragma once
|
|
2
|
-
#import "StyleTypeEnum.h"
|
|
3
2
|
#import "StylePair.h"
|
|
3
|
+
#import "StyleTypeEnum.h"
|
|
4
4
|
|
|
5
5
|
@protocol BaseStyleProtocol <NSObject>
|
|
6
6
|
+ (StyleType)getStyleType;
|
|
7
|
+
+ (BOOL)isParagraphStyle;
|
|
7
8
|
- (instancetype _Nonnull)initWithInput:(id _Nonnull)input;
|
|
8
9
|
- (void)applyStyle:(NSRange)range;
|
|
9
|
-
- (void)addAttributes:(NSRange)range;
|
|
10
|
+
- (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr;
|
|
10
11
|
- (void)removeAttributes:(NSRange)range;
|
|
11
12
|
- (void)addTypingAttributes;
|
|
12
13
|
- (void)removeTypingAttributes;
|
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
- (BOOL)isEqualToColor:(UIColor *)otherColor {
|
|
5
5
|
CGColorSpaceRef colorSpaceRGB = CGColorSpaceCreateDeviceRGB();
|
|
6
6
|
|
|
7
|
-
UIColor *(^convertColorToRGBSpace)(UIColor*) = ^(UIColor *color) {
|
|
8
|
-
if(CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)) ==
|
|
7
|
+
UIColor * (^convertColorToRGBSpace)(UIColor *) = ^(UIColor *color) {
|
|
8
|
+
if (CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)) ==
|
|
9
|
+
kCGColorSpaceModelMonochrome) {
|
|
9
10
|
const CGFloat *oldComponents = CGColorGetComponents(color.CGColor);
|
|
10
|
-
CGFloat components[4] = {oldComponents[0], oldComponents[0],
|
|
11
|
-
|
|
11
|
+
CGFloat components[4] = {oldComponents[0], oldComponents[0],
|
|
12
|
+
oldComponents[0], oldComponents[1]};
|
|
13
|
+
CGColorRef colorRef = CGColorCreate(colorSpaceRGB, components);
|
|
12
14
|
|
|
13
15
|
UIColor *color = [UIColor colorWithCGColor:colorRef];
|
|
14
16
|
CGColorRelease(colorRef);
|
|
@@ -29,7 +31,7 @@
|
|
|
29
31
|
CGFloat alpha = 0.0;
|
|
30
32
|
[self getRed:nil green:nil blue:nil alpha:&alpha];
|
|
31
33
|
if (alpha > 0.0) {
|
|
32
|
-
|
|
34
|
+
return [self colorWithAlphaComponent:newAlpha];
|
|
33
35
|
}
|
|
34
36
|
return self;
|
|
35
37
|
}
|