react-native-enriched 0.0.0 → 0.1.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/LICENSE +20 -0
- package/README.md +875 -0
- package/ReactNativeEnriched.podspec +27 -0
- package/android/build.gradle +101 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +146 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +55 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ComponentDescriptors.cpp +22 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ComponentDescriptors.h +24 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +118 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +95 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.cpp +128 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +577 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ShadowNodes.cpp +17 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ShadowNodes.h +23 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/States.cpp +16 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/States.h +20 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +535 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewLayoutManager.kt +64 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +292 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +19 -0
- package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +40 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeHtmlEvent.kt +28 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeSelectionEvent.kt +29 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeTextEvent.kt +30 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnInputBlurEvent.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnInputFocusEvent.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnLinkDetectedEvent.kt +30 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnMentionDetectedEvent.kt +29 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnMentionEvent.kt +33 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +34 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +41 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +16 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +36 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +71 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +111 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +9 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +9 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +49 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedBlockSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedHeadingSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedInlineSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedParagraphSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedZeroWidthSpaceSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +227 -0
- package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +146 -0
- package/android/src/main/java/com/swmansion/enriched/styles/ListStyles.kt +173 -0
- package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +186 -0
- package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +223 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +857 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSelection.kt +285 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpanState.kt +204 -0
- package/android/src/main/java/com/swmansion/enriched/utils/Utils.kt +91 -0
- package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +73 -0
- package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedTextWatcher.kt +51 -0
- package/android/src/main/new_arch/CMakeLists.txt +56 -0
- package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +22 -0
- package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +26 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +35 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +51 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +26 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +34 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +54 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +9 -0
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +25 -0
- package/ios/EnrichedTextInputView.h +33 -0
- package/ios/EnrichedTextInputView.mm +1190 -0
- package/ios/EnrichedTextInputViewManager.mm +13 -0
- package/ios/config/InputConfig.h +67 -0
- package/ios/config/InputConfig.mm +382 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/ComponentDescriptors.cpp +22 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/ComponentDescriptors.h +24 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +118 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +95 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/Props.cpp +128 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +577 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +384 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/ShadowNodes.cpp +17 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/ShadowNodes.h +23 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/States.cpp +16 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/States.h +20 -0
- package/ios/inputParser/InputParser.h +11 -0
- package/ios/inputParser/InputParser.mm +659 -0
- package/ios/inputTextView/InputTextView.h +6 -0
- package/ios/inputTextView/InputTextView.mm +115 -0
- package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +17 -0
- package/ios/internals/EnrichedTextInputViewShadowNode.h +40 -0
- package/ios/internals/EnrichedTextInputViewShadowNode.mm +83 -0
- package/ios/internals/EnrichedTextInputViewState.cpp +10 -0
- package/ios/internals/EnrichedTextInputViewState.h +20 -0
- package/ios/styles/BlockQuoteStyle.mm +248 -0
- package/ios/styles/BoldStyle.mm +122 -0
- package/ios/styles/H1Style.mm +10 -0
- package/ios/styles/H2Style.mm +10 -0
- package/ios/styles/H3Style.mm +10 -0
- package/ios/styles/HeadingStyleBase.mm +144 -0
- package/ios/styles/InlineCodeStyle.mm +163 -0
- package/ios/styles/ItalicStyle.mm +110 -0
- package/ios/styles/LinkStyle.mm +463 -0
- package/ios/styles/MentionStyle.mm +476 -0
- package/ios/styles/OrderedListStyle.mm +225 -0
- package/ios/styles/StrikethroughStyle.mm +80 -0
- package/ios/styles/UnderlineStyle.mm +112 -0
- package/ios/styles/UnorderedListStyle.mm +225 -0
- package/ios/utils/BaseStyleProtocol.h +16 -0
- package/ios/utils/ColorExtension.h +6 -0
- package/ios/utils/ColorExtension.mm +27 -0
- package/ios/utils/FontExtension.h +13 -0
- package/ios/utils/FontExtension.mm +91 -0
- package/ios/utils/LayoutManagerExtension.h +6 -0
- package/ios/utils/LayoutManagerExtension.mm +171 -0
- package/ios/utils/LinkData.h +9 -0
- package/ios/utils/LinkData.mm +4 -0
- package/ios/utils/MentionParams.h +9 -0
- package/ios/utils/MentionParams.mm +4 -0
- package/ios/utils/MentionStyleProps.h +13 -0
- package/ios/utils/MentionStyleProps.mm +56 -0
- package/ios/utils/OccurenceUtils.h +37 -0
- package/ios/utils/OccurenceUtils.mm +124 -0
- package/ios/utils/ParagraphsUtils.h +7 -0
- package/ios/utils/ParagraphsUtils.mm +54 -0
- package/ios/utils/StringExtension.h +15 -0
- package/ios/utils/StringExtension.mm +57 -0
- package/ios/utils/StyleHeaders.h +74 -0
- package/ios/utils/StylePair.h +9 -0
- package/ios/utils/StylePair.mm +4 -0
- package/ios/utils/StyleTypeEnum.h +22 -0
- package/ios/utils/TextDecorationLineEnum.h +6 -0
- package/ios/utils/TextDecorationLineEnum.mm +4 -0
- package/ios/utils/TextInsertionUtils.h +6 -0
- package/ios/utils/TextInsertionUtils.mm +48 -0
- package/ios/utils/WordsUtils.h +6 -0
- package/ios/utils/WordsUtils.mm +88 -0
- package/ios/utils/ZeroWidthSpaceUtils.h +7 -0
- package/ios/utils/ZeroWidthSpaceUtils.mm +164 -0
- package/lib/module/EnrichedTextInput.js +191 -0
- package/lib/module/EnrichedTextInput.js.map +1 -0
- package/lib/module/EnrichedTextInputNativeComponent.ts +235 -0
- package/lib/module/index.js +4 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/normalizeHtmlStyle.js +141 -0
- package/lib/module/normalizeHtmlStyle.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/EnrichedTextInput.d.ts +113 -0
- package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -0
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +160 -0
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/normalizeHtmlStyle.d.ts +4 -0
- package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +1 -0
- package/package.json +172 -1
- package/react-native.config.js +13 -0
- package/src/EnrichedTextInput.tsx +358 -0
- package/src/EnrichedTextInputNativeComponent.ts +235 -0
- package/src/index.tsx +9 -0
- package/src/normalizeHtmlStyle.ts +188 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#import "StyleHeaders.h"
|
|
2
|
+
#import "EnrichedTextInputView.h"
|
|
3
|
+
|
|
4
|
+
@implementation H3Style
|
|
5
|
+
+ (StyleType)getStyleType { return H3; }
|
|
6
|
+
- (CGFloat)getHeadingFontSize { return [((EnrichedTextInputView *)input)->config h3FontSize]; }
|
|
7
|
+
- (BOOL)isHeadingBold {
|
|
8
|
+
return [((EnrichedTextInputView *)input)->config h3Bold];
|
|
9
|
+
}
|
|
10
|
+
@end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#import "StyleHeaders.h"
|
|
2
|
+
#import "EnrichedTextInputView.h"
|
|
3
|
+
#import "FontExtension.h"
|
|
4
|
+
#import "OccurenceUtils.h"
|
|
5
|
+
|
|
6
|
+
@implementation HeadingStyleBase
|
|
7
|
+
|
|
8
|
+
// mock values since H1/2/3Style classes anyway are used
|
|
9
|
+
+ (StyleType)getStyleType { return None; }
|
|
10
|
+
- (CGFloat)getHeadingFontSize { return 0; }
|
|
11
|
+
- (BOOL)isHeadingBold { return false; }
|
|
12
|
+
|
|
13
|
+
- (EnrichedTextInputView *)typedInput {
|
|
14
|
+
return (EnrichedTextInputView *)input;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
- (instancetype)initWithInput:(id)input {
|
|
18
|
+
self = [super init];
|
|
19
|
+
self->input = input;
|
|
20
|
+
return self;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// the range will already be the full paragraph/s range
|
|
24
|
+
// but if the paragraph is empty it still is of length 0
|
|
25
|
+
- (void)applyStyle:(NSRange)range {
|
|
26
|
+
BOOL isStylePresent = [self detectStyle:range];
|
|
27
|
+
if(range.length >= 1) {
|
|
28
|
+
isStylePresent ? [self removeAttributes:range] : [self addAttributes:range];
|
|
29
|
+
} else {
|
|
30
|
+
isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// the range will already be the proper full paragraph/s range
|
|
35
|
+
- (void)addAttributes:(NSRange)range {
|
|
36
|
+
[[self typedInput]->textView.textStorage beginEditing];
|
|
37
|
+
[[self typedInput]->textView.textStorage enumerateAttribute:NSFontAttributeName inRange:range options:0
|
|
38
|
+
usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
|
|
39
|
+
UIFont *font = (UIFont *)value;
|
|
40
|
+
if(font != nullptr) {
|
|
41
|
+
UIFont *newFont = [font setSize:[self getHeadingFontSize]];
|
|
42
|
+
if([self isHeadingBold]) {
|
|
43
|
+
newFont = [newFont setBold];
|
|
44
|
+
}
|
|
45
|
+
[[self typedInput]->textView.textStorage addAttribute:NSFontAttributeName value:newFont range:range];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
[[self typedInput]->textView.textStorage endEditing];
|
|
50
|
+
|
|
51
|
+
// also toggle typing attributes
|
|
52
|
+
[self addTypingAttributes];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// will always be called on empty paragraphs so only typing attributes can be changed
|
|
56
|
+
- (void)addTypingAttributes {
|
|
57
|
+
UIFont *currentFontAttr = (UIFont *)[self typedInput]->textView.typingAttributes[NSFontAttributeName];
|
|
58
|
+
if(currentFontAttr != nullptr) {
|
|
59
|
+
NSMutableDictionary *newTypingAttrs = [[self typedInput]->textView.typingAttributes mutableCopy];
|
|
60
|
+
UIFont *newFont = [currentFontAttr setSize:[self getHeadingFontSize]];
|
|
61
|
+
if([self isHeadingBold]) {
|
|
62
|
+
newFont = [newFont setBold];
|
|
63
|
+
}
|
|
64
|
+
newTypingAttrs[NSFontAttributeName] = newFont;
|
|
65
|
+
[self typedInput]->textView.typingAttributes = newTypingAttrs;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// we need to remove the style from the whole paragraph
|
|
70
|
+
- (void)removeAttributes:(NSRange)range {
|
|
71
|
+
NSRange paragraphRange = [[self typedInput]->textView.textStorage.string paragraphRangeForRange:range];
|
|
72
|
+
|
|
73
|
+
[[self typedInput]->textView.textStorage beginEditing];
|
|
74
|
+
[[self typedInput]->textView.textStorage enumerateAttribute:NSFontAttributeName inRange:paragraphRange options:0
|
|
75
|
+
usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
|
|
76
|
+
if([self styleCondition:value :range]) {
|
|
77
|
+
UIFont *newFont = [(UIFont *)value setSize:[[[self typedInput]->config primaryFontSize] floatValue]];
|
|
78
|
+
if([self isHeadingBold]) {
|
|
79
|
+
newFont = [newFont removeBold];
|
|
80
|
+
}
|
|
81
|
+
[[self typedInput]->textView.textStorage addAttribute:NSFontAttributeName value:newFont range:range];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
];
|
|
85
|
+
[[self typedInput]->textView.textStorage endEditing];
|
|
86
|
+
|
|
87
|
+
// typing attributes still need to be removed
|
|
88
|
+
UIFont *currentFontAttr = (UIFont *)[self typedInput]->textView.typingAttributes[NSFontAttributeName];
|
|
89
|
+
if(currentFontAttr != nullptr) {
|
|
90
|
+
NSMutableDictionary *newTypingAttrs = [[self typedInput]->textView.typingAttributes mutableCopy];
|
|
91
|
+
UIFont *newFont = [currentFontAttr setSize:[[[self typedInput]->config primaryFontSize] floatValue]];
|
|
92
|
+
if([self isHeadingBold]) {
|
|
93
|
+
newFont = [newFont removeBold];
|
|
94
|
+
}
|
|
95
|
+
newTypingAttrs[NSFontAttributeName] = newFont;
|
|
96
|
+
[self typedInput]->textView.typingAttributes = newTypingAttrs;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
- (void)removeTypingAttributes {
|
|
101
|
+
// all the heading still needs to be removed because this function may be called in conflicting styles logic
|
|
102
|
+
// typing attributes already get removed in there as well
|
|
103
|
+
[self removeAttributes:[self typedInput]->textView.selectedRange];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
- (BOOL)styleCondition:(id _Nullable)value :(NSRange)range {
|
|
107
|
+
UIFont *font = (UIFont *)value;
|
|
108
|
+
return font != nullptr && font.pointSize == [self getHeadingFontSize];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
- (BOOL)detectStyle:(NSRange)range {
|
|
112
|
+
if(range.length >= 1) {
|
|
113
|
+
return [OccurenceUtils detect:NSFontAttributeName withInput:[self typedInput] inRange:range
|
|
114
|
+
withCondition: ^BOOL(id _Nullable value, NSRange range) {
|
|
115
|
+
return [self styleCondition:value :range];
|
|
116
|
+
}
|
|
117
|
+
];
|
|
118
|
+
} else {
|
|
119
|
+
UIFont *currentFontAttr = (UIFont *)[self typedInput]->textView.typingAttributes[NSFontAttributeName];
|
|
120
|
+
if(currentFontAttr == nullptr) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
return currentFontAttr.pointSize == [self getHeadingFontSize];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
- (BOOL)anyOccurence:(NSRange)range {
|
|
128
|
+
return [OccurenceUtils any:NSFontAttributeName withInput:[self typedInput] inRange:range
|
|
129
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
130
|
+
return [self styleCondition:value :range];
|
|
131
|
+
}
|
|
132
|
+
];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
- (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
|
|
136
|
+
return [OccurenceUtils all:NSFontAttributeName withInput:[self typedInput] inRange:range
|
|
137
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
138
|
+
return [self styleCondition:value :range];
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@end
|
|
144
|
+
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#import "StyleHeaders.h"
|
|
2
|
+
#import "EnrichedTextInputView.h"
|
|
3
|
+
#import "FontExtension.h"
|
|
4
|
+
#import "OccurenceUtils.h"
|
|
5
|
+
#import "ParagraphsUtils.h"
|
|
6
|
+
|
|
7
|
+
@implementation InlineCodeStyle {
|
|
8
|
+
EnrichedTextInputView *_input;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
+ (StyleType)getStyleType { return InlineCode; }
|
|
12
|
+
|
|
13
|
+
- (instancetype)initWithInput:(id)input {
|
|
14
|
+
self = [super init];
|
|
15
|
+
_input = (EnrichedTextInputView *)input;
|
|
16
|
+
return self;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
- (void)applyStyle:(NSRange)range {
|
|
20
|
+
BOOL isStylePresent = [self detectStyle:range];
|
|
21
|
+
if(range.length >= 1) {
|
|
22
|
+
isStylePresent ? [self removeAttributes:range] : [self addAttributes:range];
|
|
23
|
+
} else {
|
|
24
|
+
isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
- (void)addAttributes:(NSRange)range {
|
|
29
|
+
// we don't want to apply inline code to newline characters, it looks bad
|
|
30
|
+
NSArray *nonNewlineRanges = [ParagraphsUtils getNonNewlineRangesIn:_input->textView range:range];
|
|
31
|
+
|
|
32
|
+
for(NSValue *value in nonNewlineRanges) {
|
|
33
|
+
NSRange currentRange = [value rangeValue];
|
|
34
|
+
[_input->textView.textStorage beginEditing];
|
|
35
|
+
|
|
36
|
+
[_input->textView.textStorage addAttribute:NSBackgroundColorAttributeName value:[[_input->config inlineCodeBgColor] colorWithAlphaComponent:0.4] range:currentRange];
|
|
37
|
+
[_input->textView.textStorage addAttribute:NSForegroundColorAttributeName value:[_input->config inlineCodeFgColor] range:currentRange];
|
|
38
|
+
[_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName value:[_input->config inlineCodeFgColor] range:currentRange];
|
|
39
|
+
[_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName value:[_input->config inlineCodeFgColor] range:currentRange];
|
|
40
|
+
[_input->textView.textStorage enumerateAttribute:NSFontAttributeName inRange:currentRange options:0
|
|
41
|
+
usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
|
|
42
|
+
UIFont *font = (UIFont *)value;
|
|
43
|
+
if(font != nullptr) {
|
|
44
|
+
UIFont *newFont = [[_input->config monospacedFont] withFontTraits:font];
|
|
45
|
+
[_input->textView.textStorage addAttribute:NSFontAttributeName value:newFont range:range];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
[_input->textView.textStorage endEditing];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
- (void)addTypingAttributes {
|
|
55
|
+
NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
|
|
56
|
+
newTypingAttrs[NSBackgroundColorAttributeName] = [[_input->config inlineCodeBgColor] colorWithAlphaComponent:0.4];
|
|
57
|
+
newTypingAttrs[NSForegroundColorAttributeName] = [_input->config inlineCodeFgColor];
|
|
58
|
+
newTypingAttrs[NSUnderlineColorAttributeName] = [_input->config inlineCodeFgColor];
|
|
59
|
+
newTypingAttrs[NSStrikethroughColorAttributeName] = [_input->config inlineCodeFgColor];
|
|
60
|
+
UIFont* currentFont = (UIFont *)newTypingAttrs[NSFontAttributeName];
|
|
61
|
+
if(currentFont != nullptr) {
|
|
62
|
+
newTypingAttrs[NSFontAttributeName] = [[_input->config monospacedFont] withFontTraits:currentFont];
|
|
63
|
+
}
|
|
64
|
+
_input->textView.typingAttributes = newTypingAttrs;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
- (void)removeAttributes:(NSRange)range {
|
|
68
|
+
[_input->textView.textStorage beginEditing];
|
|
69
|
+
|
|
70
|
+
[_input->textView.textStorage removeAttribute:NSBackgroundColorAttributeName range:range];
|
|
71
|
+
[_input->textView.textStorage addAttribute:NSForegroundColorAttributeName value:[_input->config primaryColor] range:range];
|
|
72
|
+
[_input->textView.textStorage addAttribute:NSUnderlineColorAttributeName value:[_input->config primaryColor] range:range];
|
|
73
|
+
[_input->textView.textStorage addAttribute:NSStrikethroughColorAttributeName value:[_input->config primaryColor] range:range];
|
|
74
|
+
[_input->textView.textStorage enumerateAttribute:NSFontAttributeName inRange:range options:0
|
|
75
|
+
usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
|
|
76
|
+
UIFont *font = (UIFont *)value;
|
|
77
|
+
if(font != nullptr) {
|
|
78
|
+
UIFont *newFont = [[_input->config primaryFont] withFontTraits:font];
|
|
79
|
+
[_input->textView.textStorage addAttribute:NSFontAttributeName value:newFont range:range];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
[_input->textView.textStorage endEditing];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
- (void)removeTypingAttributes {
|
|
88
|
+
NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
|
|
89
|
+
[newTypingAttrs removeObjectForKey:NSBackgroundColorAttributeName];
|
|
90
|
+
newTypingAttrs[NSForegroundColorAttributeName] = [_input->config primaryColor];
|
|
91
|
+
newTypingAttrs[NSUnderlineColorAttributeName] = [_input->config primaryColor];
|
|
92
|
+
newTypingAttrs[NSStrikethroughColorAttributeName] = [_input->config primaryColor];
|
|
93
|
+
UIFont* currentFont = (UIFont *)newTypingAttrs[NSFontAttributeName];
|
|
94
|
+
if(currentFont != nullptr) {
|
|
95
|
+
newTypingAttrs[NSFontAttributeName] = [[_input->config primaryFont] withFontTraits:currentFont];
|
|
96
|
+
}
|
|
97
|
+
_input->textView.typingAttributes = newTypingAttrs;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// making sure no newlines get inline code style, it looks bad
|
|
101
|
+
- (void)handleNewlines {
|
|
102
|
+
for(int i = 0; i < _input->textView.textStorage.string.length; i++) {
|
|
103
|
+
if([[NSCharacterSet newlineCharacterSet] characterIsMember:[_input->textView.textStorage.string characterAtIndex:i]]) {
|
|
104
|
+
NSRange mockRange = NSMakeRange(0, 0);
|
|
105
|
+
// can't use detect style because it intentionally doesn't take newlines into consideration
|
|
106
|
+
UIColor *bgColor = [_input->textView.textStorage attribute:NSBackgroundColorAttributeName atIndex:i effectiveRange:&mockRange];
|
|
107
|
+
if([self styleCondition:bgColor :NSMakeRange(i, 1)]) {
|
|
108
|
+
[self removeAttributes:NSMakeRange(i, 1)];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// emojis don't retain monospace font attribute so we check for the background color if there is no mention
|
|
115
|
+
- (BOOL)styleCondition:(id _Nullable)value :(NSRange)range {
|
|
116
|
+
UIColor *bgColor = (UIColor *)value;
|
|
117
|
+
MentionStyle *mStyle = _input->stylesDict[@([MentionStyle getStyleType])];
|
|
118
|
+
return bgColor != nullptr && mStyle != nullptr && ![mStyle detectStyle:range];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
- (BOOL)detectStyle:(NSRange)range {
|
|
122
|
+
if(range.length >= 1) {
|
|
123
|
+
// detect only in non-newline characters
|
|
124
|
+
NSArray *nonNewlineRanges = [ParagraphsUtils getNonNewlineRangesIn:_input->textView range:range];
|
|
125
|
+
if(nonNewlineRanges.count == 0) {
|
|
126
|
+
return NO;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
BOOL detected = YES;
|
|
130
|
+
for(NSValue *value in nonNewlineRanges) {
|
|
131
|
+
NSRange currentRange = [value rangeValue];
|
|
132
|
+
BOOL currentDetected = [OccurenceUtils detect:NSBackgroundColorAttributeName withInput:_input inRange:currentRange
|
|
133
|
+
withCondition: ^BOOL(id _Nullable value, NSRange range) {
|
|
134
|
+
return [self styleCondition:value :range];
|
|
135
|
+
}
|
|
136
|
+
];
|
|
137
|
+
detected = detected && currentDetected;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return detected;
|
|
141
|
+
} else {
|
|
142
|
+
UIColor *currentBgColorAttr = (UIColor *)_input->textView.typingAttributes[NSBackgroundColorAttributeName];
|
|
143
|
+
return [self styleCondition:currentBgColorAttr :range];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
- (BOOL)anyOccurence:(NSRange)range {
|
|
148
|
+
return [OccurenceUtils any:NSBackgroundColorAttributeName withInput:_input inRange:range
|
|
149
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
150
|
+
return [self styleCondition:value :range];
|
|
151
|
+
}
|
|
152
|
+
];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
- (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
|
|
156
|
+
return [OccurenceUtils all:NSBackgroundColorAttributeName withInput:_input inRange:range
|
|
157
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
158
|
+
return [self styleCondition:value :range];
|
|
159
|
+
}
|
|
160
|
+
];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
@end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#import "StyleHeaders.h"
|
|
2
|
+
#import "EnrichedTextInputView.h"
|
|
3
|
+
#import "FontExtension.h"
|
|
4
|
+
#import "OccurenceUtils.h"
|
|
5
|
+
|
|
6
|
+
@implementation ItalicStyle {
|
|
7
|
+
EnrichedTextInputView *_input;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
+ (StyleType)getStyleType { return Italic; }
|
|
11
|
+
|
|
12
|
+
- (instancetype)initWithInput:(id)input {
|
|
13
|
+
self = [super init];
|
|
14
|
+
_input = (EnrichedTextInputView *)input;
|
|
15
|
+
return self;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
- (void)applyStyle:(NSRange)range {
|
|
19
|
+
BOOL isStylePresent = [self detectStyle:range];
|
|
20
|
+
if(range.length >= 1) {
|
|
21
|
+
isStylePresent ? [self removeAttributes:range] : [self addAttributes:range];
|
|
22
|
+
} else {
|
|
23
|
+
isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
- (void)addAttributes:(NSRange)range {
|
|
28
|
+
[_input->textView.textStorage beginEditing];
|
|
29
|
+
[_input->textView.textStorage enumerateAttribute:NSFontAttributeName inRange:range options:0
|
|
30
|
+
usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
|
|
31
|
+
UIFont *font = (UIFont *)value;
|
|
32
|
+
if(font != nullptr) {
|
|
33
|
+
UIFont *newFont = [font setItalic];
|
|
34
|
+
[_input->textView.textStorage addAttribute:NSFontAttributeName value:newFont range:range];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
];
|
|
38
|
+
[_input->textView.textStorage endEditing];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
- (void)addTypingAttributes {
|
|
42
|
+
UIFont *currentFontAttr = (UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
|
|
43
|
+
if(currentFontAttr != nullptr) {
|
|
44
|
+
NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
|
|
45
|
+
newTypingAttrs[NSFontAttributeName] = [currentFontAttr setItalic];
|
|
46
|
+
_input->textView.typingAttributes = newTypingAttrs;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
- (void)removeAttributes:(NSRange)range {
|
|
51
|
+
[_input->textView.textStorage beginEditing];
|
|
52
|
+
[_input->textView.textStorage enumerateAttribute:NSFontAttributeName inRange:range options:0
|
|
53
|
+
usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
|
|
54
|
+
UIFont *font = (UIFont *)value;
|
|
55
|
+
if(font != nullptr) {
|
|
56
|
+
UIFont *newFont = [font removeItalic];
|
|
57
|
+
[_input->textView.textStorage addAttribute:NSFontAttributeName value:newFont range:range];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
];
|
|
61
|
+
[_input->textView.textStorage endEditing];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
- (void)removeTypingAttributes {
|
|
65
|
+
UIFont *currentFontAttr = (UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
|
|
66
|
+
if(currentFontAttr != nullptr) {
|
|
67
|
+
NSMutableDictionary *newTypingAttrs = [_input->textView.typingAttributes mutableCopy];
|
|
68
|
+
newTypingAttrs[NSFontAttributeName] = [currentFontAttr removeItalic];
|
|
69
|
+
_input->textView.typingAttributes = newTypingAttrs;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
- (BOOL)styleCondition:(id _Nullable)value :(NSRange)range {
|
|
74
|
+
UIFont *font = (UIFont *)value;
|
|
75
|
+
return font != nullptr && [font isItalic];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
- (BOOL)detectStyle:(NSRange)range {
|
|
79
|
+
if(range.length >= 1) {
|
|
80
|
+
return [OccurenceUtils detect:NSFontAttributeName withInput:_input inRange:range
|
|
81
|
+
withCondition: ^BOOL(id _Nullable value, NSRange range) {
|
|
82
|
+
return [self styleCondition:value :range];
|
|
83
|
+
}
|
|
84
|
+
];
|
|
85
|
+
} else {
|
|
86
|
+
UIFont *currentFontAttr = (UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
|
|
87
|
+
if(currentFontAttr == nullptr) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
return [currentFontAttr isItalic];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
- (BOOL)anyOccurence:(NSRange)range {
|
|
95
|
+
return [OccurenceUtils any:NSFontAttributeName withInput:_input inRange:range
|
|
96
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
97
|
+
return [self styleCondition:value :range];
|
|
98
|
+
}
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
- (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
|
|
103
|
+
return [OccurenceUtils all:NSFontAttributeName withInput:_input inRange:range
|
|
104
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
105
|
+
return [self styleCondition:value :range];
|
|
106
|
+
}
|
|
107
|
+
];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@end
|