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
package/ios/styles/BoldStyle.mm
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
#import "StyleHeaders.h"
|
|
2
1
|
#import "EnrichedTextInputView.h"
|
|
3
2
|
#import "FontExtension.h"
|
|
4
3
|
#import "OccurenceUtils.h"
|
|
4
|
+
#import "StyleHeaders.h"
|
|
5
5
|
|
|
6
6
|
@implementation BoldStyle {
|
|
7
7
|
EnrichedTextInputView *_input;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
+ (StyleType)getStyleType {
|
|
10
|
+
+ (StyleType)getStyleType {
|
|
11
|
+
return Bold;
|
|
12
|
+
}
|
|
11
13
|
|
|
12
|
-
+ (BOOL)isParagraphStyle {
|
|
14
|
+
+ (BOOL)isParagraphStyle {
|
|
15
|
+
return NO;
|
|
16
|
+
}
|
|
13
17
|
|
|
14
18
|
- (instancetype)initWithInput:(id)input {
|
|
15
19
|
self = [super init];
|
|
@@ -19,31 +23,39 @@
|
|
|
19
23
|
|
|
20
24
|
- (void)applyStyle:(NSRange)range {
|
|
21
25
|
BOOL isStylePresent = [self detectStyle:range];
|
|
22
|
-
if(range.length >= 1) {
|
|
23
|
-
isStylePresent ? [self removeAttributes:range]
|
|
26
|
+
if (range.length >= 1) {
|
|
27
|
+
isStylePresent ? [self removeAttributes:range]
|
|
28
|
+
: [self addAttributes:range withTypingAttr:YES];
|
|
24
29
|
} else {
|
|
25
30
|
isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
- (void)addAttributes:(NSRange)range {
|
|
34
|
+
- (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
|
|
30
35
|
[_input->textView.textStorage beginEditing];
|
|
31
|
-
[_input->textView.textStorage
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
[_input->textView.textStorage
|
|
37
|
+
enumerateAttribute:NSFontAttributeName
|
|
38
|
+
inRange:range
|
|
39
|
+
options:0
|
|
40
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
41
|
+
BOOL *_Nonnull stop) {
|
|
42
|
+
UIFont *font = (UIFont *)value;
|
|
43
|
+
if (font != nullptr) {
|
|
44
|
+
UIFont *newFont = [font setBold];
|
|
45
|
+
[_input->textView.textStorage addAttribute:NSFontAttributeName
|
|
46
|
+
value:newFont
|
|
47
|
+
range:range];
|
|
48
|
+
}
|
|
49
|
+
}];
|
|
40
50
|
[_input->textView.textStorage endEditing];
|
|
41
51
|
}
|
|
42
52
|
|
|
43
53
|
- (void)addTypingAttributes {
|
|
44
|
-
UIFont *currentFontAttr =
|
|
45
|
-
|
|
46
|
-
|
|
54
|
+
UIFont *currentFontAttr =
|
|
55
|
+
(UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
|
|
56
|
+
if (currentFontAttr != nullptr) {
|
|
57
|
+
NSMutableDictionary *newTypingAttrs =
|
|
58
|
+
[_input->textView.typingAttributes mutableCopy];
|
|
47
59
|
newTypingAttrs[NSFontAttributeName] = [currentFontAttr setBold];
|
|
48
60
|
_input->textView.typingAttributes = newTypingAttrs;
|
|
49
61
|
}
|
|
@@ -51,77 +63,112 @@
|
|
|
51
63
|
|
|
52
64
|
- (void)removeAttributes:(NSRange)range {
|
|
53
65
|
[_input->textView.textStorage beginEditing];
|
|
54
|
-
[_input->textView.textStorage
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
[_input->textView.textStorage
|
|
67
|
+
enumerateAttribute:NSFontAttributeName
|
|
68
|
+
inRange:range
|
|
69
|
+
options:0
|
|
70
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
71
|
+
BOOL *_Nonnull stop) {
|
|
72
|
+
UIFont *font = (UIFont *)value;
|
|
73
|
+
if (font != nullptr) {
|
|
74
|
+
UIFont *newFont = [font removeBold];
|
|
75
|
+
[_input->textView.textStorage addAttribute:NSFontAttributeName
|
|
76
|
+
value:newFont
|
|
77
|
+
range:range];
|
|
78
|
+
}
|
|
79
|
+
}];
|
|
63
80
|
[_input->textView.textStorage endEditing];
|
|
64
81
|
}
|
|
65
82
|
|
|
66
83
|
- (void)removeTypingAttributes {
|
|
67
|
-
UIFont *currentFontAttr =
|
|
68
|
-
|
|
69
|
-
|
|
84
|
+
UIFont *currentFontAttr =
|
|
85
|
+
(UIFont *)_input->textView.typingAttributes[NSFontAttributeName];
|
|
86
|
+
if (currentFontAttr != nullptr) {
|
|
87
|
+
NSMutableDictionary *newTypingAttrs =
|
|
88
|
+
[_input->textView.typingAttributes mutableCopy];
|
|
70
89
|
newTypingAttrs[NSFontAttributeName] = [currentFontAttr removeBold];
|
|
71
90
|
_input->textView.typingAttributes = newTypingAttrs;
|
|
72
91
|
}
|
|
73
92
|
}
|
|
74
93
|
|
|
75
94
|
- (BOOL)boldHeadingConflictsInRange:(NSRange)range type:(StyleType)type {
|
|
76
|
-
if(type == H1) {
|
|
77
|
-
if(![_input->config h1Bold]) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
} else if(type ==
|
|
81
|
-
if(![_input->config
|
|
95
|
+
if (type == H1) {
|
|
96
|
+
if (![_input->config h1Bold]) {
|
|
97
|
+
return NO;
|
|
98
|
+
}
|
|
99
|
+
} else if (type == H2) {
|
|
100
|
+
if (![_input->config h2Bold]) {
|
|
101
|
+
return NO;
|
|
102
|
+
}
|
|
103
|
+
} else if (type == H3) {
|
|
104
|
+
if (![_input->config h3Bold]) {
|
|
105
|
+
return NO;
|
|
106
|
+
}
|
|
107
|
+
} else if (type == H4) {
|
|
108
|
+
if (![_input->config h4Bold]) {
|
|
109
|
+
return NO;
|
|
110
|
+
}
|
|
111
|
+
} else if (type == H5) {
|
|
112
|
+
if (![_input->config h5Bold]) {
|
|
113
|
+
return NO;
|
|
114
|
+
}
|
|
115
|
+
} else if (type == H6) {
|
|
116
|
+
if (![_input->config h6Bold]) {
|
|
117
|
+
return NO;
|
|
118
|
+
}
|
|
82
119
|
}
|
|
83
|
-
|
|
120
|
+
|
|
84
121
|
id<BaseStyleProtocol> headingStyle = _input->stylesDict[@(type)];
|
|
85
|
-
return range.length > 0
|
|
86
|
-
|
|
87
|
-
: [headingStyle detectStyle:range];
|
|
122
|
+
return range.length > 0 ? [headingStyle anyOccurence:range]
|
|
123
|
+
: [headingStyle detectStyle:range];
|
|
88
124
|
}
|
|
89
125
|
|
|
90
|
-
- (BOOL)styleCondition:(id _Nullable)value :(NSRange)range {
|
|
126
|
+
- (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
|
|
91
127
|
UIFont *font = (UIFont *)value;
|
|
92
|
-
return font != nullptr && [font isBold] &&
|
|
128
|
+
return font != nullptr && [font isBold] &&
|
|
129
|
+
![self boldHeadingConflictsInRange:range type:H1] &&
|
|
130
|
+
![self boldHeadingConflictsInRange:range type:H2] &&
|
|
131
|
+
![self boldHeadingConflictsInRange:range type:H3] &&
|
|
132
|
+
![self boldHeadingConflictsInRange:range type:H4] &&
|
|
133
|
+
![self boldHeadingConflictsInRange:range type:H5] &&
|
|
134
|
+
![self boldHeadingConflictsInRange:range type:H6];
|
|
93
135
|
}
|
|
94
136
|
|
|
95
137
|
- (BOOL)detectStyle:(NSRange)range {
|
|
96
|
-
if(range.length >= 1) {
|
|
97
|
-
return [OccurenceUtils detect:NSFontAttributeName
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
138
|
+
if (range.length >= 1) {
|
|
139
|
+
return [OccurenceUtils detect:NSFontAttributeName
|
|
140
|
+
withInput:_input
|
|
141
|
+
inRange:range
|
|
142
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
143
|
+
return [self styleCondition:value range:range];
|
|
144
|
+
}];
|
|
102
145
|
} else {
|
|
103
|
-
return [OccurenceUtils detect:NSFontAttributeName
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
146
|
+
return [OccurenceUtils detect:NSFontAttributeName
|
|
147
|
+
withInput:_input
|
|
148
|
+
atIndex:range.location
|
|
149
|
+
checkPrevious:NO
|
|
150
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
151
|
+
return [self styleCondition:value range:range];
|
|
152
|
+
}];
|
|
108
153
|
}
|
|
109
154
|
}
|
|
110
155
|
|
|
111
156
|
- (BOOL)anyOccurence:(NSRange)range {
|
|
112
|
-
return [OccurenceUtils any:NSFontAttributeName
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
157
|
+
return [OccurenceUtils any:NSFontAttributeName
|
|
158
|
+
withInput:_input
|
|
159
|
+
inRange:range
|
|
160
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
161
|
+
return [self styleCondition:value range:range];
|
|
162
|
+
}];
|
|
117
163
|
}
|
|
118
164
|
|
|
119
165
|
- (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
|
|
120
|
-
return [OccurenceUtils all:NSFontAttributeName
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
166
|
+
return [OccurenceUtils all:NSFontAttributeName
|
|
167
|
+
withInput:_input
|
|
168
|
+
inRange:range
|
|
169
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
170
|
+
return [self styleCondition:value range:range];
|
|
171
|
+
}];
|
|
125
172
|
}
|
|
126
173
|
|
|
127
174
|
@end
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
-
#import "
|
|
1
|
+
#import "ColorExtension.h"
|
|
2
2
|
#import "EnrichedTextInputView.h"
|
|
3
3
|
#import "FontExtension.h"
|
|
4
4
|
#import "OccurenceUtils.h"
|
|
5
5
|
#import "ParagraphsUtils.h"
|
|
6
|
+
#import "StyleHeaders.h"
|
|
6
7
|
#import "TextInsertionUtils.h"
|
|
7
|
-
#import "ColorExtension.h"
|
|
8
8
|
|
|
9
9
|
@implementation CodeBlockStyle {
|
|
10
10
|
EnrichedTextInputView *_input;
|
|
11
11
|
NSArray *_stylesToExclude;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
+ (StyleType)getStyleType {
|
|
14
|
+
+ (StyleType)getStyleType {
|
|
15
|
+
return CodeBlock;
|
|
16
|
+
}
|
|
15
17
|
|
|
16
|
-
+ (BOOL)isParagraphStyle {
|
|
18
|
+
+ (BOOL)isParagraphStyle {
|
|
19
|
+
return YES;
|
|
20
|
+
}
|
|
17
21
|
|
|
18
22
|
- (instancetype)initWithInput:(id)input {
|
|
19
23
|
self = [super init];
|
|
@@ -24,94 +28,130 @@
|
|
|
24
28
|
|
|
25
29
|
- (void)applyStyle:(NSRange)range {
|
|
26
30
|
BOOL isStylePresent = [self detectStyle:range];
|
|
27
|
-
if(range.length >= 1) {
|
|
28
|
-
isStylePresent ? [self removeAttributes:range]
|
|
31
|
+
if (range.length >= 1) {
|
|
32
|
+
isStylePresent ? [self removeAttributes:range]
|
|
33
|
+
: [self addAttributes:range withTypingAttr:YES];
|
|
29
34
|
} else {
|
|
30
35
|
isStylePresent ? [self removeTypingAttributes] : [self addTypingAttributes];
|
|
31
36
|
}
|
|
32
37
|
}
|
|
33
38
|
|
|
34
|
-
- (void)addAttributes:(NSRange)range {
|
|
35
|
-
NSTextList *codeBlockList =
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
- (void)addAttributes:(NSRange)range withTypingAttr:(BOOL)withTypingAttr {
|
|
40
|
+
NSTextList *codeBlockList =
|
|
41
|
+
[[NSTextList alloc] initWithMarkerFormat:@"codeblock" options:0];
|
|
42
|
+
NSArray *paragraphs =
|
|
43
|
+
[ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView
|
|
44
|
+
range:range];
|
|
45
|
+
// if we fill empty lines with zero width spaces, we need to offset later
|
|
46
|
+
// ranges
|
|
38
47
|
NSInteger offset = 0;
|
|
39
48
|
NSRange preModificationRange = _input->textView.selectedRange;
|
|
40
|
-
|
|
49
|
+
|
|
41
50
|
// to not emit any space filling selection/text changes
|
|
42
51
|
_input->blockEmitting = YES;
|
|
43
52
|
|
|
44
53
|
for (NSValue *value in paragraphs) {
|
|
45
|
-
NSRange pRange = NSMakeRange([value rangeValue].location + offset,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
NSRange pRange = NSMakeRange([value rangeValue].location + offset,
|
|
55
|
+
[value rangeValue].length);
|
|
56
|
+
// length 0 with first line, length 1 and newline with some empty lines in
|
|
57
|
+
// the middle
|
|
58
|
+
if (pRange.length == 0 ||
|
|
59
|
+
(pRange.length == 1 &&
|
|
60
|
+
[[NSCharacterSet newlineCharacterSet]
|
|
61
|
+
characterIsMember:[_input->textView.textStorage.string
|
|
62
|
+
characterAtIndex:pRange.location]])) {
|
|
63
|
+
[TextInsertionUtils insertText:@"\u200B"
|
|
64
|
+
at:pRange.location
|
|
65
|
+
additionalAttributes:nullptr
|
|
66
|
+
input:_input
|
|
67
|
+
withSelection:NO];
|
|
52
68
|
pRange = NSMakeRange(pRange.location, pRange.length + 1);
|
|
53
69
|
offset += 1;
|
|
54
70
|
}
|
|
55
|
-
|
|
56
|
-
[_input->textView.textStorage
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
71
|
+
|
|
72
|
+
[_input->textView.textStorage
|
|
73
|
+
enumerateAttribute:NSParagraphStyleAttributeName
|
|
74
|
+
inRange:pRange
|
|
75
|
+
options:0
|
|
76
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
77
|
+
BOOL *_Nonnull stop) {
|
|
78
|
+
NSMutableParagraphStyle *pStyle =
|
|
79
|
+
[(NSParagraphStyle *)value mutableCopy];
|
|
80
|
+
pStyle.textLists = @[ codeBlockList ];
|
|
81
|
+
[_input->textView.textStorage
|
|
82
|
+
addAttribute:NSParagraphStyleAttributeName
|
|
83
|
+
value:pStyle
|
|
84
|
+
range:range];
|
|
85
|
+
}];
|
|
63
86
|
}
|
|
64
|
-
|
|
87
|
+
|
|
65
88
|
// back to emitting
|
|
66
89
|
_input->blockEmitting = NO;
|
|
67
|
-
|
|
68
|
-
if(preModificationRange.length == 0) {
|
|
69
|
-
// fix selection if only one line was possibly made a list and filled with a
|
|
90
|
+
|
|
91
|
+
if (preModificationRange.length == 0) {
|
|
92
|
+
// fix selection if only one line was possibly made a list and filled with a
|
|
93
|
+
// space
|
|
70
94
|
_input->textView.selectedRange = preModificationRange;
|
|
71
95
|
} else {
|
|
72
96
|
// in other cases, fix the selection with newly made offsets
|
|
73
|
-
_input->textView.selectedRange = NSMakeRange(
|
|
97
|
+
_input->textView.selectedRange = NSMakeRange(
|
|
98
|
+
preModificationRange.location, preModificationRange.length + offset);
|
|
74
99
|
}
|
|
75
|
-
|
|
100
|
+
|
|
76
101
|
// also add typing attributes
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
102
|
+
if (withTypingAttr) {
|
|
103
|
+
NSMutableDictionary *typingAttrs =
|
|
104
|
+
[_input->textView.typingAttributes mutableCopy];
|
|
105
|
+
NSMutableParagraphStyle *pStyle =
|
|
106
|
+
[typingAttrs[NSParagraphStyleAttributeName] mutableCopy];
|
|
107
|
+
pStyle.textLists = @[ codeBlockList ];
|
|
108
|
+
typingAttrs[NSParagraphStyleAttributeName] = pStyle;
|
|
109
|
+
|
|
110
|
+
_input->textView.typingAttributes = typingAttrs;
|
|
111
|
+
}
|
|
83
112
|
}
|
|
84
113
|
|
|
85
114
|
- (void)addTypingAttributes {
|
|
86
|
-
[self addAttributes:_input->textView.selectedRange];
|
|
115
|
+
[self addAttributes:_input->textView.selectedRange withTypingAttr:YES];
|
|
87
116
|
}
|
|
88
117
|
|
|
89
118
|
- (void)removeAttributes:(NSRange)range {
|
|
90
|
-
NSArray *paragraphs =
|
|
91
|
-
|
|
119
|
+
NSArray *paragraphs =
|
|
120
|
+
[ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView
|
|
121
|
+
range:range];
|
|
122
|
+
|
|
92
123
|
[_input->textView.textStorage beginEditing];
|
|
93
|
-
|
|
94
|
-
for(NSValue *value in paragraphs) {
|
|
124
|
+
|
|
125
|
+
for (NSValue *value in paragraphs) {
|
|
95
126
|
NSRange pRange = [value rangeValue];
|
|
96
|
-
|
|
97
|
-
[_input->textView.textStorage
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
127
|
+
|
|
128
|
+
[_input->textView.textStorage
|
|
129
|
+
enumerateAttribute:NSParagraphStyleAttributeName
|
|
130
|
+
inRange:pRange
|
|
131
|
+
options:0
|
|
132
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
133
|
+
BOOL *_Nonnull stop) {
|
|
134
|
+
NSMutableParagraphStyle *pStyle =
|
|
135
|
+
[(NSParagraphStyle *)value mutableCopy];
|
|
136
|
+
pStyle.textLists = @[];
|
|
137
|
+
[_input->textView.textStorage
|
|
138
|
+
addAttribute:NSParagraphStyleAttributeName
|
|
139
|
+
value:pStyle
|
|
140
|
+
range:range];
|
|
141
|
+
}];
|
|
104
142
|
}
|
|
105
|
-
|
|
143
|
+
|
|
106
144
|
[_input->textView.textStorage endEditing];
|
|
107
|
-
|
|
145
|
+
|
|
108
146
|
// also remove typing attributes
|
|
109
|
-
NSMutableDictionary *typingAttrs =
|
|
110
|
-
|
|
147
|
+
NSMutableDictionary *typingAttrs =
|
|
148
|
+
[_input->textView.typingAttributes mutableCopy];
|
|
149
|
+
NSMutableParagraphStyle *pStyle =
|
|
150
|
+
[typingAttrs[NSParagraphStyleAttributeName] mutableCopy];
|
|
111
151
|
pStyle.textLists = @[];
|
|
112
|
-
|
|
152
|
+
|
|
113
153
|
typingAttrs[NSParagraphStyleAttributeName] = pStyle;
|
|
114
|
-
|
|
154
|
+
|
|
115
155
|
_input->textView.typingAttributes = typingAttrs;
|
|
116
156
|
}
|
|
117
157
|
|
|
@@ -120,14 +160,16 @@
|
|
|
120
160
|
}
|
|
121
161
|
|
|
122
162
|
- (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text {
|
|
123
|
-
if([self detectStyle:_input->textView.selectedRange] && text.length == 0) {
|
|
163
|
+
if ([self detectStyle:_input->textView.selectedRange] && text.length == 0) {
|
|
124
164
|
// backspace while the style is active
|
|
125
|
-
|
|
126
|
-
NSRange paragraphRange = [_input->textView.textStorage.string
|
|
127
|
-
|
|
128
|
-
|
|
165
|
+
|
|
166
|
+
NSRange paragraphRange = [_input->textView.textStorage.string
|
|
167
|
+
paragraphRangeForRange:_input->textView.selectedRange];
|
|
168
|
+
|
|
169
|
+
if (NSEqualRanges(_input->textView.selectedRange, NSMakeRange(0, 0))) {
|
|
129
170
|
// a backspace on the very first input's line quote
|
|
130
|
-
// it doesn't run textVieDidChange so we need to manually remove
|
|
171
|
+
// it doesn't run textVieDidChange so we need to manually remove
|
|
172
|
+
// attributes
|
|
131
173
|
[self removeAttributes:paragraphRange];
|
|
132
174
|
return YES;
|
|
133
175
|
}
|
|
@@ -135,92 +177,126 @@
|
|
|
135
177
|
return NO;
|
|
136
178
|
}
|
|
137
179
|
|
|
138
|
-
- (BOOL)styleCondition:(id _Nullable)value :(NSRange)range {
|
|
180
|
+
- (BOOL)styleCondition:(id _Nullable)value range:(NSRange)range {
|
|
139
181
|
NSParagraphStyle *paragraph = (NSParagraphStyle *)value;
|
|
140
|
-
return paragraph != nullptr && paragraph.textLists.count == 1 &&
|
|
182
|
+
return paragraph != nullptr && paragraph.textLists.count == 1 &&
|
|
183
|
+
[paragraph.textLists.firstObject.markerFormat
|
|
184
|
+
isEqualToString:@"codeblock"];
|
|
141
185
|
}
|
|
142
186
|
|
|
143
187
|
- (BOOL)detectStyle:(NSRange)range {
|
|
144
|
-
if(range.length >= 1) {
|
|
145
|
-
return [OccurenceUtils detect:NSParagraphStyleAttributeName
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
188
|
+
if (range.length >= 1) {
|
|
189
|
+
return [OccurenceUtils detect:NSParagraphStyleAttributeName
|
|
190
|
+
withInput:_input
|
|
191
|
+
inRange:range
|
|
192
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
193
|
+
return [self styleCondition:value range:range];
|
|
194
|
+
}];
|
|
150
195
|
} else {
|
|
151
|
-
return [OccurenceUtils detect:NSParagraphStyleAttributeName
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
196
|
+
return [OccurenceUtils detect:NSParagraphStyleAttributeName
|
|
197
|
+
withInput:_input
|
|
198
|
+
atIndex:range.location
|
|
199
|
+
checkPrevious:YES
|
|
200
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
201
|
+
return [self styleCondition:value range:range];
|
|
202
|
+
}];
|
|
156
203
|
}
|
|
157
204
|
}
|
|
158
205
|
|
|
159
206
|
- (BOOL)anyOccurence:(NSRange)range {
|
|
160
|
-
return [OccurenceUtils any:NSParagraphStyleAttributeName
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
207
|
+
return [OccurenceUtils any:NSParagraphStyleAttributeName
|
|
208
|
+
withInput:_input
|
|
209
|
+
inRange:range
|
|
210
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
211
|
+
return [self styleCondition:value range:range];
|
|
212
|
+
}];
|
|
165
213
|
}
|
|
166
214
|
|
|
167
215
|
- (NSArray<StylePair *> *_Nullable)findAllOccurences:(NSRange)range {
|
|
168
|
-
return [OccurenceUtils all:NSParagraphStyleAttributeName
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
216
|
+
return [OccurenceUtils all:NSParagraphStyleAttributeName
|
|
217
|
+
withInput:_input
|
|
218
|
+
inRange:range
|
|
219
|
+
withCondition:^BOOL(id _Nullable value, NSRange range) {
|
|
220
|
+
return [self styleCondition:value range:range];
|
|
221
|
+
}];
|
|
173
222
|
}
|
|
174
223
|
|
|
175
224
|
- (void)manageCodeBlockFontAndColor {
|
|
176
|
-
if([[_input->config codeBlockFgColor]
|
|
225
|
+
if ([[_input->config codeBlockFgColor]
|
|
226
|
+
isEqualToColor:[_input->config primaryColor]]) {
|
|
177
227
|
return;
|
|
178
228
|
}
|
|
179
229
|
|
|
180
|
-
NSRange wholeRange =
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
230
|
+
NSRange wholeRange =
|
|
231
|
+
NSMakeRange(0, _input->textView.textStorage.string.length);
|
|
232
|
+
NSArray *paragraphs =
|
|
233
|
+
[ParagraphsUtils getSeparateParagraphsRangesIn:_input->textView
|
|
234
|
+
range:wholeRange];
|
|
235
|
+
|
|
236
|
+
for (NSValue *pValue in paragraphs) {
|
|
184
237
|
NSRange paragraphRange = [pValue rangeValue];
|
|
185
|
-
NSArray *properRanges = [OccurenceUtils getRangesWithout:_stylesToExclude
|
|
186
|
-
|
|
187
|
-
|
|
238
|
+
NSArray *properRanges = [OccurenceUtils getRangesWithout:_stylesToExclude
|
|
239
|
+
withInput:_input
|
|
240
|
+
inRange:paragraphRange];
|
|
241
|
+
|
|
242
|
+
for (NSValue *value in properRanges) {
|
|
188
243
|
NSRange currRange = [value rangeValue];
|
|
189
244
|
BOOL selfDetected = [self detectStyle:currRange];
|
|
190
|
-
|
|
191
|
-
[_input->textView.textStorage
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
245
|
+
|
|
246
|
+
[_input->textView.textStorage
|
|
247
|
+
enumerateAttribute:NSFontAttributeName
|
|
248
|
+
inRange:currRange
|
|
249
|
+
options:0
|
|
250
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
251
|
+
BOOL *_Nonnull stop) {
|
|
252
|
+
UIFont *currentFont = (UIFont *)value;
|
|
253
|
+
UIFont *newFont = nullptr;
|
|
254
|
+
|
|
255
|
+
BOOL isCodeFont = [[currentFont familyName]
|
|
256
|
+
isEqualToString:[[_input->config monospacedFont]
|
|
257
|
+
familyName]];
|
|
258
|
+
|
|
259
|
+
if (isCodeFont && !selfDetected) {
|
|
260
|
+
newFont = [[[_input->config primaryFont]
|
|
261
|
+
withFontTraits:currentFont]
|
|
262
|
+
setSize:currentFont.pointSize];
|
|
263
|
+
} else if (!isCodeFont && selfDetected) {
|
|
264
|
+
newFont = [[[_input->config monospacedFont]
|
|
265
|
+
withFontTraits:currentFont]
|
|
266
|
+
setSize:currentFont.pointSize];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (newFont != nullptr) {
|
|
270
|
+
[_input->textView.textStorage
|
|
271
|
+
addAttribute:NSFontAttributeName
|
|
272
|
+
value:newFont
|
|
273
|
+
range:range];
|
|
274
|
+
}
|
|
275
|
+
}];
|
|
276
|
+
|
|
277
|
+
[_input->textView.textStorage
|
|
278
|
+
enumerateAttribute:NSForegroundColorAttributeName
|
|
279
|
+
inRange:currRange
|
|
280
|
+
options:0
|
|
281
|
+
usingBlock:^(id _Nullable value, NSRange range,
|
|
282
|
+
BOOL *_Nonnull stop) {
|
|
283
|
+
UIColor *newColor = nullptr;
|
|
284
|
+
BOOL colorApplied = [(UIColor *)value
|
|
285
|
+
isEqualToColor:[_input->config codeBlockFgColor]];
|
|
286
|
+
|
|
287
|
+
if (colorApplied && !selfDetected) {
|
|
288
|
+
newColor = [_input->config primaryColor];
|
|
289
|
+
} else if (!colorApplied && selfDetected) {
|
|
290
|
+
newColor = [_input->config codeBlockFgColor];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (newColor != nullptr) {
|
|
294
|
+
[_input->textView.textStorage
|
|
295
|
+
addAttribute:NSForegroundColorAttributeName
|
|
296
|
+
value:newColor
|
|
297
|
+
range:range];
|
|
298
|
+
}
|
|
299
|
+
}];
|
|
224
300
|
}
|
|
225
301
|
}
|
|
226
302
|
}
|