Skip to content

Commit

Permalink
[CP] Fix crash with CJK keyboard with emoji at end of text field (#42540
Browse files Browse the repository at this point in the history
) (#42945)

Cherry pick of #42540
  • Loading branch information
Jasguerrero committed Jun 20, 2023
1 parent a057b3a commit d4e07a9
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1658,25 +1658,6 @@ - (CGRect)firstRectForRange:(UITextRange*)range {
return CGRectZero;
}

- (BOOL)isRTLAtPosition:(NSUInteger)position {
// _selectionRects is sorted by position already.
// We can use binary search.
NSInteger min = 0;
NSInteger max = [_selectionRects count];
while (min <= max) {
const NSUInteger mid = min + (max - min) / 2;
FlutterTextSelectionRect* rect = _selectionRects[mid];
if (rect.position > position) {
max = mid - 1;
} else if (rect.position == position) {
return rect.isRTL;
} else {
min = mid + 1;
}
}
return NO;
}

- (CGRect)caretRectForPosition:(UITextPosition*)position {
NSInteger index = ((FlutterTextPosition*)position).index;
UITextStorageDirection affinity = ((FlutterTextPosition*)position).affinity;
Expand All @@ -1699,7 +1680,8 @@ - (CGRect)caretRectForPosition:(UITextPosition*)position {
CGRect characterAfterCaret = rects[0].rect;
// Return a zero-width rectangle along the upstream edge of the character after the caret
// position.
if ([self isRTLAtPosition:index]) {
if ([rects[0] isKindOfClass:[FlutterTextSelectionRect class]] &&
((FlutterTextSelectionRect*)rects[0]).isRTL) {
return CGRectMake(characterAfterCaret.origin.x + characterAfterCaret.size.width,
characterAfterCaret.origin.y, 0, characterAfterCaret.size.height);
} else {
Expand All @@ -1712,7 +1694,8 @@ - (CGRect)caretRectForPosition:(UITextPosition*)position {
CGRect characterAfterCaret = rects[1].rect;
// Return a zero-width rectangle along the upstream edge of the character after the caret
// position.
if ([self isRTLAtPosition:index]) {
if ([rects[1] isKindOfClass:[FlutterTextSelectionRect class]] &&
((FlutterTextSelectionRect*)rects[1]).isRTL) {
return CGRectMake(characterAfterCaret.origin.x + characterAfterCaret.size.width,
characterAfterCaret.origin.y, 0, characterAfterCaret.size.height);
} else {
Expand All @@ -1727,7 +1710,8 @@ - (CGRect)caretRectForPosition:(UITextPosition*)position {
// For both cases, return a zero-width rectangle along the downstream edge of the character
// before the caret position.
CGRect characterBeforeCaret = rects[0].rect;
if ([self isRTLAtPosition:index - 1]) {
if ([rects[0] isKindOfClass:[FlutterTextSelectionRect class]] &&
((FlutterTextSelectionRect*)rects[0]).isRTL) {
return CGRectMake(characterBeforeCaret.origin.x, characterBeforeCaret.origin.y, 0,
characterBeforeCaret.size.height);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1535,6 +1535,29 @@ - (void)testClosestPositionToPointWithinRange {
((FlutterTextPosition*)[inputView closestPositionToPoint:point withinRange:range]).affinity);
}

- (void)testClosestPositionToPointWithPartialSelectionRects {
FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
[inputView setTextInputState:@{@"text" : @"COMPOSING"}];

[inputView setSelectionRects:@[ [FlutterTextSelectionRect
selectionRectWithRect:CGRectMake(0, 0, 100, 100)
position:0U] ]];
// Asking with a position at the end of selection rects should give you the trailing edge of
// the last rect.
XCTAssertTrue(CGRectEqualToRect(
[inputView caretRectForPosition:[FlutterTextPosition
positionWithIndex:1
affinity:UITextStorageDirectionForward]],
CGRectMake(100, 0, 0, 100)));
// Asking with a position beyond the end of selection rects should return CGRectZero without
// crashing.
XCTAssertTrue(CGRectEqualToRect(
[inputView caretRectForPosition:[FlutterTextPosition
positionWithIndex:2
affinity:UITextStorageDirectionForward]],
CGRectZero));
}

#pragma mark - Floating Cursor - Tests

- (void)testFloatingCursorDoesNotThrow {
Expand Down

0 comments on commit d4e07a9

Please sign in to comment.