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.
Files changed (123) hide show
  1. package/README.md +4 -14
  2. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +4 -1
  3. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +2 -1
  4. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
  5. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
  6. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +0 -45
  7. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +111 -2
  8. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +9 -3
  9. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +2 -0
  10. package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +1 -1
  11. package/android/src/main/java/com/swmansion/enriched/events/OnRequestHtmlResultEvent.kt +33 -0
  12. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +6 -0
  13. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +6 -0
  14. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +42 -1
  15. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +6 -0
  16. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +6 -0
  17. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +6 -0
  18. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +135 -9
  19. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +6 -0
  20. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +5 -0
  21. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +6 -0
  22. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +6 -0
  23. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +6 -0
  24. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +13 -3
  25. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +5 -0
  26. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +5 -0
  27. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +6 -0
  28. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +4 -0
  29. package/android/src/main/java/com/swmansion/enriched/spans/utils/ForceRedrawSpan.kt +13 -0
  30. package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +80 -9
  31. package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +1 -0
  32. package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +188 -5
  33. package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +57 -30
  34. package/android/src/main/java/com/swmansion/enriched/utils/AsyncDrawable.kt +91 -0
  35. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +24 -13
  36. package/android/src/main/java/com/swmansion/enriched/utils/ResourceManager.kt +26 -0
  37. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +3 -0
  38. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +6 -6
  39. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +6 -6
  40. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +19 -19
  41. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +40 -51
  42. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +13 -15
  43. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +23 -21
  44. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +35 -36
  45. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +4 -4
  46. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +13 -14
  47. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/conversions.h +12 -13
  48. package/android/src/main/res/drawable/broken_image.xml +10 -0
  49. package/ios/EnrichedTextInputView.h +27 -12
  50. package/ios/EnrichedTextInputView.mm +906 -547
  51. package/ios/attachments/ImageAttachment.h +10 -0
  52. package/ios/attachments/ImageAttachment.mm +34 -0
  53. package/ios/attachments/MediaAttachment.h +23 -0
  54. package/ios/attachments/MediaAttachment.mm +31 -0
  55. package/ios/config/InputConfig.h +12 -6
  56. package/ios/config/InputConfig.mm +71 -33
  57. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
  58. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
  59. package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +0 -45
  60. package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +41 -4
  61. package/ios/inputParser/InputParser.h +5 -5
  62. package/ios/inputParser/InputParser.mm +867 -333
  63. package/ios/inputTextView/InputTextView.h +1 -1
  64. package/ios/inputTextView/InputTextView.mm +100 -59
  65. package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +11 -9
  66. package/ios/internals/EnrichedTextInputViewShadowNode.h +28 -24
  67. package/ios/internals/EnrichedTextInputViewShadowNode.mm +64 -47
  68. package/ios/internals/EnrichedTextInputViewState.h +3 -1
  69. package/ios/styles/BlockQuoteStyle.mm +192 -142
  70. package/ios/styles/BoldStyle.mm +96 -62
  71. package/ios/styles/CodeBlockStyle.mm +304 -0
  72. package/ios/styles/H1Style.mm +10 -3
  73. package/ios/styles/H2Style.mm +10 -3
  74. package/ios/styles/H3Style.mm +10 -3
  75. package/ios/styles/HeadingStyleBase.mm +129 -84
  76. package/ios/styles/ImageStyle.mm +160 -0
  77. package/ios/styles/InlineCodeStyle.mm +149 -84
  78. package/ios/styles/ItalicStyle.mm +77 -51
  79. package/ios/styles/LinkStyle.mm +353 -224
  80. package/ios/styles/MentionStyle.mm +434 -220
  81. package/ios/styles/OrderedListStyle.mm +172 -105
  82. package/ios/styles/StrikethroughStyle.mm +53 -34
  83. package/ios/styles/UnderlineStyle.mm +69 -45
  84. package/ios/styles/UnorderedListStyle.mm +170 -105
  85. package/ios/utils/BaseStyleProtocol.h +3 -2
  86. package/ios/utils/ColorExtension.mm +7 -5
  87. package/ios/utils/FontExtension.mm +42 -27
  88. package/ios/utils/ImageData.h +10 -0
  89. package/ios/utils/ImageData.mm +4 -0
  90. package/ios/utils/LayoutManagerExtension.h +1 -1
  91. package/ios/utils/LayoutManagerExtension.mm +334 -109
  92. package/ios/utils/MentionParams.h +0 -1
  93. package/ios/utils/MentionStyleProps.h +1 -1
  94. package/ios/utils/MentionStyleProps.mm +27 -20
  95. package/ios/utils/OccurenceUtils.h +42 -38
  96. package/ios/utils/OccurenceUtils.mm +177 -107
  97. package/ios/utils/ParagraphAttributesUtils.h +6 -1
  98. package/ios/utils/ParagraphAttributesUtils.mm +152 -41
  99. package/ios/utils/ParagraphsUtils.h +2 -1
  100. package/ios/utils/ParagraphsUtils.mm +40 -26
  101. package/ios/utils/StringExtension.h +1 -1
  102. package/ios/utils/StringExtension.mm +19 -16
  103. package/ios/utils/StyleHeaders.h +35 -11
  104. package/ios/utils/TextInsertionUtils.h +13 -2
  105. package/ios/utils/TextInsertionUtils.mm +38 -20
  106. package/ios/utils/WordsUtils.h +2 -1
  107. package/ios/utils/WordsUtils.mm +32 -22
  108. package/ios/utils/ZeroWidthSpaceUtils.h +3 -1
  109. package/ios/utils/ZeroWidthSpaceUtils.mm +153 -75
  110. package/lib/module/EnrichedTextInput.js +41 -3
  111. package/lib/module/EnrichedTextInput.js.map +1 -1
  112. package/lib/module/EnrichedTextInputNativeComponent.ts +17 -5
  113. package/lib/module/normalizeHtmlStyle.js +0 -4
  114. package/lib/module/normalizeHtmlStyle.js.map +1 -1
  115. package/lib/typescript/src/EnrichedTextInput.d.ts +2 -5
  116. package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
  117. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +7 -5
  118. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
  119. package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +1 -1
  120. package/package.json +8 -1
  121. package/src/EnrichedTextInput.tsx +48 -7
  122. package/src/EnrichedTextInputNativeComponent.ts +17 -5
  123. 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:(folly::dynamic)folly {
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(facebook::react::Color(folly["color"].asInt()));
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(facebook::react::Color(folly["backgroundColor"].asInt()));
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] isEqualToString:DecorationUnderline] ? DecorationUnderline : DecorationNone;
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 = [MentionStyleProps getSingleMentionStylePropsFromFollyDynamic:folly];
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& obj: folly.items()) {
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 getSingleMentionStylePropsFromFollyDynamic:obj.second];
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
- :(NSAttributedStringKey _Nonnull)key
9
- withInput:(EnrichedTextInputView* _Nonnull)input
10
- inRange:(NSRange)range
11
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition;
12
- + (BOOL)detect
13
- :(NSAttributedStringKey _Nonnull)key
14
- withInput:(EnrichedTextInputView* _Nonnull)input
15
- atIndex:(NSUInteger)index
16
- checkPrevious:(BOOL)check
17
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition;
18
- + (BOOL)detectMultiple
19
- :(NSArray<NSAttributedStringKey> *_Nonnull)keys
20
- withInput:(EnrichedTextInputView* _Nonnull)input
21
- inRange:(NSRange)range
22
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition;
23
- + (BOOL)any
24
- :(NSAttributedStringKey _Nonnull)key
25
- withInput:(EnrichedTextInputView* _Nonnull)input
26
- inRange:(NSRange)range
27
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition;
28
- + (BOOL)anyMultiple
29
- :(NSArray<NSAttributedStringKey> *_Nonnull)keys
30
- withInput:(EnrichedTextInputView* _Nonnull)input
31
- inRange:(NSRange)range
32
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition;
33
- + (NSArray<StylePair *> *_Nullable)all
34
- :(NSAttributedStringKey _Nonnull)key
35
- withInput:(EnrichedTextInputView* _Nonnull)input
36
- inRange:(NSRange)range
37
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition;
38
- + (NSArray<StylePair *> *_Nullable)allMultiple
39
- :(NSArray<NSAttributedStringKey> *_Nonnull)keys
40
- withInput:(EnrichedTextInputView* _Nonnull)input
41
- inRange:(NSRange)range
42
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition;
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
- :(NSAttributedStringKey _Nonnull)key
7
- withInput:(EnrichedTextInputView* _Nonnull)input
8
- inRange:(NSRange)range
9
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition
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 enumerateAttribute:key inRange:range options:0 usingBlock:
13
- ^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
14
- if(condition(value, range)) {
15
- totalLength += range.length;
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 detection is not in input's selected range and at the end of the input
24
- + (BOOL)detect
25
- :(NSAttributedStringKey _Nonnull)key
26
- withInput:(EnrichedTextInputView* _Nonnull)input
27
- atIndex:(NSUInteger)index
28
- checkPrevious:(BOOL)checkPrev
29
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition
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 paragraphRangeForRange:detectionRange];
38
- if(paragraphRange.location == detectionRange.location) {
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 withInput:input inRange:NSMakeRange(paragraphRange.location, 1) withCondition:condition];
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 atIndex:index effectiveRange:&attrRange];
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
- :(NSArray<NSAttributedStringKey> *_Nonnull)keys
55
- withInput:(EnrichedTextInputView* _Nonnull)input
56
- inRange:(NSRange)range
57
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition
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* key in keys) {
61
- [input->textView.textStorage enumerateAttribute:key inRange:range options:0 usingBlock:
62
- ^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
63
- if(condition(value, range)) {
64
- totalLength += range.length;
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
- :(NSAttributedStringKey _Nonnull)key
74
- withInput:(EnrichedTextInputView* _Nonnull)input
75
- inRange:(NSRange)range
76
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition
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 enumerateAttribute:key inRange:range options:0 usingBlock:
80
- ^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
81
- if(condition(value, range)) {
82
- found = YES;
83
- *stop = YES;
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
- :(NSArray<NSAttributedStringKey> *_Nonnull)keys
92
- withInput:(EnrichedTextInputView* _Nonnull)input
93
- inRange:(NSRange)range
94
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition
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 enumerateAttribute:key inRange:range options:0 usingBlock:
99
- ^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
100
- if(condition(value, range)) {
101
- found = YES;
102
- *stop = YES;
103
- }
104
- }
105
- ];
106
- if(found) {
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
- :(NSAttributedStringKey _Nonnull)key
115
- withInput:(EnrichedTextInputView* _Nonnull)input
116
- inRange:(NSRange)range
117
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition
118
- {
119
- __block NSMutableArray<StylePair *> *occurences = [[NSMutableArray<StylePair *> alloc] init];
120
- [input->textView.textStorage enumerateAttribute:key inRange:range options:0 usingBlock:
121
- ^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
122
- if(condition(value, range)) {
123
- StylePair *pair = [[StylePair alloc] init];
124
- pair.rangeValue = [NSValue valueWithRange:range];
125
- pair.styleValue = value;
126
- [occurences addObject:pair];
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)allMultiple
134
- :(NSArray<NSAttributedStringKey> *_Nonnull)keys
135
- withInput:(EnrichedTextInputView* _Nonnull)input
136
- inRange:(NSRange)range
137
- withCondition:(BOOL (NS_NOESCAPE ^_Nonnull)(id _Nullable value, NSRange range))condition
138
- {
139
- __block NSMutableArray<StylePair *> *occurences = [[NSMutableArray<StylePair *> alloc] init];
140
- for(NSString *key in keys) {
141
- [input->textView.textStorage enumerateAttribute:key inRange:range options:0 usingBlock:
142
- ^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
143
- if(condition(value, range)) {
144
- StylePair *pair = [[StylePair alloc] init];
145
- pair.rangeValue = [NSValue valueWithRange:range];
146
- pair.styleValue = value;
147
- [occurences addObject:pair];
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 replacementText:(NSString *)text input:(id)input;
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