react-native-enriched 0.2.0 → 0.3.0
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 +16 -17
- package/android/build.gradle +77 -72
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +21 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +7 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +156 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +147 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.cpp +10 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +194 -0
- package/android/lint.gradle +70 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputConnectionWrapper.kt +140 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +304 -83
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewLayoutManager.kt +3 -1
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +166 -51
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +1 -3
- package/android/src/main/java/com/swmansion/enriched/MeasurementStore.kt +70 -21
- package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +21 -11
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeHtmlEvent.kt +8 -9
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeSelectionEvent.kt +10 -9
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateDeprecatedEvent.kt +21 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateEvent.kt +9 -12
- package/android/src/main/java/com/swmansion/enriched/events/OnChangeTextEvent.kt +10 -10
- package/android/src/main/java/com/swmansion/enriched/events/OnInputBlurEvent.kt +7 -9
- package/android/src/main/java/com/swmansion/enriched/events/OnInputFocusEvent.kt +7 -9
- package/android/src/main/java/com/swmansion/enriched/events/OnInputKeyPressEvent.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/events/OnLinkDetectedEvent.kt +13 -11
- package/android/src/main/java/com/swmansion/enriched/events/OnMentionDetectedEvent.kt +10 -9
- package/android/src/main/java/com/swmansion/enriched/events/OnMentionEvent.kt +9 -8
- package/android/src/main/java/com/swmansion/enriched/events/OnRequestHtmlResultEvent.kt +32 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +24 -5
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +8 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +10 -2
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +8 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +8 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +8 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH4Span.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH5Span.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH6Span.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +34 -17
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +8 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +7 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +10 -4
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +14 -11
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +18 -11
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +174 -72
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +7 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +7 -1
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +11 -5
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedBlockSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedHeadingSpan.kt +1 -2
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedInlineSpan.kt +1 -2
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedParagraphSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedZeroWidthSpaceSpan.kt +1 -2
- package/android/src/main/java/com/swmansion/enriched/spans/utils/ForceRedrawSpan.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +155 -20
- package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +25 -8
- package/android/src/main/java/com/swmansion/enriched/styles/ListStyles.kt +60 -20
- package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +161 -25
- package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +128 -52
- package/android/src/main/java/com/swmansion/enriched/utils/AsyncDrawable.kt +10 -7
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedConstants.kt +11 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedEditableFactory.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +136 -87
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSelection.kt +71 -42
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpanState.kt +183 -48
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpannable.kt +82 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpannableStringBuilder.kt +15 -0
- package/android/src/main/java/com/swmansion/enriched/utils/Utils.kt +0 -70
- package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +46 -14
- package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedTextWatcher.kt +34 -11
- package/android/src/main/new_arch/CMakeLists.txt +6 -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 +33 -14
- package/ios/EnrichedTextInputView.h +26 -14
- package/ios/EnrichedTextInputView.mm +1209 -586
- package/ios/config/InputConfig.h +24 -6
- package/ios/config/InputConfig.mm +154 -38
- package/ios/{utils → extensions}/ColorExtension.mm +7 -5
- package/ios/extensions/FontExtension.mm +106 -0
- package/ios/{utils → extensions}/LayoutManagerExtension.h +1 -1
- package/ios/extensions/LayoutManagerExtension.mm +396 -0
- package/ios/{utils → extensions}/StringExtension.mm +19 -16
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +156 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +147 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/Props.cpp +10 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +194 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +95 -0
- package/ios/inputParser/InputParser.h +5 -5
- package/ios/inputParser/InputParser.mm +864 -380
- package/ios/inputTextView/InputTextView.h +1 -1
- package/ios/inputTextView/InputTextView.mm +100 -59
- package/ios/{utils → interfaces}/BaseStyleProtocol.h +2 -2
- package/ios/interfaces/ImageAttachment.h +10 -0
- package/ios/interfaces/ImageAttachment.mm +36 -0
- package/ios/interfaces/LinkRegexConfig.h +19 -0
- package/ios/interfaces/LinkRegexConfig.mm +37 -0
- package/ios/interfaces/MediaAttachment.h +23 -0
- package/ios/interfaces/MediaAttachment.mm +31 -0
- package/ios/{utils → interfaces}/MentionParams.h +0 -1
- package/ios/{utils → interfaces}/MentionStyleProps.mm +27 -20
- package/ios/{utils → interfaces}/StyleHeaders.h +37 -15
- package/ios/{utils → interfaces}/StyleTypeEnum.h +3 -0
- package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +11 -9
- package/ios/internals/EnrichedTextInputViewShadowNode.h +28 -25
- package/ios/internals/EnrichedTextInputViewShadowNode.mm +45 -40
- package/ios/internals/EnrichedTextInputViewState.h +3 -1
- package/ios/styles/BlockQuoteStyle.mm +189 -118
- package/ios/styles/BoldStyle.mm +110 -63
- package/ios/styles/CodeBlockStyle.mm +204 -128
- package/ios/styles/H1Style.mm +10 -4
- package/ios/styles/H2Style.mm +10 -4
- package/ios/styles/H3Style.mm +10 -4
- package/ios/styles/H4Style.mm +17 -0
- package/ios/styles/H5Style.mm +17 -0
- package/ios/styles/H6Style.mm +17 -0
- package/ios/styles/HeadingStyleBase.mm +148 -86
- package/ios/styles/ImageStyle.mm +75 -73
- package/ios/styles/InlineCodeStyle.mm +162 -88
- package/ios/styles/ItalicStyle.mm +76 -52
- package/ios/styles/LinkStyle.mm +411 -232
- package/ios/styles/MentionStyle.mm +363 -246
- package/ios/styles/OrderedListStyle.mm +171 -106
- package/ios/styles/StrikethroughStyle.mm +52 -35
- package/ios/styles/UnderlineStyle.mm +68 -46
- package/ios/styles/UnorderedListStyle.mm +169 -106
- package/ios/utils/OccurenceUtils.h +42 -42
- package/ios/utils/OccurenceUtils.mm +142 -119
- package/ios/utils/ParagraphAttributesUtils.h +10 -2
- package/ios/utils/ParagraphAttributesUtils.mm +182 -71
- package/ios/utils/ParagraphsUtils.h +2 -1
- package/ios/utils/ParagraphsUtils.mm +41 -27
- 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 +145 -79
- package/lib/module/EnrichedTextInput.js +61 -2
- package/lib/module/EnrichedTextInput.js.map +1 -1
- package/lib/module/EnrichedTextInputNativeComponent.ts +149 -12
- package/lib/module/{normalizeHtmlStyle.js → utils/normalizeHtmlStyle.js} +12 -0
- package/lib/module/utils/normalizeHtmlStyle.js.map +1 -0
- package/lib/module/utils/regexParser.js +46 -0
- package/lib/module/utils/regexParser.js.map +1 -0
- package/lib/typescript/src/EnrichedTextInput.d.ts +24 -14
- package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +129 -12
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts +4 -0
- package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts.map +1 -0
- package/lib/typescript/src/utils/regexParser.d.ts +3 -0
- package/lib/typescript/src/utils/regexParser.d.ts.map +1 -0
- package/package.json +17 -6
- package/src/EnrichedTextInput.tsx +96 -13
- package/src/EnrichedTextInputNativeComponent.ts +149 -12
- package/src/index.tsx +2 -0
- package/src/{normalizeHtmlStyle.ts → utils/normalizeHtmlStyle.ts} +14 -2
- package/src/utils/regexParser.ts +56 -0
- package/ios/utils/FontExtension.mm +0 -91
- package/ios/utils/LayoutManagerExtension.mm +0 -286
- package/lib/module/normalizeHtmlStyle.js.map +0 -1
- package/lib/typescript/src/normalizeHtmlStyle.d.ts +0 -4
- package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +0 -1
- package/ios/{utils → extensions}/ColorExtension.h +0 -0
- package/ios/{utils → extensions}/FontExtension.h +0 -0
- package/ios/{utils → extensions}/StringExtension.h +1 -1
- package/ios/{utils → interfaces}/ImageData.h +0 -0
- package/ios/{utils → interfaces}/ImageData.mm +0 -0
- package/ios/{utils → interfaces}/LinkData.h +0 -0
- package/ios/{utils → interfaces}/LinkData.mm +0 -0
- package/ios/{utils → interfaces}/MentionParams.mm +0 -0
- package/ios/{utils → interfaces}/MentionStyleProps.h +1 -1
- /package/ios/{utils → interfaces}/StylePair.h +0 -0
- /package/ios/{utils → interfaces}/StylePair.mm +0 -0
- /package/ios/{utils → interfaces}/TextDecorationLineEnum.h +0 -0
- /package/ios/{utils → interfaces}/TextDecorationLineEnum.mm +0 -0
|
@@ -1,59 +1,84 @@
|
|
|
1
1
|
#import "ParagraphAttributesUtils.h"
|
|
2
2
|
#import "EnrichedTextInputView.h"
|
|
3
|
-
#import "StyleHeaders.h"
|
|
4
3
|
#import "ParagraphsUtils.h"
|
|
4
|
+
#import "StyleHeaders.h"
|
|
5
5
|
#import "TextInsertionUtils.h"
|
|
6
6
|
|
|
7
7
|
@implementation ParagraphAttributesUtils
|
|
8
8
|
|
|
9
|
-
// if the user backspaces the last character in a line, the iOS applies typing
|
|
10
|
-
// in the case of some paragraph styles it
|
|
11
|
-
//
|
|
12
|
-
|
|
9
|
+
// if the user backspaces the last character in a line, the iOS applies typing
|
|
10
|
+
// attributes from the previous line in the case of some paragraph styles it
|
|
11
|
+
// works especially bad when a list point just appears this method handles that
|
|
12
|
+
// case differently with or without present paragraph styles
|
|
13
|
+
+ (BOOL)handleBackspaceInRange:(NSRange)range
|
|
14
|
+
replacementText:(NSString *)text
|
|
15
|
+
input:(id)input {
|
|
13
16
|
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)input;
|
|
14
|
-
UnorderedListStyle *ulStyle =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
UnorderedListStyle *ulStyle =
|
|
18
|
+
typedInput->stylesDict[@([UnorderedListStyle getStyleType])];
|
|
19
|
+
OrderedListStyle *olStyle =
|
|
20
|
+
typedInput->stylesDict[@([OrderedListStyle getStyleType])];
|
|
21
|
+
BlockQuoteStyle *bqStyle =
|
|
22
|
+
typedInput->stylesDict[@([BlockQuoteStyle getStyleType])];
|
|
23
|
+
CodeBlockStyle *cbStyle =
|
|
24
|
+
typedInput->stylesDict[@([CodeBlockStyle getStyleType])];
|
|
25
|
+
|
|
26
|
+
if (typedInput == nullptr) {
|
|
20
27
|
return NO;
|
|
21
28
|
}
|
|
22
|
-
|
|
23
|
-
// we make sure it was a backspace (text with 0 length) and it deleted
|
|
24
|
-
|
|
29
|
+
|
|
30
|
+
// we make sure it was a backspace (text with 0 length) and it deleted
|
|
31
|
+
// something (range longer than 0)
|
|
32
|
+
if (text.length > 0 || range.length == 0) {
|
|
25
33
|
return NO;
|
|
26
34
|
}
|
|
27
|
-
|
|
35
|
+
|
|
28
36
|
// find a non-newline range of the paragraph
|
|
29
|
-
NSRange paragraphRange =
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
NSRange paragraphRange =
|
|
38
|
+
[typedInput->textView.textStorage.string paragraphRangeForRange:range];
|
|
39
|
+
|
|
40
|
+
NSArray *paragraphs =
|
|
41
|
+
[ParagraphsUtils getNonNewlineRangesIn:typedInput->textView
|
|
42
|
+
range:paragraphRange];
|
|
43
|
+
if (paragraphs.count == 0) {
|
|
33
44
|
return NO;
|
|
34
45
|
}
|
|
35
|
-
|
|
46
|
+
|
|
36
47
|
NSRange nonNewlineRange = [(NSValue *)paragraphs.firstObject rangeValue];
|
|
37
|
-
|
|
38
|
-
// the backspace removes the whole content of a paragraph (possibly more but
|
|
39
|
-
|
|
40
|
-
|
|
48
|
+
|
|
49
|
+
// the backspace removes the whole content of a paragraph (possibly more but
|
|
50
|
+
// has to start where the paragraph starts)
|
|
51
|
+
if (range.location == nonNewlineRange.location &&
|
|
52
|
+
range.length >= nonNewlineRange.length) {
|
|
53
|
+
|
|
41
54
|
// for lists, quotes and codeblocks present we do the following:
|
|
42
55
|
// - manually do the removing
|
|
43
|
-
// - reset typing attribtues so that the previous line styles don't get
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
[
|
|
56
|
+
// - reset typing attribtues so that the previous line styles don't get
|
|
57
|
+
// applied
|
|
58
|
+
// - reapply the paragraph style that was present so that a zero width space
|
|
59
|
+
// appears here
|
|
60
|
+
NSArray *handledStyles = @[ ulStyle, olStyle, bqStyle, cbStyle ];
|
|
61
|
+
for (id<BaseStyleProtocol> style in handledStyles) {
|
|
62
|
+
if ([style detectStyle:nonNewlineRange]) {
|
|
63
|
+
[TextInsertionUtils replaceText:text
|
|
64
|
+
at:range
|
|
65
|
+
additionalAttributes:nullptr
|
|
66
|
+
input:typedInput
|
|
67
|
+
withSelection:YES];
|
|
68
|
+
typedInput->textView.typingAttributes =
|
|
69
|
+
typedInput->defaultTypingAttributes;
|
|
70
|
+
[style addAttributes:NSMakeRange(range.location, 0) withTypingAttr:YES];
|
|
51
71
|
return YES;
|
|
52
72
|
}
|
|
53
73
|
}
|
|
54
|
-
|
|
55
|
-
// otherwise (no paragraph styles present), we just do the replacement
|
|
56
|
-
|
|
74
|
+
|
|
75
|
+
// otherwise (no paragraph styles present), we just do the replacement
|
|
76
|
+
// manually and reset typing attribtues
|
|
77
|
+
[TextInsertionUtils replaceText:text
|
|
78
|
+
at:range
|
|
79
|
+
additionalAttributes:nullptr
|
|
80
|
+
input:typedInput
|
|
81
|
+
withSelection:YES];
|
|
57
82
|
typedInput->textView.typingAttributes = typedInput->defaultTypingAttributes;
|
|
58
83
|
return YES;
|
|
59
84
|
}
|
|
@@ -62,73 +87,159 @@
|
|
|
62
87
|
}
|
|
63
88
|
|
|
64
89
|
/**
|
|
65
|
-
* Handles the specific case of backspacing a newline character, which results
|
|
90
|
+
* Handles the specific case of backspacing a newline character, which results
|
|
91
|
+
* in merging two paragraphs.
|
|
66
92
|
*
|
|
67
93
|
* THE PROBLEM:
|
|
68
|
-
* When merging a bottom paragraph (Source) into a top paragraph (Destination),
|
|
69
|
-
* normally brings all its attributes with it. If the top
|
|
70
|
-
*
|
|
94
|
+
* When merging a bottom paragraph (Source) into a top paragraph (Destination),
|
|
95
|
+
* the bottom paragraph normally brings all its attributes with it. If the top
|
|
96
|
+
* paragraph is a restrictive style (like a CodeBlock), and the bottom paragraph
|
|
97
|
+
* contains a conflicting style (like an H1 Header), a standard merge would
|
|
71
98
|
* create an invalid state (e.g., a CodeBlock that is also a Header).
|
|
72
99
|
*
|
|
73
100
|
* THE SOLUTION:
|
|
74
|
-
* 1. Identifies the dominant style of the paragraph ABOVE the deleted newline
|
|
75
|
-
*
|
|
76
|
-
*
|
|
101
|
+
* 1. Identifies the dominant style of the paragraph ABOVE the deleted newline
|
|
102
|
+
* (`leftParagraphStyle`).
|
|
103
|
+
* 2. Checks the paragraph BELOW the newline (`rightRange`) for any styles that
|
|
104
|
+
* conflict with or are blocked by the top style.
|
|
105
|
+
* 3. Explicitly removes those forbidden styles from the bottom paragraph
|
|
106
|
+
* *before* the merge occurs.
|
|
77
107
|
* 4. Performs the merge (deletes the newline).
|
|
78
108
|
*
|
|
79
109
|
* @return YES if the newline backspace was handled and sanitized; NO otherwise.
|
|
80
110
|
*/
|
|
81
|
-
+ (BOOL)
|
|
111
|
+
+ (BOOL)handleParagraphStylesMergeOnBackspace:(NSRange)range
|
|
112
|
+
replacementText:(NSString *)text
|
|
113
|
+
input:(id)input {
|
|
82
114
|
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)input;
|
|
83
|
-
if(typedInput == nullptr) {
|
|
115
|
+
if (typedInput == nullptr) {
|
|
84
116
|
return NO;
|
|
85
117
|
}
|
|
86
|
-
|
|
87
|
-
if(text.length == 0
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
118
|
+
|
|
119
|
+
if (text.length == 0) {
|
|
120
|
+
NSRange leftRange = [typedInput->textView.textStorage.string
|
|
121
|
+
paragraphRangeForRange:NSMakeRange(range.location, 0)];
|
|
122
|
+
|
|
91
123
|
id<BaseStyleProtocol> leftParagraphStyle = nullptr;
|
|
92
124
|
for (NSNumber *key in typedInput->stylesDict) {
|
|
93
125
|
id<BaseStyleProtocol> style = typedInput->stylesDict[key];
|
|
94
|
-
if([[style class] isParagraphStyle] && [style detectStyle:leftRange]) {
|
|
126
|
+
if ([[style class] isParagraphStyle] && [style detectStyle:leftRange]) {
|
|
95
127
|
leftParagraphStyle = style;
|
|
96
128
|
}
|
|
97
129
|
}
|
|
98
|
-
|
|
99
|
-
if(leftParagraphStyle == nullptr) {
|
|
130
|
+
|
|
131
|
+
if (leftParagraphStyle == nullptr) {
|
|
100
132
|
return NO;
|
|
101
133
|
}
|
|
102
|
-
|
|
134
|
+
|
|
103
135
|
// index out of bounds
|
|
104
|
-
|
|
136
|
+
NSUInteger rightRangeStart = range.location + range.length;
|
|
137
|
+
if (rightRangeStart >= typedInput->textView.textStorage.string.length) {
|
|
105
138
|
return NO;
|
|
106
139
|
}
|
|
107
|
-
|
|
108
|
-
NSRange rightRange = [typedInput->textView.textStorage.string
|
|
109
|
-
|
|
140
|
+
|
|
141
|
+
NSRange rightRange = [typedInput->textView.textStorage.string
|
|
142
|
+
paragraphRangeForRange:NSMakeRange(rightRangeStart, 1)];
|
|
143
|
+
|
|
110
144
|
StyleType type = [[leftParagraphStyle class] getStyleType];
|
|
111
|
-
|
|
112
|
-
NSArray *conflictingStyles = [typedInput
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
145
|
+
|
|
146
|
+
NSArray *conflictingStyles = [typedInput
|
|
147
|
+
getPresentStyleTypesFrom:typedInput->conflictingStyles[@(type)]
|
|
148
|
+
range:rightRange];
|
|
149
|
+
NSArray *blockingStyles =
|
|
150
|
+
[typedInput getPresentStyleTypesFrom:typedInput->blockingStyles[@(type)]
|
|
151
|
+
range:rightRange];
|
|
152
|
+
NSArray *allToBeRemoved =
|
|
153
|
+
[conflictingStyles arrayByAddingObjectsFromArray:blockingStyles];
|
|
154
|
+
|
|
155
|
+
for (NSNumber *style in allToBeRemoved) {
|
|
117
156
|
id<BaseStyleProtocol> styleClass = typedInput->stylesDict[style];
|
|
118
|
-
|
|
157
|
+
|
|
119
158
|
// for ranges, we need to remove each occurence
|
|
120
|
-
NSArray<StylePair *> *allOccurences =
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
159
|
+
NSArray<StylePair *> *allOccurences =
|
|
160
|
+
[styleClass findAllOccurences:rightRange];
|
|
161
|
+
|
|
162
|
+
for (StylePair *pair in allOccurences) {
|
|
163
|
+
[styleClass removeAttributes:[pair.rangeValue rangeValue]];
|
|
124
164
|
}
|
|
125
165
|
}
|
|
126
|
-
|
|
127
|
-
[TextInsertionUtils replaceText:text
|
|
166
|
+
|
|
167
|
+
[TextInsertionUtils replaceText:text
|
|
168
|
+
at:range
|
|
169
|
+
additionalAttributes:nullptr
|
|
170
|
+
input:typedInput
|
|
171
|
+
withSelection:YES];
|
|
172
|
+
return YES;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return NO;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Resets typing attributes to defaults when the cursor lands on an empty line
|
|
180
|
+
* after a deletion.
|
|
181
|
+
*
|
|
182
|
+
* This override is necessary because `UITextView` automatically inherits
|
|
183
|
+
* attributes from the preceding newline. This prevents scenarios where a
|
|
184
|
+
* restrictive style (like CodeBlock) "leaks" into the next empty paragraph.
|
|
185
|
+
*/
|
|
186
|
+
+ (BOOL)handleResetTypingAttributesOnBackspace:(NSRange)range
|
|
187
|
+
replacementText:(NSString *)text
|
|
188
|
+
input:(id)input {
|
|
189
|
+
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)input;
|
|
190
|
+
if (typedInput == nullptr) {
|
|
191
|
+
return NO;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
NSString *storageString = typedInput->textView.textStorage.string;
|
|
195
|
+
|
|
196
|
+
if (text.length > 0 || range.location >= storageString.length) {
|
|
197
|
+
return NO;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
unichar firstCharToDelete = [storageString characterAtIndex:range.location];
|
|
201
|
+
if (![[NSCharacterSet newlineCharacterSet]
|
|
202
|
+
characterIsMember:firstCharToDelete]) {
|
|
203
|
+
return NO;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
NSRange leftParagraphRange =
|
|
207
|
+
[storageString paragraphRangeForRange:NSMakeRange(range.location, 0)];
|
|
208
|
+
BOOL isLeftLineEmpty = [self isParagraphEmpty:leftParagraphRange
|
|
209
|
+
inString:storageString];
|
|
210
|
+
|
|
211
|
+
BOOL isRightLineEmpty = YES;
|
|
212
|
+
NSUInteger rightRangeStart = range.location + range.length;
|
|
213
|
+
|
|
214
|
+
if (rightRangeStart < storageString.length) {
|
|
215
|
+
NSRange rightParagraphRange =
|
|
216
|
+
[storageString paragraphRangeForRange:NSMakeRange(rightRangeStart, 0)];
|
|
217
|
+
isRightLineEmpty = [self isParagraphEmpty:rightParagraphRange
|
|
218
|
+
inString:storageString];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (isLeftLineEmpty && isRightLineEmpty) {
|
|
222
|
+
[TextInsertionUtils replaceText:text
|
|
223
|
+
at:range
|
|
224
|
+
additionalAttributes:nullptr
|
|
225
|
+
input:typedInput
|
|
226
|
+
withSelection:YES];
|
|
227
|
+
|
|
228
|
+
typedInput->textView.typingAttributes = typedInput->defaultTypingAttributes;
|
|
128
229
|
return YES;
|
|
129
230
|
}
|
|
130
|
-
|
|
231
|
+
|
|
131
232
|
return NO;
|
|
132
233
|
}
|
|
133
234
|
|
|
235
|
+
+ (BOOL)isParagraphEmpty:(NSRange)range inString:(NSString *)string {
|
|
236
|
+
if (range.length == 0)
|
|
237
|
+
return YES;
|
|
238
|
+
|
|
239
|
+
NSString *paragraphText = [string substringWithRange:range];
|
|
240
|
+
NSString *trimmed = [paragraphText
|
|
241
|
+
stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
|
|
242
|
+
return trimmed.length == 0;
|
|
243
|
+
}
|
|
244
|
+
|
|
134
245
|
@end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#import <UIKit/UIKit.h>
|
|
3
3
|
|
|
4
4
|
@interface ParagraphsUtils : NSObject
|
|
5
|
-
+ (NSArray *)getSeparateParagraphsRangesIn:(UITextView *)textView
|
|
5
|
+
+ (NSArray *)getSeparateParagraphsRangesIn:(UITextView *)textView
|
|
6
|
+
range:(NSRange)range;
|
|
6
7
|
+ (NSArray *)getNonNewlineRangesIn:(UITextView *)textView range:(NSRange)range;
|
|
7
8
|
@end
|
|
@@ -2,52 +2,66 @@
|
|
|
2
2
|
|
|
3
3
|
@implementation ParagraphsUtils
|
|
4
4
|
|
|
5
|
-
+ (NSArray *)getSeparateParagraphsRangesIn:(UITextView *)textView
|
|
5
|
+
+ (NSArray *)getSeparateParagraphsRangesIn:(UITextView *)textView
|
|
6
|
+
range:(NSRange)range {
|
|
6
7
|
// just in case, get full paragraphs range
|
|
7
|
-
NSRange fullRange =
|
|
8
|
-
|
|
8
|
+
NSRange fullRange =
|
|
9
|
+
[textView.textStorage.string paragraphRangeForRange:range];
|
|
10
|
+
|
|
9
11
|
// we are in an empty paragraph
|
|
10
|
-
if(fullRange.length == 0) {
|
|
11
|
-
return @[[NSValue valueWithRange:fullRange]];
|
|
12
|
+
if (fullRange.length == 0) {
|
|
13
|
+
return @[ [NSValue valueWithRange:fullRange] ];
|
|
12
14
|
}
|
|
13
|
-
|
|
15
|
+
|
|
14
16
|
NSMutableArray *results = [[NSMutableArray alloc] init];
|
|
15
|
-
|
|
17
|
+
|
|
16
18
|
NSInteger lastStart = fullRange.location;
|
|
17
|
-
for(int i = fullRange.location;
|
|
19
|
+
for (int i = int(fullRange.location);
|
|
20
|
+
i < fullRange.location + fullRange.length; i++) {
|
|
18
21
|
unichar currentChar = [textView.textStorage.string characterAtIndex:i];
|
|
19
|
-
if([[NSCharacterSet newlineCharacterSet] characterIsMember:currentChar]) {
|
|
20
|
-
NSRange paragraphRange = [textView.textStorage.string
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
if ([[NSCharacterSet newlineCharacterSet] characterIsMember:currentChar]) {
|
|
23
|
+
NSRange paragraphRange = [textView.textStorage.string
|
|
24
|
+
paragraphRangeForRange:NSMakeRange(lastStart, i - lastStart)];
|
|
25
|
+
[results addObject:[NSValue valueWithRange:paragraphRange]];
|
|
26
|
+
lastStart = i + 1;
|
|
23
27
|
}
|
|
24
28
|
}
|
|
25
|
-
|
|
26
|
-
if(lastStart < fullRange.location + fullRange.length) {
|
|
27
|
-
NSRange paragraphRange = [textView.textStorage.string
|
|
28
|
-
|
|
29
|
+
|
|
30
|
+
if (lastStart < fullRange.location + fullRange.length) {
|
|
31
|
+
NSRange paragraphRange = [textView.textStorage.string
|
|
32
|
+
paragraphRangeForRange:NSMakeRange(lastStart, fullRange.location +
|
|
33
|
+
fullRange.length -
|
|
34
|
+
lastStart)];
|
|
35
|
+
[results addObject:[NSValue valueWithRange:paragraphRange]];
|
|
29
36
|
}
|
|
30
|
-
|
|
37
|
+
|
|
31
38
|
return results;
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
+ (NSArray *)getNonNewlineRangesIn:(UITextView *)textView range:(NSRange)range {
|
|
35
42
|
NSMutableArray *nonNewlineRanges = [[NSMutableArray alloc] init];
|
|
36
|
-
int lastRangeLocation = range.location;
|
|
37
|
-
|
|
38
|
-
for(int i = range.location; i < range.location + range.length; i++) {
|
|
43
|
+
int lastRangeLocation = int(range.location);
|
|
44
|
+
|
|
45
|
+
for (int i = int(range.location); i < range.location + range.length; i++) {
|
|
39
46
|
unichar currentChar = [textView.textStorage.string characterAtIndex:i];
|
|
40
|
-
if([[NSCharacterSet newlineCharacterSet] characterIsMember:currentChar]) {
|
|
41
|
-
if(i - lastRangeLocation > 0) {
|
|
42
|
-
[nonNewlineRanges
|
|
47
|
+
if ([[NSCharacterSet newlineCharacterSet] characterIsMember:currentChar]) {
|
|
48
|
+
if (i - lastRangeLocation > 0) {
|
|
49
|
+
[nonNewlineRanges
|
|
50
|
+
addObject:[NSValue
|
|
51
|
+
valueWithRange:NSMakeRange(lastRangeLocation,
|
|
52
|
+
i - lastRangeLocation)]];
|
|
43
53
|
}
|
|
44
|
-
lastRangeLocation = i+1;
|
|
54
|
+
lastRangeLocation = i + 1;
|
|
45
55
|
}
|
|
46
56
|
}
|
|
47
|
-
if(lastRangeLocation < range.location + range.length) {
|
|
48
|
-
[nonNewlineRanges
|
|
57
|
+
if (lastRangeLocation < range.location + range.length) {
|
|
58
|
+
[nonNewlineRanges
|
|
59
|
+
addObject:[NSValue
|
|
60
|
+
valueWithRange:NSMakeRange(lastRangeLocation,
|
|
61
|
+
range.location + range.length -
|
|
62
|
+
lastRangeLocation)]];
|
|
49
63
|
}
|
|
50
|
-
|
|
64
|
+
|
|
51
65
|
return nonNewlineRanges;
|
|
52
66
|
}
|
|
53
67
|
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
#import <UIKit/UIKit.h>
|
|
2
2
|
|
|
3
3
|
@interface TextInsertionUtils : NSObject
|
|
4
|
-
+ (void)insertText:(NSString*)text
|
|
5
|
-
|
|
4
|
+
+ (void)insertText:(NSString *)text
|
|
5
|
+
at:(NSInteger)index
|
|
6
|
+
additionalAttributes:
|
|
7
|
+
(NSDictionary<NSAttributedStringKey, id> *)additionalAttrs
|
|
8
|
+
input:(id)input
|
|
9
|
+
withSelection:(BOOL)withSelection;
|
|
10
|
+
+ (void)replaceText:(NSString *)text
|
|
11
|
+
at:(NSRange)range
|
|
12
|
+
additionalAttributes:
|
|
13
|
+
(NSDictionary<NSAttributedStringKey, id> *)additionalAttrs
|
|
14
|
+
input:(id)input
|
|
15
|
+
withSelection:(BOOL)withSelection;
|
|
16
|
+
;
|
|
6
17
|
@end
|
|
@@ -1,24 +1,33 @@
|
|
|
1
1
|
#import "TextInsertionUtils.h"
|
|
2
|
-
#import "UIView+React.h"
|
|
3
2
|
#import "EnrichedTextInputView.h"
|
|
3
|
+
#import "UIView+React.h"
|
|
4
4
|
|
|
5
5
|
@implementation TextInsertionUtils
|
|
6
|
-
+ (void)insertText:(NSString*)text
|
|
6
|
+
+ (void)insertText:(NSString *)text
|
|
7
|
+
at:(NSInteger)index
|
|
8
|
+
additionalAttributes:
|
|
9
|
+
(NSDictionary<NSAttributedStringKey, id> *)additionalAttrs
|
|
10
|
+
input:(id)input
|
|
11
|
+
withSelection:(BOOL)withSelection {
|
|
7
12
|
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)input;
|
|
8
|
-
if(typedInput == nullptr) {
|
|
9
|
-
|
|
13
|
+
if (typedInput == nullptr) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
10
17
|
UITextView *textView = typedInput->textView;
|
|
11
18
|
|
|
12
|
-
NSMutableDictionary<NSAttributedStringKey, id> *copiedAttrs =
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
NSMutableDictionary<NSAttributedStringKey, id> *copiedAttrs =
|
|
20
|
+
[textView.typingAttributes mutableCopy];
|
|
21
|
+
if (additionalAttrs != nullptr) {
|
|
22
|
+
[copiedAttrs addEntriesFromDictionary:additionalAttrs];
|
|
15
23
|
}
|
|
16
|
-
|
|
17
|
-
NSAttributedString *newAttrStr =
|
|
24
|
+
|
|
25
|
+
NSAttributedString *newAttrStr =
|
|
26
|
+
[[NSAttributedString alloc] initWithString:text attributes:copiedAttrs];
|
|
18
27
|
[textView.textStorage insertAttributedString:newAttrStr atIndex:index];
|
|
19
|
-
|
|
20
|
-
if(withSelection) {
|
|
21
|
-
if(![textView isFirstResponder]) {
|
|
28
|
+
|
|
29
|
+
if (withSelection) {
|
|
30
|
+
if (![textView isFirstResponder]) {
|
|
22
31
|
[textView reactFocus];
|
|
23
32
|
}
|
|
24
33
|
textView.selectedRange = NSMakeRange(index + text.length, 0);
|
|
@@ -26,19 +35,28 @@
|
|
|
26
35
|
typedInput->recentlyChangedRange = NSMakeRange(index, text.length);
|
|
27
36
|
}
|
|
28
37
|
|
|
29
|
-
+ (void)replaceText:(NSString*)text
|
|
38
|
+
+ (void)replaceText:(NSString *)text
|
|
39
|
+
at:(NSRange)range
|
|
40
|
+
additionalAttributes:
|
|
41
|
+
(NSDictionary<NSAttributedStringKey, id> *)additionalAttrs
|
|
42
|
+
input:(id)input
|
|
43
|
+
withSelection:(BOOL)withSelection {
|
|
30
44
|
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)input;
|
|
31
|
-
if(typedInput == nullptr) {
|
|
32
|
-
|
|
45
|
+
if (typedInput == nullptr) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
33
49
|
UITextView *textView = typedInput->textView;
|
|
34
50
|
|
|
35
51
|
[textView.textStorage replaceCharactersInRange:range withString:text];
|
|
36
|
-
if(additionalAttrs != nullptr) {
|
|
37
|
-
[textView.textStorage
|
|
52
|
+
if (additionalAttrs != nullptr) {
|
|
53
|
+
[textView.textStorage
|
|
54
|
+
addAttributes:additionalAttrs
|
|
55
|
+
range:NSMakeRange(range.location, [text length])];
|
|
38
56
|
}
|
|
39
|
-
|
|
40
|
-
if(withSelection) {
|
|
41
|
-
if(![textView isFirstResponder]) {
|
|
57
|
+
|
|
58
|
+
if (withSelection) {
|
|
59
|
+
if (![textView isFirstResponder]) {
|
|
42
60
|
[textView reactFocus];
|
|
43
61
|
}
|
|
44
62
|
textView.selectedRange = NSMakeRange(range.location + text.length, 0);
|
package/ios/utils/WordsUtils.h
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#import <UIKit/UIKit.h>
|
|
2
2
|
|
|
3
3
|
@interface WordsUtils : NSObject
|
|
4
|
-
+ (NSArray<NSDictionary *> *)getAffectedWordsFromText:(NSString *)text
|
|
4
|
+
+ (NSArray<NSDictionary *> *)getAffectedWordsFromText:(NSString *)text
|
|
5
|
+
modificationRange:(NSRange)range;
|
|
5
6
|
+ (NSDictionary *)getCurrentWord:(NSString *)text range:(NSRange)range;
|
|
6
7
|
@end
|
package/ios/utils/WordsUtils.mm
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
@implementation WordsUtils
|
|
4
4
|
|
|
5
|
-
+ (NSArray<NSDictionary *> *)getAffectedWordsFromText:(NSString *)text
|
|
6
|
-
|
|
5
|
+
+ (NSArray<NSDictionary *> *)getAffectedWordsFromText:(NSString *)text
|
|
6
|
+
modificationRange:(NSRange)range {
|
|
7
|
+
if (text.length == 0) {
|
|
7
8
|
return [[NSArray alloc] init];
|
|
8
9
|
}
|
|
9
10
|
|
|
@@ -12,7 +13,8 @@
|
|
|
12
13
|
if (leftIt > 0) {
|
|
13
14
|
while (leftIt >= 0) {
|
|
14
15
|
unichar charAtIndex = [text characterAtIndex:leftIt];
|
|
15
|
-
if ([[NSCharacterSet whitespaceAndNewlineCharacterSet]
|
|
16
|
+
if ([[NSCharacterSet whitespaceAndNewlineCharacterSet]
|
|
17
|
+
characterIsMember:charAtIndex]) {
|
|
16
18
|
leftIt += 1;
|
|
17
19
|
break;
|
|
18
20
|
}
|
|
@@ -21,12 +23,13 @@
|
|
|
21
23
|
}
|
|
22
24
|
leftIt = MAX(0, leftIt);
|
|
23
25
|
leftIt = MIN(NSInteger(text.length - 1), leftIt);
|
|
24
|
-
|
|
26
|
+
|
|
25
27
|
NSInteger rightIt = range.location + range.length;
|
|
26
28
|
if (rightIt < text.length - 1) {
|
|
27
29
|
while (rightIt <= text.length - 1) {
|
|
28
30
|
unichar charAtIndex = [text characterAtIndex:rightIt];
|
|
29
|
-
if ([[NSCharacterSet whitespaceAndNewlineCharacterSet]
|
|
31
|
+
if ([[NSCharacterSet whitespaceAndNewlineCharacterSet]
|
|
32
|
+
characterIsMember:charAtIndex]) {
|
|
30
33
|
rightIt -= 1;
|
|
31
34
|
break;
|
|
32
35
|
}
|
|
@@ -34,23 +37,26 @@
|
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
rightIt = MIN(NSInteger(text.length - 1), rightIt);
|
|
37
|
-
|
|
38
|
-
if(leftIt > rightIt) {
|
|
40
|
+
|
|
41
|
+
if (leftIt > rightIt) {
|
|
39
42
|
return [[NSArray alloc] init];
|
|
40
43
|
}
|
|
41
|
-
|
|
42
|
-
NSMutableArray<NSDictionary *> *separatedWords =
|
|
44
|
+
|
|
45
|
+
NSMutableArray<NSDictionary *> *separatedWords =
|
|
46
|
+
[[NSMutableArray<NSDictionary *> alloc] init];
|
|
43
47
|
NSMutableString *currentWord = [[NSMutableString alloc] init];
|
|
44
48
|
NSInteger currentRangeStart = leftIt;
|
|
45
49
|
NSInteger currentIdx = leftIt;
|
|
46
|
-
|
|
50
|
+
|
|
47
51
|
while (currentIdx <= rightIt) {
|
|
48
52
|
unichar charAtIndex = [text characterAtIndex:currentIdx];
|
|
49
|
-
if ([[NSCharacterSet whitespaceAndNewlineCharacterSet]
|
|
53
|
+
if ([[NSCharacterSet whitespaceAndNewlineCharacterSet]
|
|
54
|
+
characterIsMember:charAtIndex]) {
|
|
50
55
|
if (currentWord.length > 0) {
|
|
51
56
|
[separatedWords addObject:@{
|
|
52
|
-
@"word": [currentWord copy],
|
|
53
|
-
@"range": [NSValue
|
|
57
|
+
@"word" : [currentWord copy],
|
|
58
|
+
@"range" : [NSValue
|
|
59
|
+
valueWithRange:NSMakeRange(currentRangeStart, currentWord.length)]
|
|
54
60
|
}];
|
|
55
61
|
[currentWord setString:@""];
|
|
56
62
|
}
|
|
@@ -60,28 +66,32 @@
|
|
|
60
66
|
}
|
|
61
67
|
currentIdx += 1;
|
|
62
68
|
}
|
|
63
|
-
|
|
69
|
+
|
|
64
70
|
if (currentWord.length > 0) {
|
|
65
71
|
[separatedWords addObject:@{
|
|
66
|
-
@"word": [currentWord copy],
|
|
67
|
-
@"range"
|
|
72
|
+
@"word" : [currentWord copy],
|
|
73
|
+
@"range" :
|
|
74
|
+
[NSValue valueWithRange:NSMakeRange(currentRangeStart,
|
|
75
|
+
rightIt - currentRangeStart + 1)]
|
|
68
76
|
}];
|
|
69
77
|
}
|
|
70
|
-
|
|
78
|
+
|
|
71
79
|
return separatedWords;
|
|
72
80
|
}
|
|
73
81
|
|
|
74
82
|
+ (NSDictionary *)getCurrentWord:(NSString *)text range:(NSRange)range {
|
|
75
83
|
// we just get current word at the cursor
|
|
76
|
-
if(range.length > 0) {
|
|
84
|
+
if (range.length > 0) {
|
|
77
85
|
return nullptr;
|
|
78
86
|
}
|
|
79
|
-
|
|
80
|
-
NSArray<NSDictionary *> *words = [WordsUtils getAffectedWordsFromText:text
|
|
81
|
-
|
|
87
|
+
|
|
88
|
+
NSArray<NSDictionary *> *words = [WordsUtils getAffectedWordsFromText:text
|
|
89
|
+
modificationRange:range];
|
|
90
|
+
if (words != nullptr && [words count] == 1 &&
|
|
91
|
+
[words firstObject] != nullptr) {
|
|
82
92
|
return [words firstObject];
|
|
83
93
|
}
|
|
84
|
-
|
|
94
|
+
|
|
85
95
|
return nullptr;
|
|
86
96
|
}
|
|
87
97
|
|
|
@@ -3,5 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
@interface ZeroWidthSpaceUtils : NSObject
|
|
5
5
|
+ (void)handleZeroWidthSpacesInInput:(id)input;
|
|
6
|
-
+ (BOOL)handleBackspaceInRange:(NSRange)range
|
|
6
|
+
+ (BOOL)handleBackspaceInRange:(NSRange)range
|
|
7
|
+
replacementText:(NSString *)text
|
|
8
|
+
input:(id)input;
|
|
7
9
|
@end
|