Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ios/EnrichedTextInputView.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ NS_ASSUME_NONNULL_BEGIN
@public InputParser *parser;
@public NSMutableDictionary<NSAttributedStringKey, id> *defaultTypingAttributes;
@public NSDictionary<NSNumber *, id<BaseStyleProtocol>> *stylesDict;
NSDictionary<NSNumber *, NSArray<NSNumber *> *> *conflictingStyles;
NSDictionary<NSNumber *, NSArray<NSNumber *> *> *blockingStyles;
@public BOOL blockEmitting;
}
- (CGSize)measureSize:(CGFloat)maxWidth;
- (void)emitOnLinkDetectedEvent:(NSString *)text url:(NSString *)url range:(NSRange)range;
- (void)emitOnMentionEvent:(NSString *)indicator text:(nullable NSString *)text;
- (void)anyTextMayHaveBeenModified;
- (BOOL)handleStyleBlocksAndConflicts:(StyleType)type range:(NSRange)range;
- (NSArray<NSNumber *> *)getPresentStyleTypesFrom:(NSArray<NSNumber *> *)types range:(NSRange)range;
@end

NS_ASSUME_NONNULL_END
Expand Down
84 changes: 60 additions & 24 deletions ios/EnrichedTextInputView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ @implementation EnrichedTextInputView {
EnrichedTextInputViewShadowNode::ConcreteState::Shared _state;
int _componentViewHeightUpdateCounter;
NSMutableSet<NSNumber *> *_activeStyles;
NSDictionary<NSNumber *, NSArray<NSNumber *> *> *_conflictingStyles;
NSDictionary<NSNumber *, NSArray<NSNumber *> *> *_blockingStyles;
LinkData *_recentlyActiveLinkData;
NSRange _recentlyActiveLinkRange;
NSString *_recentlyEmittedString;
Expand Down Expand Up @@ -95,39 +93,43 @@ - (void)setDefaults {
@([H3Style getStyleType]): [[H3Style alloc] initWithInput:self],
@([UnorderedListStyle getStyleType]): [[UnorderedListStyle alloc] initWithInput:self],
@([OrderedListStyle getStyleType]): [[OrderedListStyle alloc] initWithInput:self],
@([BlockQuoteStyle getStyleType]): [[BlockQuoteStyle alloc] initWithInput:self]
@([BlockQuoteStyle getStyleType]): [[BlockQuoteStyle alloc] initWithInput:self],
@([CodeBlockStyle getStyleType]): [[CodeBlockStyle alloc] initWithInput:self]
};

_conflictingStyles = @{
conflictingStyles = @{
@([BoldStyle getStyleType]) : @[],
@([ItalicStyle getStyleType]) : @[],
@([UnderlineStyle getStyleType]) : @[],
@([StrikethroughStyle getStyleType]) : @[],
@([InlineCodeStyle getStyleType]) : @[@([LinkStyle getStyleType]), @([MentionStyle getStyleType])],
@([LinkStyle getStyleType]): @[@([InlineCodeStyle getStyleType]), @([LinkStyle getStyleType]), @([MentionStyle getStyleType])],
@([MentionStyle getStyleType]): @[@([InlineCodeStyle getStyleType]), @([LinkStyle getStyleType])],
@([H1Style getStyleType]): @[@([H2Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType])],
@([H2Style getStyleType]): @[@([H1Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType])],
@([H3Style getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType])],
@([UnorderedListStyle getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([H3Style getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType])],
@([OrderedListStyle getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType])],
@([BlockQuoteStyle getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType])]
@([H1Style getStyleType]): @[@([H2Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType]), @([CodeBlockStyle getStyleType])],
@([H2Style getStyleType]): @[@([H1Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType]), @([CodeBlockStyle getStyleType])],
@([H3Style getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType]), @([CodeBlockStyle getStyleType])],
@([UnorderedListStyle getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([H3Style getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType]), @([CodeBlockStyle getStyleType])],
@([OrderedListStyle getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType]), @([CodeBlockStyle getStyleType])],
@([BlockQuoteStyle getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType]), @([CodeBlockStyle getStyleType])],
@([CodeBlockStyle getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([H3Style getStyleType]),
@([BoldStyle getStyleType]), @([ItalicStyle getStyleType]), @([UnderlineStyle getStyleType]), @([StrikethroughStyle getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType]), @([InlineCodeStyle getStyleType]), @([MentionStyle getStyleType]), @([LinkStyle getStyleType])]
};

