OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/chrome/browser/autofill/form_suggestion_controller.h" | 5 #import "ios/chrome/browser/autofill/form_suggestion_controller.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/ios/ios_util.h" | 9 #include "base/ios/ios_util.h" |
10 #include "base/ios/weak_nsobject.h" | |
11 #include "base/mac/foundation_util.h" | 10 #include "base/mac/foundation_util.h" |
12 #include "base/mac/scoped_block.h" | 11 #include "base/mac/scoped_block.h" |
13 #include "base/mac/scoped_nsobject.h" | |
14 #include "base/strings/sys_string_conversions.h" | 12 #include "base/strings/sys_string_conversions.h" |
15 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
16 #include "components/autofill/core/browser/autofill_popup_delegate.h" | 14 #include "components/autofill/core/browser/autofill_popup_delegate.h" |
17 #import "components/autofill/ios/browser/form_suggestion.h" | 15 #import "components/autofill/ios/browser/form_suggestion.h" |
18 #import "ios/chrome/browser/autofill/form_input_accessory_view_controller.h" | 16 #import "ios/chrome/browser/autofill/form_input_accessory_view_controller.h" |
19 #import "ios/chrome/browser/autofill/form_suggestion_provider.h" | 17 #import "ios/chrome/browser/autofill/form_suggestion_provider.h" |
20 #import "ios/chrome/browser/autofill/form_suggestion_view.h" | 18 #import "ios/chrome/browser/autofill/form_suggestion_view.h" |
21 #import "ios/chrome/browser/passwords/password_generation_utils.h" | 19 #import "ios/chrome/browser/passwords/password_generation_utils.h" |
22 #include "ios/chrome/browser/ui/ui_util.h" | 20 #include "ios/chrome/browser/ui/ui_util.h" |
23 #import "ios/web/public/url_scheme_util.h" | 21 #import "ios/web/public/url_scheme_util.h" |
24 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" | 22 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" |
25 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h" | 23 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h" |
26 #import "ios/web/public/web_state/web_state.h" | 24 #import "ios/web/public/web_state/web_state.h" |
27 | 25 |
| 26 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 27 #error "This file requires ARC support." |
| 28 #endif |
| 29 |
28 namespace { | 30 namespace { |
29 | 31 |
30 // Struct that describes suggestion state. | 32 // Struct that describes suggestion state. |
31 struct AutofillSuggestionState { | 33 struct AutofillSuggestionState { |
32 AutofillSuggestionState(const std::string& form_name, | 34 AutofillSuggestionState(const std::string& form_name, |
33 const std::string& field_name, | 35 const std::string& field_name, |
34 const std::string& typed_value); | 36 const std::string& typed_value); |
35 // The name of the form for autofill. | 37 // The name of the form for autofill. |
36 std::string form_name; | 38 std::string form_name; |
37 // The name of the field for autofill. | 39 // The name of the field for autofill. |
38 std::string field_name; | 40 std::string field_name; |
39 // The user-typed value in the field. | 41 // The user-typed value in the field. |
40 std::string typed_value; | 42 std::string typed_value; |
41 // The suggestions for the form field. An array of |FormSuggestion|. | 43 // The suggestions for the form field. An array of |FormSuggestion|. |
42 base::scoped_nsobject<NSArray> suggestions; | 44 NSArray* suggestions; |
43 }; | 45 }; |
44 | 46 |
45 AutofillSuggestionState::AutofillSuggestionState(const std::string& form_name, | 47 AutofillSuggestionState::AutofillSuggestionState(const std::string& form_name, |
46 const std::string& field_name, | 48 const std::string& field_name, |
47 const std::string& typed_value) | 49 const std::string& typed_value) |
48 : form_name(form_name), field_name(field_name), typed_value(typed_value) { | 50 : form_name(form_name), field_name(field_name), typed_value(typed_value) { |
49 } | 51 } |
50 | 52 |
51 } // namespace | 53 } // namespace |
52 | 54 |
53 @interface FormSuggestionController () <FormInputAccessoryViewProvider> { | 55 @interface FormSuggestionController () <FormInputAccessoryViewProvider> { |
54 // Form navigation delegate. | 56 // Form navigation delegate. |
55 base::WeakNSProtocol<id<FormInputAccessoryViewDelegate>> _delegate; | 57 __weak id<FormInputAccessoryViewDelegate> _delegate; |
56 | 58 |
57 // Callback to update the accessory view. | 59 // Callback to update the accessory view. |
58 base::mac::ScopedBlock<AccessoryViewReadyCompletion> | 60 AccessoryViewReadyCompletion accessoryViewUpdateBlock_; |
59 accessoryViewUpdateBlock_; | |
60 | 61 |
61 // Autofill suggestion state. | 62 // Autofill suggestion state. |
62 std::unique_ptr<AutofillSuggestionState> _suggestionState; | 63 std::unique_ptr<AutofillSuggestionState> _suggestionState; |
63 | 64 |
64 // Providers for suggestions, sorted according to the order in which | 65 // Providers for suggestions, sorted according to the order in which |
65 // they should be asked for suggestions, with highest priority in front. | 66 // they should be asked for suggestions, with highest priority in front. |
66 base::scoped_nsobject<NSArray> _suggestionProviders; | 67 NSArray* _suggestionProviders; |
67 | 68 |
68 // Access to WebView from the CRWWebController. | 69 // Access to WebView from the CRWWebController. |
69 base::scoped_nsprotocol<id<CRWWebViewProxy>> _webViewProxy; | 70 id<CRWWebViewProxy> _webViewProxy; |
70 } | 71 } |
71 | 72 |
72 // Returns an autoreleased input accessory view that shows |suggestions|. | 73 // Returns an autoreleased input accessory view that shows |suggestions|. |
73 - (UIView*)suggestionViewWithSuggestions:(NSArray*)suggestions; | 74 - (UIView*)suggestionViewWithSuggestions:(NSArray*)suggestions; |
74 | 75 |
75 // Updates keyboard for |suggestionState|. | 76 // Updates keyboard for |suggestionState|. |
76 - (void)updateKeyboard:(AutofillSuggestionState*)suggestionState; | 77 - (void)updateKeyboard:(AutofillSuggestionState*)suggestionState; |
77 | 78 |
78 // Updates keyboard with |suggestions|. | 79 // Updates keyboard with |suggestions|. |
79 - (void)updateKeyboardWithSuggestions:(NSArray*)suggestions; | 80 - (void)updateKeyboardWithSuggestions:(NSArray*)suggestions; |
80 | 81 |
81 // Clears state in between page loads. | 82 // Clears state in between page loads. |
82 - (void)resetSuggestionState; | 83 - (void)resetSuggestionState; |
83 | 84 |
84 @end | 85 @end |
85 | 86 |
86 @implementation FormSuggestionController { | 87 @implementation FormSuggestionController { |
87 // Bridge to observe the web state from Objective-C. | 88 // Bridge to observe the web state from Objective-C. |
88 std::unique_ptr<web::WebStateObserverBridge> _webStateObserverBridge; | 89 std::unique_ptr<web::WebStateObserverBridge> _webStateObserverBridge; |
89 | 90 |
90 // Manager for FormSuggestion JavaScripts. | 91 // Manager for FormSuggestion JavaScripts. |
91 base::scoped_nsobject<JsSuggestionManager> _jsSuggestionManager; | 92 JsSuggestionManager* _jsSuggestionManager; |
92 | 93 |
93 // The provider for the current set of suggestions. | 94 // The provider for the current set of suggestions. |
94 __unsafe_unretained id<FormSuggestionProvider> _provider; // weak | 95 __unsafe_unretained id<FormSuggestionProvider> _provider; // weak |
95 } | 96 } |
96 | 97 |
97 - (instancetype)initWithWebState:(web::WebState*)webState | 98 - (instancetype)initWithWebState:(web::WebState*)webState |
98 providers:(NSArray*)providers | 99 providers:(NSArray*)providers |
99 JsSuggestionManager:(JsSuggestionManager*)jsSuggestionManager { | 100 JsSuggestionManager:(JsSuggestionManager*)jsSuggestionManager { |
100 self = [super init]; | 101 self = [super init]; |
101 if (self) { | 102 if (self) { |
102 _webStateObserverBridge.reset( | 103 _webStateObserverBridge.reset( |
103 new web::WebStateObserverBridge(webState, self)); | 104 new web::WebStateObserverBridge(webState, self)); |
104 _webViewProxy.reset([webState->GetWebViewProxy() retain]); | 105 _webViewProxy = webState->GetWebViewProxy(); |
105 _jsSuggestionManager.reset([jsSuggestionManager retain]); | 106 _jsSuggestionManager = jsSuggestionManager; |
106 _suggestionProviders.reset([providers copy]); | 107 _suggestionProviders = [providers copy]; |
107 } | 108 } |
108 return self; | 109 return self; |
109 } | 110 } |
110 | 111 |
111 - (instancetype)initWithWebState:(web::WebState*)webState | 112 - (instancetype)initWithWebState:(web::WebState*)webState |
112 providers:(NSArray*)providers { | 113 providers:(NSArray*)providers { |
113 JsSuggestionManager* jsSuggestionManager = | 114 JsSuggestionManager* jsSuggestionManager = |
114 base::mac::ObjCCast<JsSuggestionManager>( | 115 base::mac::ObjCCast<JsSuggestionManager>( |
115 [webState->GetJSInjectionReceiver() | 116 [webState->GetJSInjectionReceiver() |
116 instanceOfClass:[JsSuggestionManager class]]); | 117 instanceOfClass:[JsSuggestionManager class]]); |
(...skipping 29 matching lines...) Expand all Loading... |
146 if (trustLevel != web::URLVerificationTrustLevel::kAbsolute) { | 147 if (trustLevel != web::URLVerificationTrustLevel::kAbsolute) { |
147 DLOG(WARNING) << "Page load not handled on untrusted page"; | 148 DLOG(WARNING) << "Page load not handled on untrusted page"; |
148 return; | 149 return; |
149 } | 150 } |
150 | 151 |
151 if (web::UrlHasWebScheme(pageURL) && webState->ContentIsHTML()) | 152 if (web::UrlHasWebScheme(pageURL) && webState->ContentIsHTML()) |
152 [_jsSuggestionManager inject]; | 153 [_jsSuggestionManager inject]; |
153 } | 154 } |
154 | 155 |
155 - (void)setWebViewProxy:(id<CRWWebViewProxy>)webViewProxy { | 156 - (void)setWebViewProxy:(id<CRWWebViewProxy>)webViewProxy { |
156 _webViewProxy.reset([webViewProxy retain]); | 157 _webViewProxy = webViewProxy; |
157 } | 158 } |
158 | 159 |
159 - (void)retrieveSuggestionsForFormNamed:(const std::string&)formName | 160 - (void)retrieveSuggestionsForFormNamed:(const std::string&)formName |
160 fieldName:(const std::string&)fieldName | 161 fieldName:(const std::string&)fieldName |
161 type:(const std::string&)type | 162 type:(const std::string&)type |
162 webState:(web::WebState*)webState { | 163 webState:(web::WebState*)webState { |
163 base::WeakNSObject<FormSuggestionController> weakSelf(self); | 164 __weak FormSuggestionController* weakSelf = self; |
164 base::scoped_nsobject<NSString> strongFormName( | 165 NSString* strongFormName = [base::SysUTF8ToNSString(formName) copy]; |
165 [base::SysUTF8ToNSString(formName) copy]); | 166 NSString* strongFieldName = [base::SysUTF8ToNSString(fieldName) copy]; |
166 base::scoped_nsobject<NSString> strongFieldName( | 167 NSString* strongType = [base::SysUTF8ToNSString(type) copy]; |
167 [base::SysUTF8ToNSString(fieldName) copy]); | 168 NSString* strongValue = |
168 base::scoped_nsobject<NSString> strongType( | 169 [base::SysUTF8ToNSString(_suggestionState.get()->typed_value) copy]; |
169 [base::SysUTF8ToNSString(type) copy]); | |
170 base::scoped_nsobject<NSString> strongValue( | |
171 [base::SysUTF8ToNSString(_suggestionState.get()->typed_value) copy]); | |
172 | 170 |
173 // Build a block for each provider that will invoke its completion with YES | 171 // Build a block for each provider that will invoke its completion with YES |
174 // if the provider can provide suggestions for the specified form/field/type | 172 // if the provider can provide suggestions for the specified form/field/type |
175 // and NO otherwise. | 173 // and NO otherwise. |
176 base::scoped_nsobject<NSMutableArray> findProviderBlocks( | 174 NSMutableArray* findProviderBlocks = [[NSMutableArray alloc] init]; |
177 [[NSMutableArray alloc] init]); | |
178 for (NSUInteger i = 0; i < [_suggestionProviders count]; i++) { | 175 for (NSUInteger i = 0; i < [_suggestionProviders count]; i++) { |
179 base::mac::ScopedBlock<passwords::PipelineBlock> block( | 176 passwords::PipelineBlock block = |
180 ^(void (^completion)(BOOL success)) { | 177 ^(void (^completion)(BOOL success)) { |
181 // Access all the providers through |self| to guarantee that both | 178 // Access all the providers through |self| to guarantee that both |
182 // |self| and all the providers exist when the block is executed. | 179 // |self| and all the providers exist when the block is executed. |
183 // |_suggestionProviders| is immutable, so the subscripting is | 180 // |_suggestionProviders| is immutable, so the subscripting is |
184 // always valid. | 181 // always valid. |
185 base::scoped_nsobject<FormSuggestionController> strongSelf( | 182 FormSuggestionController* strongSelf = weakSelf; |
186 [weakSelf retain]); | |
187 if (!strongSelf) | 183 if (!strongSelf) |
188 return; | 184 return; |
189 id<FormSuggestionProvider> provider = | 185 id<FormSuggestionProvider> provider = |
190 strongSelf.get()->_suggestionProviders[i]; | 186 strongSelf->_suggestionProviders[i]; |
191 [provider checkIfSuggestionsAvailableForForm:strongFormName | 187 [provider checkIfSuggestionsAvailableForForm:strongFormName |
192 field:strongFieldName | 188 field:strongFieldName |
193 type:strongType | 189 type:strongType |
194 typedValue:strongValue | 190 typedValue:strongValue |
195 webState:webState | 191 webState:webState |
196 completionHandler:completion]; | 192 completionHandler:completion]; |
197 }, | 193 }; |
198 base::scoped_policy::RETAIN); | |
199 [findProviderBlocks addObject:block]; | 194 [findProviderBlocks addObject:block]; |
200 } | 195 } |
201 | 196 |
202 // Once the suggestions are retrieved, update the suggestions UI. | 197 // Once the suggestions are retrieved, update the suggestions UI. |
203 SuggestionsReadyCompletion readyCompletion = | 198 SuggestionsReadyCompletion readyCompletion = |
204 ^(NSArray* suggestions, id<FormSuggestionProvider> provider) { | 199 ^(NSArray* suggestions, id<FormSuggestionProvider> provider) { |
205 [weakSelf onSuggestionsReady:suggestions provider:provider]; | 200 [weakSelf onSuggestionsReady:suggestions provider:provider]; |
206 }; | 201 }; |
207 | 202 |
208 // Once a provider is found, use it to retrieve suggestions. | 203 // Once a provider is found, use it to retrieve suggestions. |
209 passwords::PipelineCompletionBlock completion = ^(NSUInteger providerIndex) { | 204 passwords::PipelineCompletionBlock completion = ^(NSUInteger providerIndex) { |
210 if (providerIndex == NSNotFound) { | 205 if (providerIndex == NSNotFound) { |
211 [weakSelf onNoSuggestionsAvailable]; | 206 [weakSelf onNoSuggestionsAvailable]; |
212 return; | 207 return; |
213 } | 208 } |
214 base::scoped_nsobject<FormSuggestionController> strongSelf( | 209 FormSuggestionController* strongSelf = weakSelf; |
215 [weakSelf retain]); | |
216 if (!strongSelf) | 210 if (!strongSelf) |
217 return; | 211 return; |
218 id<FormSuggestionProvider> provider = | 212 id<FormSuggestionProvider> provider = |
219 strongSelf.get()->_suggestionProviders[providerIndex]; | 213 strongSelf->_suggestionProviders[providerIndex]; |
220 [provider retrieveSuggestionsForForm:strongFormName | 214 [provider retrieveSuggestionsForForm:strongFormName |
221 field:strongFieldName | 215 field:strongFieldName |
222 type:strongType | 216 type:strongType |
223 typedValue:strongValue | 217 typedValue:strongValue |
224 webState:webState | 218 webState:webState |
225 completionHandler:readyCompletion]; | 219 completionHandler:readyCompletion]; |
226 }; | 220 }; |
227 | 221 |
228 // Run all the blocks in |findProviderBlocks| until one invokes its | 222 // Run all the blocks in |findProviderBlocks| until one invokes its |
229 // completion with YES. The first one to do so will be passed to | 223 // completion with YES. The first one to do so will be passed to |
230 // |completion|. | 224 // |completion|. |
231 passwords::RunSearchPipeline(findProviderBlocks, completion); | 225 passwords::RunSearchPipeline(findProviderBlocks, completion); |
232 } | 226 } |
233 | 227 |
234 - (void)onSuggestionsReady:(NSArray*)suggestions | 228 - (void)onSuggestionsReady:(NSArray*)suggestions |
235 provider:(id<FormSuggestionProvider>)provider { | 229 provider:(id<FormSuggestionProvider>)provider { |
236 // TODO(ios): crbug.com/249916. If we can also pass in the form/field for | 230 // TODO(ios): crbug.com/249916. If we can also pass in the form/field for |
237 // which |suggestions| are, we should check here if |suggestions| are for | 231 // which |suggestions| are, we should check here if |suggestions| are for |
238 // the current active element. If not, reset |_suggestionState|. | 232 // the current active element. If not, reset |_suggestionState|. |
239 if (!_suggestionState) { | 233 if (!_suggestionState) { |
240 // The suggestion state was reset in between the call to Autofill API (e.g. | 234 // The suggestion state was reset in between the call to Autofill API (e.g. |
241 // OnQueryFormFieldAutofill) and this method being called back. Results are | 235 // OnQueryFormFieldAutofill) and this method being called back. Results are |
242 // therefore no longer relevant. | 236 // therefore no longer relevant. |
243 return; | 237 return; |
244 } | 238 } |
245 | 239 |
246 _provider = provider; | 240 _provider = provider; |
247 _suggestionState->suggestions.reset([suggestions copy]); | 241 _suggestionState->suggestions = [suggestions copy]; |
248 [self updateKeyboard:_suggestionState.get()]; | 242 [self updateKeyboard:_suggestionState.get()]; |
249 } | 243 } |
250 | 244 |
251 - (void)resetSuggestionState { | 245 - (void)resetSuggestionState { |
252 _provider = nil; | 246 _provider = nil; |
253 _suggestionState.reset(); | 247 _suggestionState.reset(); |
254 } | 248 } |
255 | 249 |
256 - (void)clearSuggestions { | 250 - (void)clearSuggestions { |
257 // Note that other parts of the suggestionsState are not reset. | 251 // Note that other parts of the suggestionsState are not reset. |
258 if (!_suggestionState.get()) | 252 if (!_suggestionState.get()) |
259 return; | 253 return; |
260 _suggestionState->suggestions.reset([[NSArray alloc] init]); | 254 _suggestionState->suggestions = [[NSArray alloc] init]; |
261 [self updateKeyboard:_suggestionState.get()]; | 255 [self updateKeyboard:_suggestionState.get()]; |
262 } | 256 } |
263 | 257 |
264 - (void)updateKeyboard:(AutofillSuggestionState*)suggestionState { | 258 - (void)updateKeyboard:(AutofillSuggestionState*)suggestionState { |
265 if (!suggestionState) { | 259 if (!suggestionState) { |
266 if (accessoryViewUpdateBlock_) | 260 if (accessoryViewUpdateBlock_) |
267 accessoryViewUpdateBlock_.get()(nil, self); | 261 accessoryViewUpdateBlock_(nil, self); |
268 } else { | 262 } else { |
269 [self updateKeyboardWithSuggestions:suggestionState->suggestions]; | 263 [self updateKeyboardWithSuggestions:suggestionState->suggestions]; |
270 } | 264 } |
271 } | 265 } |
272 | 266 |
273 - (void)updateKeyboardWithSuggestions:(NSArray*)suggestions { | 267 - (void)updateKeyboardWithSuggestions:(NSArray*)suggestions { |
274 if (accessoryViewUpdateBlock_) { | 268 if (accessoryViewUpdateBlock_) { |
275 accessoryViewUpdateBlock_.get()( | 269 accessoryViewUpdateBlock_([self suggestionViewWithSuggestions:suggestions], |
276 [self suggestionViewWithSuggestions:suggestions], self); | 270 self); |
277 } | 271 } |
278 } | 272 } |
279 | 273 |
280 - (UIView*)suggestionViewWithSuggestions:(NSArray*)suggestions { | 274 - (UIView*)suggestionViewWithSuggestions:(NSArray*)suggestions { |
281 CGRect frame = [_webViewProxy keyboardAccessory].frame; | 275 CGRect frame = [_webViewProxy keyboardAccessory].frame; |
282 // Force the desired height on iPad where the height of the | 276 // Force the desired height on iPad where the height of the |
283 // inputAccessoryView is 0. | 277 // inputAccessoryView is 0. |
284 if (IsIPadIdiom()) { | 278 if (IsIPadIdiom()) { |
285 frame.size.height = autofill::kInputAccessoryHeight; | 279 frame.size.height = autofill::kInputAccessoryHeight; |
286 } | 280 } |
287 base::scoped_nsobject<FormSuggestionView> view([[FormSuggestionView alloc] | 281 FormSuggestionView* view = |
288 initWithFrame:frame | 282 [[FormSuggestionView alloc] initWithFrame:frame |
289 client:self | 283 client:self |
290 suggestions:suggestions]); | 284 suggestions:suggestions]; |
291 return view.autorelease(); | 285 return view; |
292 } | 286 } |
293 | 287 |
294 - (void)didSelectSuggestion:(FormSuggestion*)suggestion { | 288 - (void)didSelectSuggestion:(FormSuggestion*)suggestion { |
295 if (!_suggestionState) | 289 if (!_suggestionState) |
296 return; | 290 return; |
297 | 291 |
298 // Send the suggestion to the provider. Upon completion advance the cursor | 292 // Send the suggestion to the provider. Upon completion advance the cursor |
299 // for single-field Autofill, or close the keyboard for full-form Autofill. | 293 // for single-field Autofill, or close the keyboard for full-form Autofill. |
300 base::WeakNSObject<FormSuggestionController> weakSelf(self); | 294 __weak FormSuggestionController* weakSelf = self; |
301 [_provider | 295 [_provider |
302 didSelectSuggestion:suggestion | 296 didSelectSuggestion:suggestion |
303 forField:base::SysUTF8ToNSString(_suggestionState->field_name) | 297 forField:base::SysUTF8ToNSString(_suggestionState->field_name) |
304 form:base::SysUTF8ToNSString(_suggestionState->form_name) | 298 form:base::SysUTF8ToNSString(_suggestionState->form_name) |
305 completionHandler:^{ | 299 completionHandler:^{ |
306 [[weakSelf accessoryViewDelegate] closeKeyboardWithoutButtonPress]; | 300 [[weakSelf accessoryViewDelegate] closeKeyboardWithoutButtonPress]; |
307 }]; | 301 }]; |
308 _provider = nil; | 302 _provider = nil; |
309 } | 303 } |
310 | 304 |
311 - (id<FormInputAccessoryViewProvider>)accessoryViewProvider { | 305 - (id<FormInputAccessoryViewProvider>)accessoryViewProvider { |
312 return self; | 306 return self; |
313 } | 307 } |
314 | 308 |
315 #pragma mark FormInputAccessoryViewProvider | 309 #pragma mark FormInputAccessoryViewProvider |
316 | 310 |
317 - (id<FormInputAccessoryViewDelegate>)accessoryViewDelegate { | 311 - (id<FormInputAccessoryViewDelegate>)accessoryViewDelegate { |
318 return _delegate.get(); | 312 return _delegate; |
319 } | 313 } |
320 | 314 |
321 - (void)setAccessoryViewDelegate:(id<FormInputAccessoryViewDelegate>)delegate { | 315 - (void)setAccessoryViewDelegate:(id<FormInputAccessoryViewDelegate>)delegate { |
322 _delegate.reset(delegate); | 316 _delegate = delegate; |
323 } | 317 } |
324 | 318 |
325 - (void) | 319 - (void) |
326 checkIfAccessoryViewIsAvailableForFormNamed:(const std::string&)formName | 320 checkIfAccessoryViewIsAvailableForFormNamed:(const std::string&)formName |
327 fieldName:(const std::string&)fieldName | 321 fieldName:(const std::string&)fieldName |
328 webState:(web::WebState*)webState | 322 webState:(web::WebState*)webState |
329 completionHandler: | 323 completionHandler: |
330 (AccessoryViewAvailableCompletion) | 324 (AccessoryViewAvailableCompletion) |
331 completionHandler { | 325 completionHandler { |
332 [self processPage:webState]; | 326 [self processPage:webState]; |
333 completionHandler(YES); | 327 completionHandler(YES); |
334 } | 328 } |
335 | 329 |
336 - (void)retrieveAccessoryViewForFormNamed:(const std::string&)formName | 330 - (void)retrieveAccessoryViewForFormNamed:(const std::string&)formName |
337 fieldName:(const std::string&)fieldName | 331 fieldName:(const std::string&)fieldName |
338 value:(const std::string&)value | 332 value:(const std::string&)value |
339 type:(const std::string&)type | 333 type:(const std::string&)type |
340 webState:(web::WebState*)webState | 334 webState:(web::WebState*)webState |
341 accessoryViewUpdateBlock: | 335 accessoryViewUpdateBlock: |
342 (AccessoryViewReadyCompletion)accessoryViewUpdateBlock { | 336 (AccessoryViewReadyCompletion)accessoryViewUpdateBlock { |
343 _suggestionState.reset( | 337 _suggestionState.reset( |
344 new AutofillSuggestionState(formName, fieldName, value)); | 338 new AutofillSuggestionState(formName, fieldName, value)); |
345 accessoryViewUpdateBlock([self suggestionViewWithSuggestions:@[]], self); | 339 accessoryViewUpdateBlock([self suggestionViewWithSuggestions:@[]], self); |
346 accessoryViewUpdateBlock_.reset([accessoryViewUpdateBlock copy]); | 340 accessoryViewUpdateBlock_ = [accessoryViewUpdateBlock copy]; |
347 [self retrieveSuggestionsForFormNamed:formName | 341 [self retrieveSuggestionsForFormNamed:formName |
348 fieldName:fieldName | 342 fieldName:fieldName |
349 type:type | 343 type:type |
350 webState:webState]; | 344 webState:webState]; |
351 } | 345 } |
352 | 346 |
353 - (void)inputAccessoryViewControllerDidReset: | 347 - (void)inputAccessoryViewControllerDidReset: |
354 (FormInputAccessoryViewController*)controller { | 348 (FormInputAccessoryViewController*)controller { |
355 accessoryViewUpdateBlock_.reset(); | 349 accessoryViewUpdateBlock_ = nil; |
356 [self resetSuggestionState]; | 350 [self resetSuggestionState]; |
357 } | 351 } |
358 | 352 |
359 - (void)resizeAccessoryView { | 353 - (void)resizeAccessoryView { |
360 [self updateKeyboard:_suggestionState.get()]; | 354 [self updateKeyboard:_suggestionState.get()]; |
361 } | 355 } |
362 | 356 |
363 - (BOOL)getLogKeyboardAccessoryMetrics { | 357 - (BOOL)getLogKeyboardAccessoryMetrics { |
364 return YES; | 358 return YES; |
365 } | 359 } |
366 | 360 |
367 @end | 361 @end |
OLD | NEW |