From 754b3a31d1523566b415083d9ad06ddd59109040 Mon Sep 17 00:00:00 2001 From: camsim99 Date: Wed, 24 Aug 2022 13:49:38 -0700 Subject: [PATCH 1/7] Add nativeSpellCheckServiceDefined: --- shell/platform/darwin/macos/framework/Source/FlutterEngine.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index ab4b8f4e96ea9..77a97906fd060 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -540,7 +540,8 @@ - (void)onSettingsChanged:(NSNotification*)notification { @"platformBrightness" : [brightness isEqualToString:@"Dark"] ? @"dark" : @"light", // TODO(jonahwilliams): https://github.com/flutter/flutter/issues/32006. @"textScaleFactor" : @1.0, - @"alwaysUse24HourFormat" : @false + @"alwaysUse24HourFormat" : @false, + @"nativeSpellCheckServiceDefined" : @true }]; } From 4b812801ef762dce6a3b074a30e0801d47217ce0 Mon Sep 17 00:00:00 2001 From: camsim99 Date: Thu, 25 Aug 2022 16:40:04 -0700 Subject: [PATCH 2/7] Make corrections --- .../android/io/flutter/plugin/editing/SpellCheckPlugin.java | 1 - .../darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm | 4 +++- .../darwin/ios/framework/Source/FlutterViewController.mm | 3 ++- shell/platform/darwin/macos/framework/Source/FlutterEngine.mm | 1 - 4 files changed, 5 insertions(+), 4 deletions(-) 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..9fe6a47adf1e7 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,7 @@ - (instancetype)initWithMisspelledRange:(NSRange)range - (NSDictionary*)toDictionary { NSMutableDictionary* result = [[[NSMutableDictionary alloc] initWithCapacity:3] autorelease]; result[@"startIndex"] = @(_misspelledRange.location); - result[@"endIndex"] = @(_misspelledRange.location + _misspelledRange.length - 1); + result[@"endIndex"] = @(_misspelledRange.location + _misspelledRange.length); result[@"suggestions"] = _suggestions; return result; } 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 }]; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 77a97906fd060..35e298b5ff784 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -541,7 +541,6 @@ - (void)onSettingsChanged:(NSNotification*)notification { // TODO(jonahwilliams): https://github.com/flutter/flutter/issues/32006. @"textScaleFactor" : @1.0, @"alwaysUse24HourFormat" : @false, - @"nativeSpellCheckServiceDefined" : @true }]; } From b51ad98086c4251a5ce643413bcda45e9dabb279 Mon Sep 17 00:00:00 2001 From: camsim99 Date: Fri, 26 Aug 2022 10:45:41 -0700 Subject: [PATCH 3/7] Formatting --- .../platform/darwin/macos/framework/Source/FlutterEngine.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 35e298b5ff784..25e89d22f2507 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -643,9 +643,9 @@ - (void)sendUserLocales { // Convert to a list of pointers, and send to the engine. std::vector flutterLocaleList; flutterLocaleList.reserve(flutterLocales.size()); - std::transform( - flutterLocales.begin(), flutterLocales.end(), std::back_inserter(flutterLocaleList), - [](const auto& arg) -> const auto* { return &arg; }); + std::transform(flutterLocales.begin(), flutterLocales.end(), + std::back_inserter(flutterLocaleList), + [](const auto& arg) -> const auto* { return &arg; }); _embedderAPI.UpdateLocales(_engine, flutterLocaleList.data(), flutterLocaleList.size()); } From 7f58d19bd52bd4770f08d77e21d384e62637120c Mon Sep 17 00:00:00 2001 From: camsim99 Date: Fri, 26 Aug 2022 10:47:24 -0700 Subject: [PATCH 4/7] Revert changes to FlutterEngine --- .../darwin/macos/framework/Source/FlutterEngine.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 25e89d22f2507..ab4b8f4e96ea9 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -540,7 +540,7 @@ - (void)onSettingsChanged:(NSNotification*)notification { @"platformBrightness" : [brightness isEqualToString:@"Dark"] ? @"dark" : @"light", // TODO(jonahwilliams): https://github.com/flutter/flutter/issues/32006. @"textScaleFactor" : @1.0, - @"alwaysUse24HourFormat" : @false, + @"alwaysUse24HourFormat" : @false }]; } @@ -643,9 +643,9 @@ - (void)sendUserLocales { // Convert to a list of pointers, and send to the engine. std::vector flutterLocaleList; flutterLocaleList.reserve(flutterLocales.size()); - std::transform(flutterLocales.begin(), flutterLocales.end(), - std::back_inserter(flutterLocaleList), - [](const auto& arg) -> const auto* { return &arg; }); + std::transform( + flutterLocales.begin(), flutterLocales.end(), std::back_inserter(flutterLocaleList), + [](const auto& arg) -> const auto* { return &arg; }); _embedderAPI.UpdateLocales(_engine, flutterLocaleList.data(), flutterLocaleList.size()); } From 0d92b62f916200906b48501e95e2510013ebc014 Mon Sep 17 00:00:00 2001 From: camsim99 Date: Thu, 1 Sep 2022 16:57:40 -0700 Subject: [PATCH 5/7] Add comment --- .../darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm index 9fe6a47adf1e7..7c15bb2d19eb4 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm @@ -147,6 +147,9 @@ - (instancetype)initWithMisspelledRange:(NSRange)range - (NSDictionary*)toDictionary { NSMutableDictionary* result = [[[NSMutableDictionary alloc] initWithCapacity:3] autorelease]; result[@"startIndex"] = @(_misspelledRange.location); + // 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; From 293ad93563801cc4f4187f6c250f842c9376ba74 Mon Sep 17 00:00:00 2001 From: camsim99 Date: Fri, 2 Sep 2022 09:00:51 -0700 Subject: [PATCH 6/7] Formatting --- .../darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm index 7c15bb2d19eb4..1b2038b5f63ea 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm @@ -147,9 +147,8 @@ - (instancetype)initWithMisspelledRange:(NSRange)range - (NSDictionary*)toDictionary { NSMutableDictionary* result = [[[NSMutableDictionary alloc] initWithCapacity:3] autorelease]; result[@"startIndex"] = @(_misspelledRange.location); - // 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 + // 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; From d25457fbab093a9e9baf72410b3de2671fd059a9 Mon Sep 17 00:00:00 2001 From: camsim99 Date: Fri, 2 Sep 2022 15:03:05 -0700 Subject: [PATCH 7/7] Add back tests --- .../Source/FlutterSpellCheckPluginTest.mm | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) 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);