_blockingStyles = @{
@([BoldStyle getStyleType]) : @[],
@([ItalicStyle getStyleType]) : @[],
@([UnderlineStyle getStyleType]) : @[],
@([StrikethroughStyle getStyleType]) : @[],
@([InlineCodeStyle getStyleType]) : @[],
@([LinkStyle getStyleType]): @[],
@([MentionStyle getStyleType]): @[],
blockingStyles = @{
@([BoldStyle getStyleType]) : @[@([CodeBlockStyle getStyleType])],
@([ItalicStyle getStyleType]) : @[@([CodeBlockStyle getStyleType])],
@([UnderlineStyle getStyleType]) : @[@([CodeBlockStyle getStyleType])],
@([StrikethroughStyle getStyleType]) : @[@([CodeBlockStyle getStyleType])],
@([InlineCodeStyle getStyleType]) : @[@([CodeBlockStyle getStyleType])],
@([LinkStyle getStyleType]): @[@([CodeBlockStyle getStyleType])],
@([MentionStyle getStyleType]): @[@([CodeBlockStyle getStyleType])],
@([H1Style getStyleType]): @[],
@([H2Style getStyleType]): @[],
@([H3Style getStyleType]): @[],
@([UnorderedListStyle getStyleType]): @[],
@([OrderedListStyle getStyleType]): @[],
@([BlockQuoteStyle getStyleType]): @[],
@([CodeBlockStyle getStyleType]): @[],
};

parser = [[InputParser alloc] initWithInput:self];
Expand Down Expand Up @@ -347,6 +349,25 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
}
}

if(newViewProps.htmlStyle.codeblock.color != oldViewProps.htmlStyle.codeblock.color) {
if(isColorMeaningful(newViewProps.htmlStyle.codeblock.color)) {
[newConfig setCodeBlockFgColor:RCTUIColorFromSharedColor(newViewProps.htmlStyle.codeblock.color)];
stylePropChanged = YES;
}
}

if(newViewProps.htmlStyle.codeblock.backgroundColor != oldViewProps.htmlStyle.codeblock.backgroundColor) {
if(isColorMeaningful(newViewProps.htmlStyle.codeblock.backgroundColor)) {
[newConfig setCodeBlockBgColor:RCTUIColorFromSharedColor(newViewProps.htmlStyle.codeblock.backgroundColor)];
stylePropChanged = YES;
}
}

if(newViewProps.htmlStyle.codeblock.borderRadius != oldViewProps.htmlStyle.codeblock.borderRadius) {
[newConfig setCodeBlockBorderRadius:newViewProps.htmlStyle.codeblock.borderRadius];
stylePropChanged = YES;
}

