Skip to content
Merged
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: 2 additions & 1 deletion ios/ReactNativeRichTextEditorView.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
#import "EditorConfig.h"
#import "EditorParser.h"
#import "BaseStyleProtocol.h"
#import "EditorTextView.h"

#ifndef ReactNativeRichTextEditorViewNativeComponent_h
#define ReactNativeRichTextEditorViewNativeComponent_h

NS_ASSUME_NONNULL_BEGIN

@interface ReactNativeRichTextEditorView : RCTViewComponentView {
@public UITextView *textView;
@public EditorTextView *textView;
@public NSRange recentlyChangedRange;
@public EditorConfig *config;
@public EditorParser *parser;
Expand Down
2 changes: 1 addition & 1 deletion ios/ReactNativeRichTextEditorView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#import "StyleHeaders.h"
#import "WordsUtils.h"
#import "LayoutManagerExtension.h"
#import "EditorTextView.h"

using namespace facebook::react;

Expand Down Expand Up @@ -137,6 +136,7 @@ - (void)setupTextView {
textView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
textView.textContainer.lineFragmentPadding = 0;
textView.delegate = self;
textView.editor = self;
textView.layoutManager.editor = self;
}

Expand Down
1 change: 1 addition & 0 deletions ios/editorTextView/EditorTextView.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
#import <UIkit/UIKit.h>

@interface EditorTextView : UITextView
@property (nonatomic, weak) id editor;
@end
16 changes: 8 additions & 8 deletions ios/editorTextView/EditorTextView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@implementation EditorTextView

- (void)copy:(id)sender {
ReactNativeRichTextEditorView *typedEditor = (ReactNativeRichTextEditorView *)self.delegate;
ReactNativeRichTextEditorView *typedEditor = (ReactNativeRichTextEditorView *)_editor;
if(typedEditor == nullptr) { return; }

NSString *plainText = [typedEditor->textView.textStorage.string substringWithRange:typedEditor->textView.selectedRange];
Expand All @@ -27,7 +27,7 @@ - (void)copy:(id)sender {
}

- (void)paste:(id)sender {
ReactNativeRichTextEditorView *typedEditor = (ReactNativeRichTextEditorView *)self.delegate;
ReactNativeRichTextEditorView *typedEditor = (ReactNativeRichTextEditorView *)_editor;
if(typedEditor == nullptr) { return; }

UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
Expand Down Expand Up @@ -61,26 +61,26 @@ - (void)paste:(id)sender {
if([pasteboardTypes containsObject:UTTypePlainText.identifier]) {
NSString *plainString = [pasteboard valueForPasteboardType:UTTypePlainText.identifier];
currentRange.length > 0
? [TextInsertionUtils replaceText:plainString inView:typedEditor->textView at:currentRange additionalAttributes:nullptr]
: [TextInsertionUtils insertText:plainString inView:typedEditor->textView at:currentRange.location additionalAttributes:nullptr];
? [TextInsertionUtils replaceText:plainString inView:typedEditor->textView at:currentRange additionalAttributes:nullptr editor:typedEditor]
: [TextInsertionUtils insertText:plainString inView:typedEditor->textView at:currentRange.location additionalAttributes:nullptr editor:typedEditor];
}
}
} else if([pasteboardTypes containsObject:UTTypePlainText.identifier]) {
// just plain text

NSString *plainString = [pasteboard valueForPasteboardType:UTTypePlainText.identifier];
currentRange.length > 0
? [TextInsertionUtils replaceText:plainString inView:typedEditor->textView at:currentRange additionalAttributes:nullptr]
: [TextInsertionUtils insertText:plainString inView:typedEditor->textView at:currentRange.location additionalAttributes:nullptr];
? [TextInsertionUtils replaceText:plainString inView:typedEditor->textView at:currentRange additionalAttributes:nullptr editor:typedEditor]
: [TextInsertionUtils insertText:plainString inView:typedEditor->textView at:currentRange.location additionalAttributes:nullptr editor:typedEditor];
}
}

- (void)cut:(id)sender {
ReactNativeRichTextEditorView *typedEditor = (ReactNativeRichTextEditorView *)self.delegate;
ReactNativeRichTextEditorView *typedEditor = (ReactNativeRichTextEditorView *)_editor;
if(typedEditor == nullptr) { return; }

[self copy:sender];
[TextInsertionUtils replaceText:@"" inView:typedEditor->textView at:typedEditor->textView.selectedRange additionalAttributes:nullptr];
[TextInsertionUtils replaceText:@"" inView:typedEditor->textView at:typedEditor->textView.selectedRange additionalAttributes:nullptr editor:typedEditor];
}

@end
4 changes: 2 additions & 2 deletions ios/parser/EditorParser.mm
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ - (void)replaceFromHtml:(NSString * _Nonnull)html range:(NSRange)range {
NSArray *stylesInfo = (NSArray *)processingResult[1];

// we can use ready replace util
[TextInsertionUtils replaceText:plainText inView:_editor->textView at:range additionalAttributes:nil];
[TextInsertionUtils replaceText:plainText inView:_editor->textView at:range additionalAttributes:nil editor:_editor];

[self applyProcessedStyles:stylesInfo offsetFromBeginning:range.location];
[_editor anyTextMayHaveBeenModified];
Expand All @@ -366,7 +366,7 @@ - (void)insertFromHtml:(NSString * _Nonnull)html location:(NSInteger)location {
NSArray *stylesInfo = (NSArray *)processingResult[1];

// same here, insertion utils got our back
[TextInsertionUtils insertText:plainText inView:_editor->textView at:location additionalAttributes:nil];
[TextInsertionUtils insertText:plainText inView:_editor->textView at:location additionalAttributes:nil editor:_editor];

[self applyProcessedStyles:stylesInfo offsetFromBeginning:location];
[_editor anyTextMayHaveBeenModified];
Expand Down
4 changes: 2 additions & 2 deletions ios/styles/LinkStyle.mm
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ - (void)addLink:(NSString*)text url:(NSString*)url range:(NSRange)range manual:(

if(range.length == 0) {
// insert link
[TextInsertionUtils insertText:text inView:_editor->textView at:range.location additionalAttributes:newAttrs];
[TextInsertionUtils insertText:text inView:_editor->textView at:range.location additionalAttributes:newAttrs editor:_editor];
} else if([currentText isEqualToString:text]) {
// apply link attributes
[_editor->textView.textStorage addAttributes:newAttrs range:range];
Expand All @@ -152,7 +152,7 @@ - (void)addLink:(NSString*)text url:(NSString*)url range:(NSRange)range manual:(
}
} else {
// replace text with link
[TextInsertionUtils replaceText:text inView:_editor->textView at:range additionalAttributes:newAttrs];
[TextInsertionUtils replaceText:text inView:_editor->textView at:range additionalAttributes:newAttrs editor:_editor];
}

// mandatory connected links check
Expand Down
6 changes: 3 additions & 3 deletions ios/styles/MentionStyle.mm
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ - (void)addMention:(NSString *)indicator text:(NSString *)text attributes:(NSStr
// add a single space after the mention
NSString *newText = [NSString stringWithFormat:@"%@ ", text];
NSRange rangeToBeReplaced = [_activeMentionRange rangeValue];
[TextInsertionUtils replaceText:newText inView: _editor->textView at:rangeToBeReplaced additionalAttributes:nullptr];
[TextInsertionUtils replaceText:newText inView: _editor->textView at:rangeToBeReplaced additionalAttributes:nullptr editor:_editor];

// THEN, add the attributes to not apply them on the space
[_editor->textView.textStorage addAttributes:newAttrs range:NSMakeRange(rangeToBeReplaced.location, text.length)];
Expand Down Expand Up @@ -230,9 +230,9 @@ - (void)startMentionWithIndicator:(NSString *)indicator {
NSRange newSelect = NSMakeRange(currentRange.location + finalString.length + (addSpaceAfter ? -1 : 0), 0);

if(currentRange.length == 0) {
[TextInsertionUtils insertText:finalString inView:_editor->textView at:currentRange.location additionalAttributes:nullptr];
[TextInsertionUtils insertText:finalString inView:_editor->textView at:currentRange.location additionalAttributes:nullptr editor:_editor];
} else {
[TextInsertionUtils replaceText:finalString inView:_editor->textView at:currentRange additionalAttributes:nullptr];
[TextInsertionUtils replaceText:finalString inView:_editor->textView at:currentRange additionalAttributes:nullptr editor:_editor];
}

[_editor->textView reactFocus];
Expand Down
6 changes: 3 additions & 3 deletions ios/styles/OrderedListStyle.mm
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ - (void)addAttributes:(NSRange)range {
NSRange fixedRange = NSMakeRange([value rangeValue].location + offset, [value rangeValue].length);

if(fixedRange.length == 0) {
[TextInsertionUtils insertText:@" " inView:_editor->textView at:fixedRange.location additionalAttributes:nullptr];
[TextInsertionUtils insertText:@" " inView:_editor->textView at:fixedRange.location additionalAttributes:nullptr editor:_editor];
fixedRange = NSMakeRange(fixedRange.location, 1);
offset += 1;
}
Expand Down Expand Up @@ -144,7 +144,7 @@ - (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text {

// if there is only a space left we should also remove it as it's apple's placholder for empty lists
if([[_editor->textView.textStorage.string substringWithRange:paragraphRange] isEqualToString:@" "]) {
[TextInsertionUtils replaceText:@"" inView:_editor->textView at:paragraphRange additionalAttributes:nullptr];
[TextInsertionUtils replaceText:@"" inView:_editor->textView at:paragraphRange additionalAttributes:nullptr editor:_editor];
return YES;
}
}
Expand All @@ -166,7 +166,7 @@ - (BOOL)tryHandlingListShorcutInRange:(NSRange)range replacementText:(NSString *
}

// remove the number
[TextInsertionUtils replaceText:@"" inView:_editor->textView at:NSMakeRange(paragraphRange.location, 1) additionalAttributes:nullptr];
[TextInsertionUtils replaceText:@"" inView:_editor->textView at:NSMakeRange(paragraphRange.location, 1) additionalAttributes:nullptr editor:_editor];

if(prevEmitHtml) {
_editor->emitHtml = YES;
Expand Down
6 changes: 3 additions & 3 deletions ios/styles/UnorderedListStyle.mm
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ - (void)addAttributes:(NSRange)range {
NSRange fixedRange = NSMakeRange([value rangeValue].location + offset, [value rangeValue].length);

if(fixedRange.length == 0) {
[TextInsertionUtils insertText:@" " inView:_editor->textView at:fixedRange.location additionalAttributes:nullptr];
[TextInsertionUtils insertText:@" " inView:_editor->textView at:fixedRange.location additionalAttributes:nullptr editor:_editor];
fixedRange = NSMakeRange(fixedRange.location, 1);
offset += 1;
}
Expand Down Expand Up @@ -144,7 +144,7 @@ - (BOOL)handleBackspaceInRange:(NSRange)range replacementText:(NSString *)text {

// if there is only a space left we should also remove it as it's apple's placholder for empty lists
if([[_editor->textView.textStorage.string substringWithRange:paragraphRange] isEqualToString:@" "]) {
[TextInsertionUtils replaceText:@"" inView:_editor->textView at:paragraphRange additionalAttributes:nullptr];
[TextInsertionUtils replaceText:@"" inView:_editor->textView at:paragraphRange additionalAttributes:nullptr editor:_editor];
return YES;
}
}
Expand All @@ -166,7 +166,7 @@ - (BOOL)tryHandlingListShorcutInRange:(NSRange)range replacementText:(NSString *
}

// remove the dash
[TextInsertionUtils replaceText:@"" inView:_editor->textView at:NSMakeRange(paragraphRange.location, 1) additionalAttributes:nullptr];
[TextInsertionUtils replaceText:@"" inView:_editor->textView at:NSMakeRange(paragraphRange.location, 1) additionalAttributes:nullptr editor:_editor];

if(prevEmitHtml) {
_editor->emitHtml = YES;
Expand Down
5 changes: 3 additions & 2 deletions ios/utils/TextInsertionUtils.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import <UIKit/UIKit.h>
#import "ReactNativeRichTextEditorView.h"

@interface TextInsertionUtils : NSObject
+ (void)insertText:(NSString*)text inView:(UITextView*)textView at:(NSInteger)index additionalAttributes:(NSDictionary<NSAttributedStringKey, id>*)additionalAttrs;
+ (void)replaceText:(NSString*)text inView:(UITextView*)textView at:(NSRange)range additionalAttributes:(NSDictionary<NSAttributedStringKey, id>*)additionalAttrs;
+ (void)insertText:(NSString*)text inView:(UITextView*)textView at:(NSInteger)index additionalAttributes:(NSDictionary<NSAttributedStringKey, id>*)additionalAttrs editor:(ReactNativeRichTextEditorView *)editor;
+ (void)replaceText:(NSString*)text inView:(UITextView*)textView at:(NSRange)range additionalAttributes:(NSDictionary<NSAttributedStringKey, id>*)additionalAttrs editor:(ReactNativeRichTextEditorView *)editor;
@end
16 changes: 7 additions & 9 deletions ios/utils/TextInsertionUtils.mm
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#import "TextInsertionUtils.h"
#import "UIView+React.h"
#import "ReactNativeRichTextEditorView.h"


@implementation TextInsertionUtils
+ (void)insertText:(NSString*)text inView:(UITextView*)textView at:(NSInteger)index additionalAttributes:(NSDictionary<NSAttributedStringKey, id>*)additionalAttrs {
+ (void)insertText:(NSString*)text inView:(UITextView*)textView at:(NSInteger)index additionalAttributes:(NSDictionary<NSAttributedStringKey, id>*)additionalAttrs editor:(ReactNativeRichTextEditorView *)editor {
NSMutableDictionary<NSAttributedStringKey, id> *copiedAttrs = [textView.typingAttributes mutableCopy];
if(additionalAttrs != nullptr) {
[copiedAttrs addEntriesFromDictionary: additionalAttrs];
Expand All @@ -15,13 +15,12 @@ + (void)insertText:(NSString*)text inView:(UITextView*)textView at:(NSInteger)in
[textView reactFocus];
textView.selectedRange = NSMakeRange(index + text.length, 0);

ReactNativeRichTextEditorView *typedEditor = (ReactNativeRichTextEditorView *)textView.delegate;
if(typedEditor != nullptr) {
typedEditor->recentlyChangedRange = NSMakeRange(index, text.length);
if(editor != nullptr) {
editor->recentlyChangedRange = NSMakeRange(index, text.length);
}
}

+ (void)replaceText:(NSString*)text inView:(UITextView*)textView at:(NSRange)range additionalAttributes:(NSDictionary<NSAttributedStringKey, id>*)additionalAttrs {
+ (void)replaceText:(NSString*)text inView:(UITextView*)textView at:(NSRange)range additionalAttributes:(NSDictionary<NSAttributedStringKey, id>*)additionalAttrs editor:(ReactNativeRichTextEditorView *)editor {
[textView.textStorage replaceCharactersInRange:range withString:text];
if(additionalAttrs != nullptr) {
[textView.textStorage addAttributes:additionalAttrs range:NSMakeRange(range.location, [text length])];
Expand All @@ -30,9 +29,8 @@ + (void)replaceText:(NSString*)text inView:(UITextView*)textView at:(NSRange)ran
[textView reactFocus];
textView.selectedRange = NSMakeRange(range.location + text.length, 0);

ReactNativeRichTextEditorView *typedEditor = (ReactNativeRichTextEditorView *)textView.delegate;
if(typedEditor != nullptr) {
typedEditor->recentlyChangedRange = NSMakeRange(range.location, text.length);
if(editor != nullptr) {
editor->recentlyChangedRange = NSMakeRange(range.location, text.length);
}
}
@end
Loading