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,56 +1,63 @@
|
|
|
1
1
|
#import "MentionStyleProps.h"
|
|
2
|
-
#import <React/RCTConversions.h>
|
|
3
2
|
#import "StringExtension.h"
|
|
3
|
+
#import <React/RCTConversions.h>
|
|
4
4
|
|
|
5
5
|
@implementation MentionStyleProps
|
|
6
6
|
|
|
7
|
-
+ (MentionStyleProps *)getSingleMentionStylePropsFromFollyDynamic:
|
|
7
|
+
+ (MentionStyleProps *)getSingleMentionStylePropsFromFollyDynamic:
|
|
8
|
+
(folly::dynamic)folly {
|
|
8
9
|
MentionStyleProps *nativeProps = [[MentionStyleProps alloc] init];
|
|
9
|
-
|
|
10
|
-
if(folly["color"].isNumber()) {
|
|
11
|
-
facebook::react::SharedColor color = facebook::react::SharedColor(
|
|
10
|
+
|
|
11
|
+
if (folly["color"].isNumber()) {
|
|
12
|
+
facebook::react::SharedColor color = facebook::react::SharedColor(
|
|
13
|
+
facebook::react::Color(folly["color"].asInt()));
|
|
12
14
|
nativeProps.color = RCTUIColorFromSharedColor(color);
|
|
13
15
|
} else {
|
|
14
16
|
nativeProps.color = [UIColor blueColor];
|
|
15
17
|
}
|
|
16
|
-
|
|
17
|
-
if(folly["backgroundColor"].isNumber()) {
|
|
18
|
-
facebook::react::SharedColor bgColor = facebook::react::SharedColor(
|
|
18
|
+
|
|
19
|
+
if (folly["backgroundColor"].isNumber()) {
|
|
20
|
+
facebook::react::SharedColor bgColor = facebook::react::SharedColor(
|
|
21
|
+
facebook::react::Color(folly["backgroundColor"].asInt()));
|
|
19
22
|
nativeProps.backgroundColor = RCTUIColorFromSharedColor(bgColor);
|
|
20
23
|
} else {
|
|
21
24
|
nativeProps.backgroundColor = [UIColor yellowColor];
|
|
22
25
|
}
|
|
23
|
-
|
|
24
|
-
if(folly["textDecorationLine"].isString()) {
|
|
26
|
+
|
|
27
|
+
if (folly["textDecorationLine"].isString()) {
|
|
25
28
|
std::string textDecorationLine = folly["textDecorationLine"].asString();
|
|
26
|
-
nativeProps.decorationLine = [[NSString fromCppString:textDecorationLine]
|
|
29
|
+
nativeProps.decorationLine = [[NSString fromCppString:textDecorationLine]
|
|
30
|
+
isEqualToString:DecorationUnderline]
|
|
31
|
+
? DecorationUnderline
|
|
32
|
+
: DecorationNone;
|
|
27
33
|
} else {
|
|
28
34
|
nativeProps.decorationLine = DecorationUnderline;
|
|
29
35
|
}
|
|
30
|
-
|
|
36
|
+
|
|
31
37
|
return nativeProps;
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
+ (NSDictionary *)getSinglePropsFromFollyDynamic:(folly::dynamic)folly {
|
|
35
|
-
MentionStyleProps *nativeProps =
|
|
41
|
+
MentionStyleProps *nativeProps =
|
|
42
|
+
[MentionStyleProps getSingleMentionStylePropsFromFollyDynamic:folly];
|
|
36
43
|
// the single props need to be somehow distinguishable in config
|
|
37
|
-
NSDictionary *dict = @{@"all": nativeProps};
|
|
44
|
+
NSDictionary *dict = @{@"all" : nativeProps};
|
|
38
45
|
return dict;
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
+ (NSDictionary *)getComplexPropsFromFollyDynamic:(folly::dynamic)folly {
|
|
42
49
|
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
|
43
|
-
|
|
44
|
-
for(const auto&
|
|
45
|
-
if(obj.first.isString() && obj.second.isObject()) {
|
|
50
|
+
|
|
51
|
+
for (const auto &obj : folly.items()) {
|
|
52
|
+
if (obj.first.isString() && obj.second.isObject()) {
|
|
46
53
|
std::string key = obj.first.asString();
|
|
47
|
-
MentionStyleProps *props = [MentionStyleProps
|
|
54
|
+
MentionStyleProps *props = [MentionStyleProps
|
|
55
|
+
getSingleMentionStylePropsFromFollyDynamic:obj.second];
|
|
48
56
|
dict[[NSString fromCppString:key]] = props;
|
|
49
57
|
}
|
|
50
58
|
}
|
|
51
|
-
|
|
59
|
+
|
|
52
60
|
return dict;
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
@end
|
|
56
|
-
|
|
@@ -1,43 +1,47 @@
|
|
|
1
1
|
#pragma once
|
|
2
|
-
#import "StylePair.h"
|
|
3
2
|
#import "EnrichedTextInputView.h"
|
|
4
|
-
|
|
3
|
+
#import "StylePair.h"
|
|
5
4
|
|
|
6
5
|
@interface OccurenceUtils : NSObject
|
|
7
|
-
+ (BOOL)detect
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
+ (BOOL)detect
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
+ (BOOL)detectMultiple
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
+ (BOOL)any
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
+ (BOOL)anyMultiple
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
+ (NSArray<StylePair *> *_Nullable)all
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
6
|
+
+ (BOOL)detect:(NSAttributedStringKey _Nonnull)key
|
|
7
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
8
|
+
inRange:(NSRange)range
|
|
9
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
10
|
+
NSRange range))condition;
|
|
11
|
+
+ (BOOL)detect:(NSAttributedStringKey _Nonnull)key
|
|
12
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
13
|
+
atIndex:(NSUInteger)index
|
|
14
|
+
checkPrevious:(BOOL)check
|
|
15
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
16
|
+
NSRange range))condition;
|
|
17
|
+
+ (BOOL)detectMultiple:(NSArray<NSAttributedStringKey> *_Nonnull)keys
|
|
18
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
19
|
+
inRange:(NSRange)range
|
|
20
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
21
|
+
NSRange range))condition;
|
|
22
|
+
+ (BOOL)any:(NSAttributedStringKey _Nonnull)key
|
|
23
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
24
|
+
inRange:(NSRange)range
|
|
25
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
26
|
+
NSRange range))condition;
|
|
27
|
+
+ (BOOL)anyMultiple:(NSArray<NSAttributedStringKey> *_Nonnull)keys
|
|
28
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
29
|
+
inRange:(NSRange)range
|
|
30
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
31
|
+
NSRange range))condition;
|
|
32
|
+
+ (NSArray<StylePair *> *_Nullable)all:(NSAttributedStringKey _Nonnull)key
|
|
33
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
34
|
+
inRange:(NSRange)range
|
|
35
|
+
withCondition:(BOOL(NS_NOESCAPE ^
|
|
36
|
+
_Nonnull)(id _Nullable value,
|
|
37
|
+
NSRange range))condition;
|
|
38
|
+
+ (NSArray<StylePair *> *_Nullable)
|
|
39
|
+
allMultiple:(NSArray<NSAttributedStringKey> *_Nonnull)keys
|
|
40
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
41
|
+
inRange:(NSRange)range
|
|
42
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
43
|
+
NSRange range))condition;
|
|
44
|
+
+ (NSArray *_Nonnull)getRangesWithout:(NSArray<NSNumber *> *_Nonnull)types
|
|
45
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
46
|
+
inRange:(NSRange)range;
|
|
43
47
|
@end
|
|
@@ -2,154 +2,224 @@
|
|
|
2
2
|
|
|
3
3
|
@implementation OccurenceUtils
|
|
4
4
|
|
|
5
|
-
+ (BOOL)detect
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
{
|
|
5
|
+
+ (BOOL)detect:(NSAttributedStringKey _Nonnull)key
|
|
6
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
7
|
+
inRange:(NSRange)range
|
|
8
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
9
|
+
NSRange range))condition {
|
|
11
10
|
__block NSInteger totalLength = 0;
|
|
12
|
-
[input->textView.textStorage
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
[input->textView.textStorage
|
|
12
|
+
enumerateAttribute:key
|
|
13
|
+
inRange:range
|
|
14
|
+
options:0
|
|
15
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
16
|
+
BOOL *_Nonnull stop) {
|
|
17
|
+
if (condition(value, range)) {
|
|
18
|
+
totalLength += range.length;
|
|
19
|
+
}
|
|
20
|
+
}];
|
|
19
21
|
return totalLength == range.length;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
// checkPrevious flag is used for styles like lists or blockquotes
|
|
23
|
-
// it means that first character of paragraph will be checked instead if the
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
{
|
|
25
|
+
// it means that first character of paragraph will be checked instead if the
|
|
26
|
+
// detection is not in input's selected range and at the end of the input
|
|
27
|
+
+ (BOOL)detect:(NSAttributedStringKey _Nonnull)key
|
|
28
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
29
|
+
atIndex:(NSUInteger)index
|
|
30
|
+
checkPrevious:(BOOL)checkPrev
|
|
31
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
32
|
+
NSRange range))condition {
|
|
31
33
|
NSRange detectionRange = NSMakeRange(index, 0);
|
|
32
34
|
id attrValue;
|
|
33
|
-
if(NSEqualRanges(input->textView.selectedRange, detectionRange)) {
|
|
35
|
+
if (NSEqualRanges(input->textView.selectedRange, detectionRange)) {
|
|
34
36
|
attrValue = input->textView.typingAttributes[key];
|
|
35
|
-
} else if(index == input->textView.textStorage.string.length) {
|
|
36
|
-
if(checkPrev) {
|
|
37
|
-
NSRange paragraphRange = [input->textView.textStorage.string
|
|
38
|
-
|
|
37
|
+
} else if (index == input->textView.textStorage.string.length) {
|
|
38
|
+
if (checkPrev) {
|
|
39
|
+
NSRange paragraphRange = [input->textView.textStorage.string
|
|
40
|
+
paragraphRangeForRange:detectionRange];
|
|
41
|
+
if (paragraphRange.location == detectionRange.location) {
|
|
39
42
|
return NO;
|
|
40
43
|
} else {
|
|
41
|
-
return [self detect:key
|
|
44
|
+
return [self detect:key
|
|
45
|
+
withInput:input
|
|
46
|
+
inRange:NSMakeRange(paragraphRange.location, 1)
|
|
47
|
+
withCondition:condition];
|
|
42
48
|
}
|
|
43
49
|
} else {
|
|
44
50
|
return NO;
|
|
45
51
|
}
|
|
46
52
|
} else {
|
|
47
53
|
NSRange attrRange = NSMakeRange(0, 0);
|
|
48
|
-
attrValue = [input->textView.textStorage attribute:key
|
|
54
|
+
attrValue = [input->textView.textStorage attribute:key
|
|
55
|
+
atIndex:index
|
|
56
|
+
effectiveRange:&attrRange];
|
|
49
57
|
}
|
|
50
58
|
return condition(attrValue, detectionRange);
|
|
51
59
|
}
|
|
52
60
|
|
|
53
|
-
+ (BOOL)detectMultiple
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
{
|
|
61
|
+
+ (BOOL)detectMultiple:(NSArray<NSAttributedStringKey> *_Nonnull)keys
|
|
62
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
63
|
+
inRange:(NSRange)range
|
|
64
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
65
|
+
NSRange range))condition {
|
|
59
66
|
__block NSInteger totalLength = 0;
|
|
60
|
-
for(NSString*
|
|
61
|
-
[input->textView.textStorage
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
for (NSString *key in keys) {
|
|
68
|
+
[input->textView.textStorage
|
|
69
|
+
enumerateAttribute:key
|
|
70
|
+
inRange:range
|
|
71
|
+
options:0
|
|
72
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
73
|
+
BOOL *_Nonnull stop) {
|
|
74
|
+
if (condition(value, range)) {
|
|
75
|
+
totalLength += range.length;
|
|
76
|
+
}
|
|
77
|
+
}];
|
|
68
78
|
}
|
|
69
79
|
return totalLength == range.length;
|
|
70
80
|
}
|
|
71
81
|
|
|
72
|
-
+ (BOOL)any
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
{
|
|
82
|
+
+ (BOOL)any:(NSAttributedStringKey _Nonnull)key
|
|
83
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
84
|
+
inRange:(NSRange)range
|
|
85
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
86
|
+
NSRange range))condition {
|
|
78
87
|
__block BOOL found = NO;
|
|
79
|
-
[input->textView.textStorage
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
88
|
+
[input->textView.textStorage
|
|
89
|
+
enumerateAttribute:key
|
|
90
|
+
inRange:range
|
|
91
|
+
options:0
|
|
92
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
93
|
+
BOOL *_Nonnull stop) {
|
|
94
|
+
if (condition(value, range)) {
|
|
95
|
+
found = YES;
|
|
96
|
+
*stop = YES;
|
|
97
|
+
}
|
|
98
|
+
}];
|
|
87
99
|
return found;
|
|
88
100
|
}
|
|
89
101
|
|
|
90
|
-
+ (BOOL)anyMultiple
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
{
|
|
102
|
+
+ (BOOL)anyMultiple:(NSArray<NSAttributedStringKey> *_Nonnull)keys
|
|
103
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
104
|
+
inRange:(NSRange)range
|
|
105
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
106
|
+
NSRange range))condition {
|
|
96
107
|
__block BOOL found = NO;
|
|
97
|
-
for(NSString *key in keys) {
|
|
98
|
-
[input->textView.textStorage
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
for (NSString *key in keys) {
|
|
109
|
+
[input->textView.textStorage
|
|
110
|
+
enumerateAttribute:key
|
|
111
|
+
inRange:range
|
|
112
|
+
options:0
|
|
113
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
114
|
+
BOOL *_Nonnull stop) {
|
|
115
|
+
if (condition(value, range)) {
|
|
116
|
+
found = YES;
|
|
117
|
+
*stop = YES;
|
|
118
|
+
}
|
|
119
|
+
}];
|
|
120
|
+
if (found) {
|
|
107
121
|
return YES;
|
|
108
122
|
}
|
|
109
123
|
}
|
|
110
124
|
return NO;
|
|
111
125
|
}
|
|
112
126
|
|
|
113
|
-
+ (NSArray<StylePair *> *_Nullable)all
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
+ (NSArray<StylePair *> *_Nullable)all:(NSAttributedStringKey _Nonnull)key
|
|
128
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
129
|
+
inRange:(NSRange)range
|
|
130
|
+
withCondition:
|
|
131
|
+
(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
132
|
+
NSRange range))
|
|
133
|
+
condition {
|
|
134
|
+
__block NSMutableArray<StylePair *> *occurences =
|
|
135
|
+
[[NSMutableArray<StylePair *> alloc] init];
|
|
136
|
+
[input->textView.textStorage
|
|
137
|
+
enumerateAttribute:key
|
|
138
|
+
inRange:range
|
|
139
|
+
options:0
|
|
140
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
141
|
+
BOOL *_Nonnull stop) {
|
|
142
|
+
if (condition(value, range)) {
|
|
143
|
+
StylePair *pair = [[StylePair alloc] init];
|
|
144
|
+
pair.rangeValue = [NSValue valueWithRange:range];
|
|
145
|
+
pair.styleValue = value;
|
|
146
|
+
[occurences addObject:pair];
|
|
147
|
+
}
|
|
148
|
+
}];
|
|
130
149
|
return occurences;
|
|
131
150
|
}
|
|
132
151
|
|
|
133
|
-
+ (NSArray<StylePair *> *_Nullable)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
{
|
|
139
|
-
__block NSMutableArray<StylePair *> *occurences =
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
152
|
+
+ (NSArray<StylePair *> *_Nullable)
|
|
153
|
+
allMultiple:(NSArray<NSAttributedStringKey> *_Nonnull)keys
|
|
154
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
155
|
+
inRange:(NSRange)range
|
|
156
|
+
withCondition:(BOOL(NS_NOESCAPE ^ _Nonnull)(id _Nullable value,
|
|
157
|
+
NSRange range))condition {
|
|
158
|
+
__block NSMutableArray<StylePair *> *occurences =
|
|
159
|
+
[[NSMutableArray<StylePair *> alloc] init];
|
|
160
|
+
for (NSString *key in keys) {
|
|
161
|
+
[input->textView.textStorage
|
|
162
|
+
enumerateAttribute:key
|
|
163
|
+
inRange:range
|
|
164
|
+
options:0
|
|
165
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
166
|
+
BOOL *_Nonnull stop) {
|
|
167
|
+
if (condition(value, range)) {
|
|
168
|
+
StylePair *pair = [[StylePair alloc] init];
|
|
169
|
+
pair.rangeValue = [NSValue valueWithRange:range];
|
|
170
|
+
pair.styleValue = value;
|
|
171
|
+
[occurences addObject:pair];
|
|
172
|
+
}
|
|
173
|
+
}];
|
|
151
174
|
}
|
|
152
175
|
return occurences;
|
|
153
176
|
}
|
|
154
177
|
|
|
178
|
+
+ (NSArray *_Nonnull)getRangesWithout:(NSArray<NSNumber *> *_Nonnull)types
|
|
179
|
+
withInput:(EnrichedTextInputView *_Nonnull)input
|
|
180
|
+
inRange:(NSRange)range {
|
|
181
|
+
NSMutableArray<id> *activeStyleObjects = [[NSMutableArray alloc] init];
|
|
182
|
+
for (NSNumber *type in types) {
|
|
183
|
+
id<BaseStyleProtocol> styleClass = input->stylesDict[type];
|
|
184
|
+
[activeStyleObjects addObject:styleClass];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (activeStyleObjects.count == 0) {
|
|
188
|
+
return @[ [NSValue valueWithRange:range] ];
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
NSMutableArray<NSValue *> *newRanges = [[NSMutableArray alloc] init];
|
|
192
|
+
NSUInteger lastRangeLocation = range.location;
|
|
193
|
+
NSUInteger endLocation = range.location + range.length;
|
|
194
|
+
|
|
195
|
+
for (NSUInteger i = range.location; i < endLocation; i++) {
|
|
196
|
+
NSRange currentRange = NSMakeRange(i, 1);
|
|
197
|
+
BOOL forbiddenStyleFound = NO;
|
|
198
|
+
|
|
199
|
+
for (id style in activeStyleObjects) {
|
|
200
|
+
if ([style detectStyle:currentRange]) {
|
|
201
|
+
forbiddenStyleFound = YES;
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (forbiddenStyleFound) {
|
|
207
|
+
if (i > lastRangeLocation) {
|
|
208
|
+
NSRange cleanRange =
|
|
209
|
+
NSMakeRange(lastRangeLocation, i - lastRangeLocation);
|
|
210
|
+
[newRanges addObject:[NSValue valueWithRange:cleanRange]];
|
|
211
|
+
}
|
|
212
|
+
lastRangeLocation = i + 1;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (lastRangeLocation < endLocation) {
|
|
217
|
+
NSRange remainingRange =
|
|
218
|
+
NSMakeRange(lastRangeLocation, endLocation - lastRangeLocation);
|
|
219
|
+
[newRanges addObject:[NSValue valueWithRange:remainingRange]];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return newRanges;
|
|
223
|
+
}
|
|
224
|
+
|
|
155
225
|
@end
|
|
@@ -2,5 +2,10 @@
|
|
|
2
2
|
#pragma once
|
|
3
3
|
|
|
4
4
|
@interface ParagraphAttributesUtils : NSObject
|
|
5
|
-
+ (BOOL)handleBackspaceInRange:(NSRange)range
|
|
5
|
+
+ (BOOL)handleBackspaceInRange:(NSRange)range
|
|
6
|
+
replacementText:(NSString *)text
|
|
7
|
+
input:(id)input;
|
|
8
|
+
+ (BOOL)handleParagraphStylesMergeOnBackspace:(NSRange)range
|
|
9
|
+
replacementText:(NSString *)text
|
|
10
|
+
input:(id)input;
|
|
6
11
|
@end
|