未验证 提交 69cbb2bb 编写于 作者: J Justin McCandless 提交者: GitHub

iOS Text Editing Infinite Loop (#20160)

Fixes an infinite loop by eliminating an unnecessary engine/framework message.
上级 fb19b871
......@@ -537,10 +537,7 @@ static FlutterAutofillType autofillTypeOf(NSDictionary* configuration) {
_textInputClient = client;
}
// Return true if the new input state needs to be synced back to the framework.
// TODO(LongCatIsLooong): setTextInputState should never call updateEditingState. Sending the
// editing value back may overwrite the framework's updated editing value.
- (BOOL)setTextInputState:(NSDictionary*)state {
- (void)setTextInputState:(NSDictionary*)state {
NSString* newText = state[@"text"];
BOOL textChanged = ![self.text isEqualToString:newText];
if (textChanged) {
......@@ -575,9 +572,6 @@ static FlutterAutofillType autofillTypeOf(NSDictionary* configuration) {
if (textChanged) {
[self.inputDelegate textDidChange:self];
}
// For consistency with Android behavior, send an update to the framework if the text changed.
return textChanged;
}
// Extracts the selection information from the editing state dictionary.
......@@ -1423,9 +1417,7 @@ static FlutterAutofillType autofillTypeOf(NSDictionary* configuration) {
}
- (void)setTextInputEditingState:(NSDictionary*)state {
if ([_activeView setTextInputState:state]) {
[_activeView updateEditingState];
}
[_activeView setTextInputState:state];
}
- (void)clearTextInputClient {
......
......@@ -16,7 +16,7 @@ FLUTTER_ASSERT_ARC
@property(nonatomic, copy) NSString* autofillId;
- (void)setEditableTransform:(NSArray*)matrix;
- (BOOL)setTextInputState:(NSDictionary*)state;
- (void)setTextInputState:(NSDictionary*)state;
- (void)setMarkedRect:(CGRect)markedRect;
- (void)updateEditingState;
- (BOOL)isVisibleToAutofill;
......@@ -211,71 +211,45 @@ FLUTTER_ASSERT_ARC
XCTAssertEqual(updateCount, 6);
}
- (void)testTextChangesTriggerUpdateEditingClient {
- (void)testTextChangesDoNotTriggerUpdateEditingClient {
FlutterTextInputView* inputView = [[FlutterTextInputView alloc] init];
inputView.textInputDelegate = engine;
[inputView.text setString:@"BEFORE"];
inputView.markedTextRange = nil;
inputView.selectedTextRange = nil;
// Text changes trigger update.
XCTAssertTrue([inputView setTextInputState:@{@"text" : @"AFTER"}]);
// Don't send anything if there's nothing new.
XCTAssertFalse([inputView setTextInputState:@{@"text" : @"AFTER"}]);
}
__block int updateCount = 0;
OCMStub([engine updateEditingClient:0 withState:[OCMArg isNotNil]])
.andDo(^(NSInvocation* invocation) {
updateCount++;
});
- (void)testSelectionChangeDoesNotTriggerUpdateEditingClient {
FlutterTextInputView* inputView = [[FlutterTextInputView alloc] init];
inputView.textInputDelegate = engine;
[inputView.text setString:@"BEFORE"];
XCTAssertEqual(updateCount, 0);
[inputView.text setString:@"SELECTION"];
inputView.markedTextRange = nil;
inputView.selectedTextRange = nil;
XCTAssertEqual(updateCount, 1);
BOOL shouldUpdate = [inputView
setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @0, @"selectionExtent" : @3}];
XCTAssertFalse(shouldUpdate);
// Text changes don't trigger an update.
XCTAssertEqual(updateCount, 1);
[inputView setTextInputState:@{@"text" : @"AFTER"}];
XCTAssertEqual(updateCount, 1);
[inputView setTextInputState:@{@"text" : @"AFTER"}];
XCTAssertEqual(updateCount, 1);
shouldUpdate = [inputView
// Selection changes don't trigger an update.
[inputView
setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @0, @"selectionExtent" : @3}];
XCTAssertEqual(updateCount, 1);
[inputView
setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @1, @"selectionExtent" : @3}];
XCTAssertFalse(shouldUpdate);
shouldUpdate = [inputView
setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @1, @"selectionExtent" : @2}];
XCTAssertFalse(shouldUpdate);
// Don't send anything if there's nothing new.
shouldUpdate = [inputView
setTextInputState:@{@"text" : @"SELECTION", @"selectionBase" : @1, @"selectionExtent" : @2}];
XCTAssertFalse(shouldUpdate);
}
- (void)testComposingChangeDoesNotTriggerUpdateEditingClient {
FlutterTextInputView* inputView = [[FlutterTextInputView alloc] init];
inputView.textInputDelegate = engine;
// Reset to test marked text.
[inputView.text setString:@"COMPOSING"];
inputView.markedTextRange = nil;
inputView.selectedTextRange = nil;
BOOL shouldUpdate = [inputView
setTextInputState:@{@"text" : @"COMPOSING", @"composingBase" : @0, @"composingExtent" : @3}];
XCTAssertFalse(shouldUpdate);
shouldUpdate = [inputView
setTextInputState:@{@"text" : @"COMPOSING", @"composingBase" : @1, @"composingExtent" : @3}];
XCTAssertFalse(shouldUpdate);
shouldUpdate = [inputView
setTextInputState:@{@"text" : @"COMPOSING", @"composingBase" : @1, @"composingExtent" : @2}];
XCTAssertFalse(shouldUpdate);
XCTAssertEqual(updateCount, 1);
shouldUpdate = [inputView
// Composing region changes don't trigger an update.
[inputView
setTextInputState:@{@"text" : @"COMPOSING", @"composingBase" : @1, @"composingExtent" : @2}];
XCTAssertFalse(shouldUpdate);
XCTAssertEqual(updateCount, 1);
[inputView
setTextInputState:@{@"text" : @"COMPOSING", @"composingBase" : @1, @"composingExtent" : @3}];
XCTAssertEqual(updateCount, 1);
}
- (void)testUITextInputAvoidUnnecessaryUndateEditingClientCalls {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册