diff --git a/shell/platform/android/io/flutter/plugin/editing/SpellCheckPlugin.java b/shell/platform/android/io/flutter/plugin/editing/SpellCheckPlugin.java index 1bfc503a73c4c..f74076c7af45b 100644 --- a/shell/platform/android/io/flutter/plugin/editing/SpellCheckPlugin.java +++ b/shell/platform/android/io/flutter/plugin/editing/SpellCheckPlugin.java @@ -89,7 +89,6 @@ public void initiateSpellCheck( /** Calls on the Android spell check API to spell check specified text. */ public void performSpellCheck(@NonNull String locale, @NonNull String text) { - String[] localeCodes = locale.split("-"); Locale localeFromString = LocalizationPlugin.localeFromString(locale); if (mSpellCheckerSession == null) { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm index 2eac491c3cefc..1b2038b5f63ea 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm @@ -61,6 +61,8 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { // Returns an empty array if no spell check suggestions. - (NSArray*>*)findAllSpellCheckSuggestionsForText:(NSString*)text inLanguage:(NSString*)language { + // Transform Dart Locale format to iOS language format. + language = [language stringByReplacingOccurrencesOfString:@"-" withString:@"_"]; if (![UITextChecker.availableLanguages containsObject:language]) { return nil; } @@ -145,7 +147,9 @@ - (instancetype)initWithMisspelledRange:(NSRange)range - (NSDictionary*)toDictionary { NSMutableDictionary* result = [[[NSMutableDictionary alloc] initWithCapacity:3] autorelease]; result[@"startIndex"] = @(_misspelledRange.location); - result[@"endIndex"] = @(_misspelledRange.location + _misspelledRange.length - 1); + // The end index represents the next index after the last character of a misspelled word to match + // the behavior of Dart's TextRange: https://api.flutter.dev/flutter/dart-ui/TextRange/end.html + result[@"endIndex"] = @(_misspelledRange.location + _misspelledRange.length); result[@"suggestions"] = _suggestions; return result; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPluginTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPluginTest.mm index 92fc4469b8872..221050638efea 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPluginTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPluginTest.mm @@ -161,11 +161,11 @@ - (void)testFindAllSpellCheckSuggestionsForText { XCTAssertTrue(capturedResult.count == 2); NSDictionary* suggestionsJSON1 = capturedResult.firstObject; XCTAssertEqualObjects(suggestionsJSON1[@"startIndex"], @0); - XCTAssertEqualObjects(suggestionsJSON1[@"endIndex"], @4); + XCTAssertEqualObjects(suggestionsJSON1[@"endIndex"], @5); XCTAssertEqualObjects(suggestionsJSON1[@"suggestions"], suggestions1); NSDictionary* suggestionsJSON2 = capturedResult[1]; XCTAssertEqualObjects(suggestionsJSON2[@"startIndex"], @5); - XCTAssertEqualObjects(suggestionsJSON2[@"endIndex"], @9); + XCTAssertEqualObjects(suggestionsJSON2[@"endIndex"], @10); XCTAssertEqualObjects(suggestionsJSON2[@"suggestions"], suggestions2); [self.mockTextChecker reset]; [textCheckerClassMock stopMocking]; @@ -198,11 +198,11 @@ - (void)testStopFindingMoreWhenTheLastWordIsMisspelled { XCTAssertTrue(capturedResult.count == 2); NSDictionary* suggestionsJSON1 = capturedResult.firstObject; XCTAssertEqualObjects(suggestionsJSON1[@"startIndex"], @0); - XCTAssertEqualObjects(suggestionsJSON1[@"endIndex"], @4); + XCTAssertEqualObjects(suggestionsJSON1[@"endIndex"], @5); XCTAssertEqualObjects(suggestionsJSON1[@"suggestions"], suggestions1); NSDictionary* suggestionsJSON2 = capturedResult[1]; XCTAssertEqualObjects(suggestionsJSON2[@"startIndex"], @6); - XCTAssertEqualObjects(suggestionsJSON2[@"endIndex"], @9); + XCTAssertEqualObjects(suggestionsJSON2[@"endIndex"], @10); XCTAssertEqualObjects(suggestionsJSON2[@"suggestions"], suggestions2); [self.mockTextChecker reset]; [textCheckerClassMock stopMocking]; @@ -228,7 +228,7 @@ - (void)testStopFindingMoreWhenTheWholeStringIsAMisspelledWord { XCTAssertTrue(capturedResult.count == 1); NSDictionary* suggestionsJSON1 = capturedResult.firstObject; XCTAssertEqualObjects(suggestionsJSON1[@"startIndex"], @0); - XCTAssertEqualObjects(suggestionsJSON1[@"endIndex"], @4); + XCTAssertEqualObjects(suggestionsJSON1[@"endIndex"], @5); XCTAssertEqualObjects(suggestionsJSON1[@"suggestions"], suggestions1); [self.mockTextChecker reset]; [textCheckerClassMock stopMocking]; @@ -270,6 +270,29 @@ - (void)testUnsupportedLanguageShouldReturnNil { [textCheckerClassMock stopMocking]; } +- (void)testSupportSubLanguage { + self.partialMockPlugin = OCMPartialMock(self.plugin); + OCMStub([self.partialMockPlugin textChecker]).andReturn(self.mockTextChecker); + id textCheckerClassMock = OCMClassMock([UITextChecker class]); + [[[textCheckerClassMock stub] andReturn:@[ @"en_us" ]] availableLanguages]; + NSArray* suggestions1 = @[ @"suggestion 1", @"suggestion 2" ]; + + [self mockUITextCheckerWithExpectedMisspelledWordRange:NSMakeRange(0, 5) + startingIndex:0 + suggestions:suggestions1]; + __block NSArray* capturedResult; + [self.mockMethodChannel invokeMethod:@"SpellCheck.initiateSpellCheck" + arguments:@[ @"en-us", @"hejjo" ] + result:^(id _Nullable result) { + capturedResult = result; + }]; + NSDictionary* suggestionsJSON1 = capturedResult.firstObject; + XCTAssertEqualObjects(suggestionsJSON1[@"startIndex"], @0); + XCTAssertEqualObjects(suggestionsJSON1[@"endIndex"], @5); + XCTAssertEqualObjects(suggestionsJSON1[@"suggestions"], suggestions1); + [textCheckerClassMock stopMocking]; +} + - (void)testEmptyStringShouldReturnEmptyResults { self.partialMockPlugin = OCMPartialMock(self.plugin); OCMStub([self.partialMockPlugin textChecker]).andReturn(self.mockTextChecker); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 8719855a7e5b8..d4ce938899df9 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -1654,7 +1654,8 @@ - (void)onUserSettingsChanged:(NSNotification*)notification { @"textScaleFactor" : @([self textScaleFactor]), @"alwaysUse24HourFormat" : @([self isAlwaysUse24HourFormat]), @"platformBrightness" : [self brightnessMode], - @"platformContrast" : [self contrastMode] + @"platformContrast" : [self contrastMode], + @"nativeSpellCheckServiceDefined" : @true }]; }