@@ -77,6 +77,7 @@ - (void)setDefaults {
7777 _recentlyEmittedString = @" " ;
7878 _recentlyEmittedHtml = @" " ;
7979 _emitHtml = NO ;
80+ blockEmitting = NO ;
8081 _emitFocusBlur = YES ;
8182
8283 defaultTypingAttributes = [[NSMutableDictionary <NSAttributedStringKey , id > alloc] init ];
@@ -91,7 +92,8 @@ - (void)setDefaults {
9192 @([MentionStyle getStyleType ]): [[MentionStyle alloc ] initWithEditor: self ],
9293 @([H1Style getStyleType ]): [[H1Style alloc ] initWithEditor: self ],
9394 @([H2Style getStyleType ]): [[H2Style alloc ] initWithEditor: self ],
94- @([H3Style getStyleType ]): [[H3Style alloc ] initWithEditor: self ]
95+ @([H3Style getStyleType ]): [[H3Style alloc ] initWithEditor: self ],
96+ @([UnorderedListStyle getStyleType ]): [[UnorderedListStyle alloc ] initWithEditor: self ]
9597 };
9698
9799 _conflictingStyles = @{
@@ -102,9 +104,10 @@ - (void)setDefaults {
102104 @([InlineCodeStyle getStyleType ]) : @[@([LinkStyle getStyleType ]), @([MentionStyle getStyleType ])],
103105 @([LinkStyle getStyleType ]): @[@([InlineCodeStyle getStyleType ]), @([LinkStyle getStyleType ]), @([MentionStyle getStyleType ])],
104106 @([MentionStyle getStyleType ]): @[@([InlineCodeStyle getStyleType ]), @([LinkStyle getStyleType ])],
105- @([H1Style getStyleType ]): @[@([H2Style getStyleType ]), @([H3Style getStyleType ])],
106- @([H2Style getStyleType ]): @[@([H1Style getStyleType ]), @([H3Style getStyleType ])],
107- @([H3Style getStyleType ]): @[@([H1Style getStyleType ]), @([H2Style getStyleType ])]
107+ @([H1Style getStyleType ]): @[@([H2Style getStyleType ]), @([H3Style getStyleType ]), @([UnorderedListStyle getStyleType ])],
108+ @([H2Style getStyleType ]): @[@([H1Style getStyleType ]), @([H3Style getStyleType ]), @([UnorderedListStyle getStyleType ])],
109+ @([H3Style getStyleType ]): @[@([H1Style getStyleType ]), @([H2Style getStyleType ]), @([UnorderedListStyle getStyleType ])],
110+ @([UnorderedListStyle getStyleType ]): @[@([H1Style getStyleType ]), @([H2Style getStyleType ]), @([H3Style getStyleType ])],
108111 };
109112
110113 _blockingStyles = @{
@@ -117,7 +120,8 @@ - (void)setDefaults {
117120 @([MentionStyle getStyleType ]): @[],
118121 @([H1Style getStyleType ]): @[],
119122 @([H2Style getStyleType ]): @[],
120- @([H3Style getStyleType ]): @[]
123+ @([H3Style getStyleType ]): @[],
124+ @([UnorderedListStyle getStyleType ]): @[],
121125 };
122126
123127 _editorParser = [[EditorParser alloc ] initWithEditor: self ];
@@ -205,6 +209,7 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
205209 defaultTypingAttributes[NSFontAttributeName ] = [config primaryFont ];
206210 defaultTypingAttributes[NSUnderlineColorAttributeName ] = [config primaryColor ];
207211 defaultTypingAttributes[NSStrikethroughColorAttributeName ] = [config primaryColor ];
212+ defaultTypingAttributes[NSParagraphStyleAttributeName ] = [[NSParagraphStyle alloc ] init ];
208213 textView.typingAttributes = defaultTypingAttributes;
209214
210215 if (stylePropChanged) {
@@ -496,7 +501,7 @@ - (void)tryUpdatingActiveStyles {
496501 .isH3 = [_activeStyles containsObject: @([H3Style getStyleType ])],
497502 .isCodeBlock = NO , // [_activeStyles containsObject: @([CodeBlockStyle getStyleType])],
498503 .isBlockQuote = NO , // [_activeStyles containsObject: @([BlockQuoteStyle getStyleType])],
499- .isUnorderedList = NO , // [_activeStyles containsObject: @([UnorderedListStyle getStyleType])],
504+ .isUnorderedList = [_activeStyles containsObject: @([UnorderedListStyle getStyleType ])],
500505 .isOrderedList = NO , // [_activeStyles containsObject: @([OrderedListStyle getStyleType]]],
501506 .isImage = NO // [_activeStyles containsObject: @([ImageStyle getStyleType]]],
502507 });
@@ -560,11 +565,13 @@ - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args {
560565 [self toggleParagraphStyle: [H2Style getStyleType ]];
561566 } else if ([commandName isEqualToString: @" toggleH3" ]) {
562567 [self toggleParagraphStyle: [H3Style getStyleType ]];
568+ } else if ([commandName isEqualToString: @" toggleUnorderedList" ]) {
569+ [self toggleParagraphStyle: [UnorderedListStyle getStyleType ]];
563570 }
564571}
565572
566573- (std::shared_ptr<ReactNativeRichTextEditorViewEventEmitter>)getEventEmitter {
567- if (_eventEmitter != nullptr ) {
574+ if (_eventEmitter != nullptr && !blockEmitting ) {
568575 auto emitter = static_cast <const ReactNativeRichTextEditorViewEventEmitter &>(*_eventEmitter);
569576 return std::make_shared<ReactNativeRichTextEditorViewEventEmitter>(emitter);
570577 } else {
@@ -644,6 +651,7 @@ - (void)toggleRegularStyle:(StyleType)type {
644651
645652 if ([self handleStyleBlocksAndConflicts: type range: textView.selectedRange]) {
646653 [styleClass applyStyle: textView.selectedRange];
654+ [self tryUpdatingHeight ];
647655 [self tryUpdatingActiveStyles ];
648656 }
649657}
@@ -655,7 +663,6 @@ - (void)toggleParagraphStyle:(StyleType)type {
655663
656664 if ([self handleStyleBlocksAndConflicts: type range: paragraphRange]) {
657665 [styleClass applyStyle: paragraphRange];
658- // height needs to be checked as well with paragraph styles
659666 [self tryUpdatingHeight ];
660667 [self tryUpdatingActiveStyles ];
661668 }
@@ -669,6 +676,7 @@ - (void)addLinkAt:(NSInteger)start end:(NSInteger)end text:(NSString *)text url:
669676 NSRange linkRange = NSMakeRange (start, end - start);
670677 if ([self handleStyleBlocksAndConflicts: [LinkStyle getStyleType ] range: linkRange]) {
671678 [linkStyleClass addLink: text url: url range: linkRange manual: YES ];
679+ [self tryUpdatingHeight ];
672680 [self tryUpdatingActiveStyles ];
673681 }
674682}
@@ -680,6 +688,7 @@ - (void)addMention:(NSString *)indicator text:(NSString *)text attributes:(NSStr
680688
681689 if ([self handleStyleBlocksAndConflicts: [MentionStyle getStyleType ] range: [[mentionStyleClass getActiveMentionRange ] rangeValue ]]) {
682690 [mentionStyleClass addMention: indicator text: text attributes: attributes];
691+ [self tryUpdatingHeight ];
683692 [self tryUpdatingActiveStyles ];
684693 }
685694}
@@ -690,6 +699,7 @@ - (void)startMentionWithIndicator:(NSString *)indicator {
690699
691700 if ([self handleStyleBlocksAndConflicts: [MentionStyle getStyleType ] range: [[mentionStyleClass getActiveMentionRange ] rangeValue ]]) {
692701 [mentionStyleClass startMentionWithIndicator: indicator];
702+ [self tryUpdatingHeight ];
693703 [self tryUpdatingActiveStyles ];
694704 }
695705}
@@ -781,14 +791,17 @@ - (void)anyTextMayHaveBeenModified {
781791
782792 // do all the stuff only if the text really changed
783793 if (![textView.textStorage.string isEqualToString: _recentlyEmittedString]) {
794+ // emptying input
795+ if (textView.textStorage .string .length == 0 ) {
796+ // reset typing attribtues
797+ textView.typingAttributes = defaultTypingAttributes;
798+ }
784799
785800 // placholder management
786801 if (_recentlyEmittedString.length == 0 && textView.textStorage .string .length > 0 ) {
787802 [self setPlaceholderLabelShown: NO ];
788803 } else if (_recentlyEmittedString.length > 0 && textView.textStorage .string .length == 0 ) {
789804 [self setPlaceholderLabelShown: YES ];
790- // also typing attributes get reset when emptying the input
791- textView.typingAttributes = defaultTypingAttributes;
792805 }
793806
794807 // modified words handling
@@ -816,12 +829,12 @@ - (void)anyTextMayHaveBeenModified {
816829
817830 // set the recently emitted string
818831 _recentlyEmittedString = [textView.textStorage.string copy ];
819-
820- // update height on each character change
821- [self tryUpdatingHeight ];
822- // update active styles as well
823- [self tryUpdatingActiveStyles ];
824832 }
833+
834+ // update height on each character change
835+ [self tryUpdatingHeight ];
836+ // update active styles as well
837+ [self tryUpdatingActiveStyles ];
825838}
826839
827840// MARK: - UITextView delegate methods
@@ -855,7 +868,19 @@ - (void)textViewDidEndEditing:(UITextView *)textView {
855868
856869- (bool )textView : (UITextView *)textView shouldChangeTextInRange : (NSRange )range replacementText : (NSString *)text {
857870 _recentlyChangedRange = NSMakeRange (range.location , text.length );
858- return true ;
871+
872+ UnorderedListStyle *uStyle = stylesDict[@([UnorderedListStyle getStyleType ])];
873+ if (uStyle != nullptr ) {
874+ // removing first line list fix
875+ [uStyle handleBackspaceInRange: range replacementText: text];
876+ // creating unordered list from "- "
877+ if ([uStyle tryHandlingListShorcutInRange: range replacementText: text]) {
878+ // we successfully added a list -> so we reject the text change
879+ return NO ;
880+ }
881+ }
882+
883+ return YES ;
859884}
860885
861886- (void )textViewDidChangeSelection : (UITextView *)textView {
0 commit comments