if(newViewProps.htmlStyle.a.textDecorationLine != oldViewProps.htmlStyle.a.textDecorationLine) {
NSString *objcString = [NSString fromCppString:newViewProps.htmlStyle.a.textDecorationLine];
if([objcString isEqualToString:DecorationUnderline]) {
Expand Down Expand Up @@ -512,9 +533,8 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
_emitHtml = newViewProps.isOnChangeHtmlSet;

[super updateProps:props oldProps:oldProps];
// mandatory text and height checks
// run the changes callback
[self anyTextMayHaveBeenModified];
[self tryUpdatingHeight];

// autofocus - needs to be done at the very end
if(isFirstMount && newViewProps.autoFocus) {
Expand Down Expand Up @@ -702,7 +722,7 @@ - (void)tryUpdatingActiveStyles {
.isUnorderedList = [_activeStyles containsObject: @([UnorderedListStyle getStyleType])],
.isOrderedList = [_activeStyles containsObject: @([OrderedListStyle getStyleType])],
.isBlockQuote = [_activeStyles containsObject: @([BlockQuoteStyle getStyleType])],
.isCodeBlock = NO, // [_activeStyles containsObject: @([CodeBlockStyle getStyleType])],
.isCodeBlock = [_activeStyles containsObject: @([CodeBlockStyle getStyleType])],
.isImage = NO // [_activeStyles containsObject: @([ImageStyle getStyleType]])],
});
}
Expand Down Expand Up @@ -771,6 +791,8 @@ - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args {
[self toggleParagraphStyle:[OrderedListStyle getStyleType]];
} else if([commandName isEqualToString:@"toggleBlockQuote"]) {
[self toggleParagraphStyle:[BlockQuoteStyle getStyleType]];
} else if([commandName isEqualToString:@"toggleCodeBlock"]) {
[self toggleParagraphStyle:[CodeBlockStyle getStyleType]];
}
}

