OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "ios/web_view/internal/translate/cwv_translation_controller_internal.h" | 5 #import "ios/web_view/internal/translate/cwv_translation_controller_internal.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "base/strings/string16.h" | 10 #include "base/strings/string16.h" |
| 11 #include "base/strings/sys_string_conversions.h" |
| 12 #include "components/translate/core/browser/translate_download_manager.h" |
11 #include "components/translate/core/browser/translate_manager.h" | 13 #include "components/translate/core/browser/translate_manager.h" |
12 #include "components/translate/core/browser/translate_ui_delegate.h" | |
13 #import "ios/web_view/internal/translate/cwv_language_detection_result_internal.
h" | 14 #import "ios/web_view/internal/translate/cwv_language_detection_result_internal.
h" |
14 #import "ios/web_view/internal/translate/cwv_translation_language_internal.h" | 15 #import "ios/web_view/internal/translate/cwv_translation_language_internal.h" |
15 #import "ios/web_view/internal/translate/web_view_translate_client.h" | 16 #import "ios/web_view/internal/translate/web_view_translate_client.h" |
16 #import "ios/web_view/public/cwv_translation_controller_delegate.h" | 17 #import "ios/web_view/public/cwv_translation_controller_delegate.h" |
| 18 #import "ios/web_view/public/cwv_translation_policy.h" |
| 19 #include "ui/base/l10n/l10n_util.h" |
17 | 20 |
18 #if !defined(__has_feature) || !__has_feature(objc_arc) | 21 #if !defined(__has_feature) || !__has_feature(objc_arc) |
19 #error "This file requires ARC support." | 22 #error "This file requires ARC support." |
20 #endif | 23 #endif |
21 | 24 |
22 NSErrorDomain const CWVTranslationErrorDomain = | 25 NSErrorDomain const CWVTranslationErrorDomain = |
23 @"org.chromium.chromewebview.TranslationErrorDomain"; | 26 @"org.chromium.chromewebview.TranslationErrorDomain"; |
24 | 27 |
25 const NSInteger CWVTranslationErrorNetwork = | 28 const NSInteger CWVTranslationErrorNetwork = |
26 translate::TranslateErrors::NETWORK; | 29 translate::TranslateErrors::NETWORK; |
(...skipping 11 matching lines...) Expand all Loading... |
38 translate::TranslateErrors::TRANSLATION_TIMEOUT; | 41 translate::TranslateErrors::TRANSLATION_TIMEOUT; |
39 const NSInteger CWVTranslationErrorUnexpectedScriptError = | 42 const NSInteger CWVTranslationErrorUnexpectedScriptError = |
40 translate::TranslateErrors::UNEXPECTED_SCRIPT_ERROR; | 43 translate::TranslateErrors::UNEXPECTED_SCRIPT_ERROR; |
41 const NSInteger CWVTranslationErrorBadOrigin = | 44 const NSInteger CWVTranslationErrorBadOrigin = |
42 translate::TranslateErrors::BAD_ORIGIN; | 45 translate::TranslateErrors::BAD_ORIGIN; |
43 const NSInteger CWVTranslationErrorScriptLoadError = | 46 const NSInteger CWVTranslationErrorScriptLoadError = |
44 translate::TranslateErrors::SCRIPT_LOAD_ERROR; | 47 translate::TranslateErrors::SCRIPT_LOAD_ERROR; |
45 | 48 |
46 @interface CWVTranslationController () | 49 @interface CWVTranslationController () |
47 | 50 |
48 // Convenience method to generate all supported languages from | 51 // A map of CWTranslationLanguages keyed by its language code. Lazily loaded. |
49 // |translateUIDelegate|. | 52 @property(nonatomic, readonly) |
50 - (NSArray<CWVTranslationLanguage*>*)supportedLanguages; | 53 NSDictionary<NSString*, CWVTranslationLanguage*>* supportedLanguagesByCode; |
51 | 54 |
52 // Convenience method to get a language at |index| from |translateUIDelegate|. | 55 // Convenience method to get the language with |languageCode|. |
53 - (CWVTranslationLanguage*)languageAtIndex:(size_t)index; | 56 - (CWVTranslationLanguage*)languageWithCode:(const std::string&)languageCode; |
54 | 57 |
55 @end | 58 @end |
56 | 59 |
57 @implementation CWVTranslationController { | 60 @implementation CWVTranslationController { |
58 ios_web_view::WebViewTranslateClient* _translateClient; | 61 ios_web_view::WebViewTranslateClient* _translateClient; |
59 std::unique_ptr<translate::TranslateUIDelegate> _translateUIDelegate; | 62 std::unique_ptr<translate::TranslatePrefs> _translatePrefs; |
60 } | 63 } |
61 | 64 |
62 @synthesize delegate = _delegate; | 65 @synthesize delegate = _delegate; |
| 66 @synthesize supportedLanguagesByCode = _supportedLanguagesByCode; |
63 @synthesize webState = _webState; | 67 @synthesize webState = _webState; |
64 | 68 |
65 #pragma mark - Internal Methods | 69 #pragma mark - Internal Methods |
66 | 70 |
67 - (void)setWebState:(web::WebState*)webState { | 71 - (void)setWebState:(web::WebState*)webState { |
68 _webState = webState; | 72 _webState = webState; |
69 | 73 |
70 ios_web_view::WebViewTranslateClient::CreateForWebState(_webState); | 74 ios_web_view::WebViewTranslateClient::CreateForWebState(_webState); |
71 _translateClient = | 75 _translateClient = |
72 ios_web_view::WebViewTranslateClient::FromWebState(_webState); | 76 ios_web_view::WebViewTranslateClient::FromWebState(_webState); |
73 _translateClient->set_translation_controller(self); | 77 _translateClient->set_translation_controller(self); |
| 78 _translatePrefs = _translateClient->translate_manager() |
| 79 ->translate_client() |
| 80 ->GetTranslatePrefs(); |
74 } | 81 } |
75 | 82 |
76 - (void)updateTranslateStep:(translate::TranslateStep)step | 83 - (void)updateTranslateStep:(translate::TranslateStep)step |
77 sourceLanguage:(const std::string&)sourceLanguage | 84 sourceLanguage:(const std::string&)sourceLanguage |
78 targetLanguage:(const std::string&)targetLanguage | 85 targetLanguage:(const std::string&)targetLanguage |
79 errorType:(translate::TranslateErrors::Type)errorType | 86 errorType:(translate::TranslateErrors::Type)errorType |
80 triggeredFromMenu:(bool)triggeredFromMenu { | 87 triggeredFromMenu:(bool)triggeredFromMenu { |
81 translate::TranslateManager* manager = _translateClient->translate_manager(); | 88 CWVTranslationLanguage* source = [self languageWithCode:sourceLanguage]; |
82 _translateUIDelegate = base::MakeUnique<translate::TranslateUIDelegate>( | 89 CWVTranslationLanguage* target = [self languageWithCode:targetLanguage]; |
83 manager->GetWeakPtr(), sourceLanguage, targetLanguage); | |
84 | |
85 CWVTranslationLanguage* source = | |
86 [self languageAtIndex:_translateUIDelegate->GetOriginalLanguageIndex()]; | |
87 CWVTranslationLanguage* target = | |
88 [self languageAtIndex:_translateUIDelegate->GetTargetLanguageIndex()]; | |
89 | 90 |
90 NSError* error; | 91 NSError* error; |
91 if (errorType != translate::TranslateErrors::NONE) { | 92 if (errorType != translate::TranslateErrors::NONE) { |
92 error = [NSError errorWithDomain:CWVTranslationErrorDomain | 93 error = [NSError errorWithDomain:CWVTranslationErrorDomain |
93 code:errorType | 94 code:errorType |
94 userInfo:nil]; | 95 userInfo:nil]; |
95 } | 96 } |
96 | 97 |
97 switch (step) { | 98 switch (step) { |
98 case translate::TRANSLATE_STEP_BEFORE_TRANSLATE: { | 99 case translate::TRANSLATE_STEP_BEFORE_TRANSLATE: { |
| 100 NSArray* supportedLanguages = [self.supportedLanguagesByCode.allValues |
| 101 sortedArrayUsingComparator:^NSComparisonResult( |
| 102 CWVTranslationLanguage* languageA, |
| 103 CWVTranslationLanguage* languageB) { |
| 104 return [languageA.languageName compare:languageB.languageName]; |
| 105 }]; |
99 CWVLanguageDetectionResult* languageDetectionResult = | 106 CWVLanguageDetectionResult* languageDetectionResult = |
100 [[CWVLanguageDetectionResult alloc] | 107 [[CWVLanguageDetectionResult alloc] |
101 initWithPageLanguage:source | 108 initWithPageLanguage:source |
102 suggestedTargetLanguage:target | 109 suggestedTargetLanguage:target |
103 supportedLanguages:[self supportedLanguages]]; | 110 supportedLanguages:supportedLanguages]; |
104 if ([_delegate respondsToSelector:@selector | 111 if ([_delegate respondsToSelector:@selector |
105 (translationController:didFinishLanguageDetectionWithResult | 112 (translationController:didFinishLanguageDetectionWithResult |
106 :error:)]) { | 113 :error:)]) { |
107 [_delegate translationController:self | 114 [_delegate translationController:self |
108 didFinishLanguageDetectionWithResult:languageDetectionResult | 115 didFinishLanguageDetectionWithResult:languageDetectionResult |
109 error:error]; | 116 error:error]; |
110 } | 117 } |
111 break; | 118 break; |
112 } | 119 } |
113 case translate::TRANSLATE_STEP_TRANSLATING: | 120 case translate::TRANSLATE_STEP_TRANSLATING: |
(...skipping 19 matching lines...) Expand all Loading... |
133 break; | 140 break; |
134 case translate::TRANSLATE_STEP_TRANSLATE_ERROR: | 141 case translate::TRANSLATE_STEP_TRANSLATE_ERROR: |
135 break; | 142 break; |
136 } | 143 } |
137 } | 144 } |
138 | 145 |
139 #pragma mark - Public Methods | 146 #pragma mark - Public Methods |
140 | 147 |
141 - (void)translatePageFromLanguage:(CWVTranslationLanguage*)sourceLanguage | 148 - (void)translatePageFromLanguage:(CWVTranslationLanguage*)sourceLanguage |
142 toLanguage:(CWVTranslationLanguage*)targetLanguage { | 149 toLanguage:(CWVTranslationLanguage*)targetLanguage { |
143 // TODO(706289): Use the passed parameters. | 150 std::string sourceLanguageCode = |
144 _translateUIDelegate->Translate(); | 151 base::SysNSStringToUTF8(sourceLanguage.languageCode); |
| 152 std::string targetLanguageCode = |
| 153 base::SysNSStringToUTF8(targetLanguage.languageCode); |
| 154 _translateClient->translate_manager()->TranslatePage( |
| 155 sourceLanguageCode, targetLanguageCode, false); |
145 } | 156 } |
146 | 157 |
147 - (void)revertTranslation { | 158 - (void)revertTranslation { |
148 _translateUIDelegate->RevertTranslation(); | 159 _translateClient->translate_manager()->RevertTranslation(); |
| 160 } |
| 161 |
| 162 - (void)setTranslationPolicy:(CWVTranslationPolicy*)policy |
| 163 forPageLanguage:(CWVTranslationLanguage*)pageLanguage { |
| 164 std::string languageCode = base::SysNSStringToUTF8(pageLanguage.languageCode); |
| 165 switch (policy.type) { |
| 166 case CWVTranslationPolicyAsk: { |
| 167 _translatePrefs->UnblockLanguage(languageCode); |
| 168 _translatePrefs->RemoveLanguagePairFromWhitelist(languageCode, |
| 169 std::string()); |
| 170 break; |
| 171 } |
| 172 case CWVTranslationPolicyNever: { |
| 173 _translatePrefs->BlockLanguage(languageCode); |
| 174 break; |
| 175 } |
| 176 case CWVTranslationPolicyAuto: { |
| 177 _translatePrefs->UnblockLanguage(languageCode); |
| 178 _translatePrefs->WhitelistLanguagePair( |
| 179 languageCode, base::SysNSStringToUTF8(policy.language.languageCode)); |
| 180 break; |
| 181 } |
| 182 } |
| 183 } |
| 184 |
| 185 - (CWVTranslationPolicy*)translationPolicyForPageLanguage: |
| 186 (CWVTranslationLanguage*)pageLanguage { |
| 187 std::string languageCode = base::SysNSStringToUTF8(pageLanguage.languageCode); |
| 188 bool isLanguageBlocked = _translatePrefs->IsBlockedLanguage(languageCode); |
| 189 if (isLanguageBlocked) { |
| 190 return [CWVTranslationPolicy translationPolicyNever]; |
| 191 } |
| 192 |
| 193 std::string autoTargetLanguageCode; |
| 194 if (!_translatePrefs->ShouldAutoTranslate(languageCode, |
| 195 &autoTargetLanguageCode)) { |
| 196 return [CWVTranslationPolicy translationPolicyAsk]; |
| 197 } |
| 198 |
| 199 CWVTranslationLanguage* targetLanguage = |
| 200 [self languageWithCode:autoTargetLanguageCode]; |
| 201 return [CWVTranslationPolicy |
| 202 translationPolicyAutoTranslateToLanguage:targetLanguage]; |
| 203 } |
| 204 |
| 205 - (void)setTranslationPolicy:(CWVTranslationPolicy*)policy |
| 206 forPageHost:(NSString*)pageHost { |
| 207 DCHECK(pageHost.length); |
| 208 switch (policy.type) { |
| 209 case CWVTranslationPolicyAsk: { |
| 210 _translatePrefs->RemoveSiteFromBlacklist( |
| 211 base::SysNSStringToUTF8(pageHost)); |
| 212 break; |
| 213 } |
| 214 case CWVTranslationPolicyNever: { |
| 215 _translatePrefs->BlacklistSite(base::SysNSStringToUTF8(pageHost)); |
| 216 break; |
| 217 } |
| 218 case CWVTranslationPolicyAuto: { |
| 219 // TODO(crbug.com/706289): Support auto translation policies for websites. |
| 220 NOTREACHED(); |
| 221 break; |
| 222 } |
| 223 } |
| 224 } |
| 225 |
| 226 - (CWVTranslationPolicy*)translationPolicyForPageHost:(NSString*)pageHost { |
| 227 // TODO(crbug.com/706289): Return translationPolicyAuto when implemented. |
| 228 bool isSiteBlackListed = |
| 229 _translatePrefs->IsSiteBlacklisted(base::SysNSStringToUTF8(pageHost)); |
| 230 if (isSiteBlackListed) { |
| 231 return [CWVTranslationPolicy translationPolicyNever]; |
| 232 } |
| 233 return [CWVTranslationPolicy translationPolicyAsk]; |
149 } | 234 } |
150 | 235 |
151 #pragma mark - Private Methods | 236 #pragma mark - Private Methods |
152 | 237 |
153 - (NSArray<CWVTranslationLanguage*>*)supportedLanguages { | 238 - (NSDictionary<NSString*, CWVTranslationLanguage*>*)supportedLanguagesByCode { |
154 NSMutableArray* supportedLanguages = [NSMutableArray array]; | 239 if (!_supportedLanguagesByCode) { |
155 for (size_t i = 0; i < _translateUIDelegate->GetNumberOfLanguages(); i++) { | 240 NSMutableDictionary<NSString*, CWVTranslationLanguage*>* |
156 CWVTranslationLanguage* language = [self languageAtIndex:i]; | 241 supportedLanguagesByCode = [NSMutableDictionary dictionary]; |
157 [supportedLanguages addObject:language]; | 242 std::vector<std::string> languageCodes; |
| 243 translate::TranslateDownloadManager::GetSupportedLanguages(&languageCodes); |
| 244 std::string locale = translate::TranslateDownloadManager::GetInstance() |
| 245 ->application_locale(); |
| 246 for (const std::string& languageCode : languageCodes) { |
| 247 base::string16 languageName = |
| 248 l10n_util::GetDisplayNameForLocale(languageCode, locale, true); |
| 249 CWVTranslationLanguage* language = |
| 250 [[CWVTranslationLanguage alloc] initWithLanguageCode:languageCode |
| 251 languageName:languageName]; |
| 252 |
| 253 supportedLanguagesByCode[language.languageCode] = language; |
| 254 } |
| 255 |
| 256 _supportedLanguagesByCode = [supportedLanguagesByCode copy]; |
158 } | 257 } |
159 | 258 return _supportedLanguagesByCode; |
160 return [supportedLanguages copy]; | |
161 } | 259 } |
162 | 260 |
163 - (CWVTranslationLanguage*)languageAtIndex:(size_t)index { | 261 - (CWVTranslationLanguage*)languageWithCode:(const std::string&)languageCode { |
164 std::string languageCode = _translateUIDelegate->GetLanguageCodeAt(index); | 262 NSString* languageCodeString = base::SysUTF8ToNSString(languageCode); |
165 base::string16 languageName = _translateUIDelegate->GetLanguageNameAt(index); | 263 return self.supportedLanguagesByCode[languageCodeString]; |
166 return [[CWVTranslationLanguage alloc] initWithLanguageCode:languageCode | |
167 languageName:languageName]; | |
168 } | 264 } |
169 | 265 |
170 @end | 266 @end |
OLD | NEW |