Skip to content

Commit

Permalink
Fix cursor position in new line after blockquote
Browse files Browse the repository at this point in the history
  • Loading branch information
tomekzaw committed Nov 26, 2024
1 parent 5cf9b9b commit c00c440
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
12 changes: 12 additions & 0 deletions apple/MarkdownBackedTextInputDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#import <React/RCTBackedTextInputDelegate.h>
#import <React/RCTUITextView.h>

NS_ASSUME_NONNULL_BEGIN

@interface MarkdownBackedTextInputDelegate : NSObject <RCTBackedTextInputDelegate>

- (instancetype)initWithTextView:(RCTUITextView *)textView;

@end

NS_ASSUME_NONNULL_END
76 changes: 76 additions & 0 deletions apple/MarkdownBackedTextInputDelegate.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#import "MarkdownBackedTextInputDelegate.h"

@implementation MarkdownBackedTextInputDelegate {
__weak RCTUITextView *_textView;
id<RCTBackedTextInputDelegate> _originalTextInputDelegate;
}

- (instancetype)initWithTextView:(RCTUITextView *)textView
{
if (self = [super init]) {
_textView = textView;
_originalTextInputDelegate = _textView.textInputDelegate;
_textView.textInputDelegate = self;
}
return self;
}

- (void)dealloc
{
// Restore original text input delegate
_textView.textInputDelegate = _originalTextInputDelegate;
}

- (void)textInputDidChange
{
// After adding a newline at the end of the blockquote, the typing attributes in the new line
// still contain NSParagraphStyle with non-zero firstLineHeadIndent and headIntent.
// This causes the cursor to be shifted to the right instead of being located at the beginning of the line.
// The following code removes NSParagraphStyle from typing attributes to fix the position of the cursor.
NSMutableDictionary *typingAttributes = [_textView.typingAttributes mutableCopy];
[typingAttributes removeObjectForKey:NSParagraphStyleAttributeName];
_textView.typingAttributes = typingAttributes;

// Delegate the call to the original text input delegate
[_originalTextInputDelegate textInputDidChange];
}

// Delegate all remaining calls to the original text input delegate

- (void)textInputDidBeginEditing {
[_originalTextInputDelegate textInputDidBeginEditing];
}

- (void)textInputDidChangeSelection {
[_originalTextInputDelegate textInputDidChangeSelection];
}

- (void)textInputDidEndEditing {
[_originalTextInputDelegate textInputDidEndEditing];
}

- (void)textInputDidReturn {
[_originalTextInputDelegate textInputDidReturn];
}

- (BOOL)textInputShouldBeginEditing {
return [_originalTextInputDelegate textInputShouldBeginEditing];
}

- (nonnull NSString *)textInputShouldChangeText:(nonnull NSString *)text inRange:(NSRange)range {
return [_originalTextInputDelegate textInputShouldChangeText:text inRange:range];
}

- (BOOL)textInputShouldEndEditing {
return [_originalTextInputDelegate textInputShouldEndEditing];
}

- (BOOL)textInputShouldReturn {
return [_originalTextInputDelegate textInputShouldReturn];
}

- (BOOL)textInputShouldSubmitOnReturn {
return [_originalTextInputDelegate textInputShouldSubmitOnReturn];
}

@end
6 changes: 6 additions & 0 deletions apple/MarkdownTextInputDecoratorView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#import <React/RCTBaseTextInputView.h>
#endif

#import <RNLiveMarkdown/MarkdownBackedTextInputDelegate.h>
#import <RNLiveMarkdown/MarkdownLayoutManager.h>
#import <RNLiveMarkdown/MarkdownTextInputDecoratorView.h>
#import <RNLiveMarkdown/MarkdownTextStorageDelegate.h>
Expand All @@ -18,6 +19,7 @@
@implementation MarkdownTextInputDecoratorView {
RCTMarkdownUtils *_markdownUtils;
RCTMarkdownStyle *_markdownStyle;
MarkdownBackedTextInputDelegate *_markdownBackedTextInputDelegate;
MarkdownTextStorageDelegate *_markdownTextStorageDelegate;
MarkdownTextFieldObserver *_markdownTextFieldObserver;
__weak RCTUITextView *_textView;
Expand Down Expand Up @@ -86,6 +88,9 @@ - (void)didMoveToWindow {
_markdownTextStorageDelegate = [[MarkdownTextStorageDelegate alloc] initWithTextView:_textView markdownUtils:_markdownUtils];
_textView.textStorage.delegate = _markdownTextStorageDelegate;

// register delegate for fixing cursor position
_markdownBackedTextInputDelegate = [[MarkdownBackedTextInputDelegate alloc] initWithTextView:_textView];

#ifdef RCT_NEW_ARCH_ENABLED
// format initial value
[_textView.textStorage setAttributedString:_textView.attributedText];
Expand Down Expand Up @@ -117,6 +122,7 @@ - (void)willMoveToWindow:(UIWindow *)newWindow
[_textView.layoutManager setValue:nil forKey:@"markdownUtils"];
object_setClass(_textView.layoutManager, [NSLayoutManager class]);
}
_markdownBackedTextInputDelegate = nil;
_markdownTextStorageDelegate = nil;
_textView.textStorage.delegate = nil;
_textView = nil;
Expand Down

0 comments on commit c00c440

Please sign in to comment.