Expand Down Expand Up @@ -930,13 +952,13 @@ - (void)startMentionWithIndicator:(NSString *)indicator {
// returns false when style shouldn't be applied and true when it can be
- (BOOL)handleStyleBlocksAndConflicts:(StyleType)type range:(NSRange)range {
// handle blocking styles: if any is present we do not apply the toggled style
NSArray<NSNumber *> *blocking = [self getPresentStyleTypesFrom: _blockingStyles[@(type)] range:range];
NSArray<NSNumber *> *blocking = [self getPresentStyleTypesFrom: blockingStyles[@(type)] range:range];
if(blocking.count != 0) {
return NO;
}

// handle conflicting styles: all of their occurences have to be removed
NSArray<NSNumber *> *conflicting = [self getPresentStyleTypesFrom: _conflictingStyles[@(type)] range:range];
NSArray<NSNumber *> *conflicting = [self getPresentStyleTypesFrom: conflictingStyles[@(type)] range:range];
if(conflicting.count != 0) {
for(NSNumber *style in conflicting) {
id<BaseStyleProtocol> styleClass = stylesDict[style];
Expand Down Expand Up @@ -1012,6 +1034,7 @@ - (void)manageSelectionBasedChanges {
- (void)handleWordModificationBasedChanges:(NSString*)word inRange:(NSRange)range {
// manual links refreshing and automatic links detection handling
LinkStyle* linkStyle = [stylesDict objectForKey:@([LinkStyle getStyleType])];

if(linkStyle != nullptr) {
// manual links need to be handled first because they can block automatic links after being refreshed
[linkStyle handleManualLinks:word inRange:range];
Expand Down Expand Up @@ -1046,6 +1069,12 @@ - (void)anyTextMayHaveBeenModified {
[bqStyle manageBlockquoteColor];
}

// codeblock font and color management
CodeBlockStyle *codeBlockStyle = stylesDict[@([CodeBlockStyle getStyleType])];
if(codeBlockStyle != nullptr) {
[codeBlockStyle manageCodeBlockFontAndColor];
}

// improper headings fix
H1Style *h1Style = stylesDict[@([H1Style getStyleType])];
H2Style *h2Style = stylesDict[@([H2Style getStyleType])];
Expand Down Expand Up @@ -1171,6 +1200,7 @@ - (bool)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range r
UnorderedListStyle *uStyle = stylesDict[@([UnorderedListStyle getStyleType])];
OrderedListStyle *oStyle = stylesDict[@([OrderedListStyle getStyleType])];
BlockQuoteStyle *bqStyle = stylesDict[@([BlockQuoteStyle getStyleType])];
CodeBlockStyle *cbStyle = stylesDict[@([CodeBlockStyle getStyleType])];
LinkStyle *linkStyle = stylesDict[@([LinkStyle getStyleType])];
MentionStyle *mentionStyle = stylesDict[@([MentionStyle getStyleType])];
H1Style *h1Style = stylesDict[@([H1Style getStyleType])];
Expand All @@ -1186,13 +1216,19 @@ - (bool)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range r
[oStyle handleBackspaceInRange:range replacementText:text] ||
[oStyle tryHandlingListShorcutInRange:range replacementText:text] ||
[bqStyle handleBackspaceInRange:range replacementText:text] ||
[cbStyle handleBackspaceInRange:range replacementText:text] ||
[linkStyle handleLeadingLinkReplacement:range replacementText:text] ||
[mentionStyle handleLeadingMentionReplacement:range replacementText:text] ||
[h1Style handleNewlinesInRange:range replacementText:text] ||
[h2Style handleNewlinesInRange:range replacementText:text] ||
[h3Style handleNewlinesInRange:range replacementText:text] ||
[ZeroWidthSpaceUtils handleBackspaceInRange:range replacementText:text input:self] ||
[ParagraphAttributesUtils handleBackspaceInRange:range replacementText:text input:self]
[ParagraphAttributesUtils handleBackspaceInRange:range replacementText:text input:self] ||
// CRITICAL: This callback HAS TO be always evaluated last.
//
// This function is the "Generic Fallback": if no specific style claims the backspace action
// to change its state, only then do we proceed to physically delete the newline and merge paragraphs.
[ParagraphAttributesUtils handleNewlineBackspaceInRange:range replacementText:text input:self]
) {
[self anyTextMayHaveBeenModified];
return NO;
Expand Down
6 changes: 6 additions & 0 deletions ios/config/InputConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,10 @@
- (void)setLinkDecorationLine:(TextDecorationLineEnum)newValue;
- (void)setMentionStyleProps:(NSDictionary *)newValue;
- (MentionStyleProps *)mentionStylePropsForIndicator:(NSString *)indicator;
- (UIColor *)codeBlockFgColor;
- (void)setCodeBlockFgColor:(UIColor *)newValue;
- (UIColor *)codeBlockBgColor;
- (void)setCodeBlockBgColor:(UIColor *)newValue;
- (CGFloat)codeBlockBorderRadius;
- (void)setCodeBlockBorderRadius:(CGFloat)newValue;
@end
30 changes: 30 additions & 0 deletions ios/config/InputConfig.mm
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ @implementation InputConfig {
UIColor *_linkColor;
TextDecorationLineEnum _linkDecorationLine;
NSDictionary *_mentionProperties;
UIColor *_codeBlockFgColor;
CGFloat _codeBlockBorderRadius;
UIColor *_codeBlockBgColor;
}

- (instancetype) init {
Expand Down Expand Up @@ -79,6 +82,9 @@ - (id)copyWithZone:(NSZone *)zone {
copy->_linkColor = [_linkColor copy];
copy->_linkDecorationLine = [_linkDecorationLine copy];
copy->_mentionProperties = [_mentionProperties mutableCopy];
copy->_codeBlockFgColor = [_codeBlockFgColor copy];
copy->_codeBlockBgColor = [_codeBlockBgColor copy];
copy->_codeBlockBorderRadius = _codeBlockBorderRadius;
return copy;
}

Expand Down Expand Up @@ -379,4 +385,28 @@ - (MentionStyleProps *)mentionStylePropsForIndicator:(NSString *)indicator {
return fallbackProps;
}

- (UIColor *)codeBlockFgColor {
return _codeBlockFgColor;
}

- (void)setCodeBlockFgColor:(UIColor *)newValue {
_codeBlockFgColor = newValue;
}

- (UIColor *)codeBlockBgColor {
return _codeBlockBgColor;
}

- (void)setCodeBlockBgColor:(UIColor *)newValue {
_codeBlockBgColor = newValue;
}

- (CGFloat)codeBlockBorderRadius {
return _codeBlockBorderRadius;
}

- (void)setCodeBlockBorderRadius:(CGFloat)newValue {
_codeBlockBorderRadius = newValue;
}

@end
Loading
Loading