| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "chrome/renderer/password_autocomplete_manager.h" | 5 #include "chrome/renderer/autofill/password_autofill_manager.h" |
| 6 | 6 |
| 7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
| 8 #include "base/scoped_ptr.h" | 8 #include "base/scoped_ptr.h" |
| 9 #include "chrome/common/autofill_messages.h" | 9 #include "chrome/common/autofill_messages.h" |
| 10 #include "chrome/renderer/render_view.h" | 10 #include "chrome/renderer/render_view.h" |
| 11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
| 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" | 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" |
| 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h" | 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h" |
| 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
| 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" | 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
| 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h" | 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h" |
| 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
| 19 #include "ui/base/keycodes/keyboard_codes.h" | 19 #include "ui/base/keycodes/keyboard_codes.h" |
| 20 #include "webkit/glue/form_field.h" | 20 #include "webkit/glue/form_field.h" |
| 21 #include "webkit/glue/password_form.h" | 21 #include "webkit/glue/password_form.h" |
| 22 #include "webkit/glue/password_form_dom_manager.h" | 22 #include "webkit/glue/password_form_dom_manager.h" |
| 23 | 23 |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 // The size above which we stop triggering autocomplete. | 26 // The size above which we stop triggering autocomplete. |
| 27 static const size_t kMaximumTextSizeForAutocomplete = 1000; | 27 static const size_t kMaximumTextSizeForAutocomplete = 1000; |
| 28 | 28 |
| 29 // Maps element names to the actual elements to simplify form filling. | 29 // Maps element names to the actual elements to simplify form filling. |
| 30 typedef std::map<string16, WebKit::WebInputElement> | 30 typedef std::map<string16, WebKit::WebInputElement> |
| 31 FormInputElementMap; | 31 FormInputElementMap; |
| 32 | 32 |
| 33 // Utility struct for form lookup and autocomplete. When we parse the DOM to | 33 // Utility struct for form lookup and autofill. When we parse the DOM to look up |
| 34 // lookup a form, in addition to action and origin URL's we have to compare all | 34 // a form, in addition to action and origin URL's we have to compare all |
| 35 // necessary form elements. To avoid having to look these up again when we want | 35 // necessary form elements. To avoid having to look these up again when we want |
| 36 // to fill the form, the FindFormElements function stores the pointers | 36 // to fill the form, the FindFormElements function stores the pointers |
| 37 // in a FormElements* result, referenced to ensure they are safe to use. | 37 // in a FormElements* result, referenced to ensure they are safe to use. |
| 38 struct FormElements { | 38 struct FormElements { |
| 39 WebKit::WebFormElement form_element; | 39 WebKit::WebFormElement form_element; |
| 40 FormInputElementMap input_elements; | 40 FormInputElementMap input_elements; |
| 41 }; | 41 }; |
| 42 | 42 |
| 43 typedef std::vector<FormElements*> FormElementsList; | 43 typedef std::vector<FormElements*> FormElementsList; |
| 44 | 44 |
| 45 // Helper to search the given form element for the specified input elements | 45 // Helper to search the given form element for the specified input elements |
| 46 // in |data|, and add results to |result|. | 46 // in |data|, and add results to |result|. |
| 47 static bool FindFormInputElements(WebKit::WebFormElement* fe, | 47 static bool FindFormInputElements(WebKit::WebFormElement* fe, |
| 48 const webkit_glue::FormData& data, | 48 const webkit_glue::FormData& data, |
| 49 FormElements* result) { | 49 FormElements* result) { |
| 50 // Loop through the list of elements we need to find on the form in order to | 50 // Loop through the list of elements we need to find on the form in order to |
| 51 // autocomplete it. If we don't find any one of them, abort processing this | 51 // autofill it. If we don't find any one of them, abort processing this |
| 52 // form; it can't be the right one. | 52 // form; it can't be the right one. |
| 53 for (size_t j = 0; j < data.fields.size(); j++) { | 53 for (size_t j = 0; j < data.fields.size(); j++) { |
| 54 WebKit::WebVector<WebKit::WebNode> temp_elements; | 54 WebKit::WebVector<WebKit::WebNode> temp_elements; |
| 55 fe->getNamedElements(data.fields[j].name(), temp_elements); | 55 fe->getNamedElements(data.fields[j].name(), temp_elements); |
| 56 | 56 |
| 57 // Match the first input element, if any. | 57 // Match the first input element, if any. |
| 58 // |getNamedElements| may return non-input elements where the names match, | 58 // |getNamedElements| may return non-input elements where the names match, |
| 59 // so the results are filtered for input elements. | 59 // so the results are filtered for input elements. |
| 60 // If more than one match is made, then we have ambiguity (due to misuse | 60 // If more than one match is made, then we have ambiguity (due to misuse |
| 61 // of "name" attribute) so is it considered not found. | 61 // of "name" attribute) so is it considered not found. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 bool DoUsernamesMatch(const string16& username1, | 178 bool DoUsernamesMatch(const string16& username1, |
| 179 const string16& username2, | 179 const string16& username2, |
| 180 bool exact_match) { | 180 bool exact_match) { |
| 181 if (exact_match) | 181 if (exact_match) |
| 182 return username1 == username2; | 182 return username1 == username2; |
| 183 return StartsWith(username1, username2, true); | 183 return StartsWith(username1, username2, true); |
| 184 } | 184 } |
| 185 | 185 |
| 186 } // namespace | 186 } // namespace |
| 187 | 187 |
| 188 namespace autofill { |
| 189 |
| 188 //////////////////////////////////////////////////////////////////////////////// | 190 //////////////////////////////////////////////////////////////////////////////// |
| 189 // PasswordAutocompleteManager, public: | 191 // PasswordAutoFillManager, public: |
| 190 | 192 |
| 191 PasswordAutocompleteManager::PasswordAutocompleteManager( | 193 PasswordAutoFillManager::PasswordAutoFillManager( |
| 192 RenderView* render_view) | 194 RenderView* render_view) |
| 193 : RenderViewObserver(render_view), | 195 : RenderViewObserver(render_view), |
| 194 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { | 196 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
| 195 } | 197 } |
| 196 | 198 |
| 197 PasswordAutocompleteManager::~PasswordAutocompleteManager() { | 199 PasswordAutoFillManager::~PasswordAutoFillManager() { |
| 198 } | 200 } |
| 199 | 201 |
| 200 bool PasswordAutocompleteManager::TextFieldDidEndEditing( | 202 bool PasswordAutoFillManager::TextFieldDidEndEditing( |
| 201 const WebKit::WebInputElement& element) { | 203 const WebKit::WebInputElement& element) { |
| 202 LoginToPasswordInfoMap::const_iterator iter = | 204 LoginToPasswordInfoMap::const_iterator iter = |
| 203 login_to_password_info_.find(element); | 205 login_to_password_info_.find(element); |
| 204 if (iter == login_to_password_info_.end()) | 206 if (iter == login_to_password_info_.end()) |
| 205 return false; | 207 return false; |
| 206 | 208 |
| 207 const webkit_glue::PasswordFormFillData& fill_data = | 209 const webkit_glue::PasswordFormFillData& fill_data = |
| 208 iter->second.fill_data; | 210 iter->second.fill_data; |
| 209 | 211 |
| 210 // If wait_for_username is false, we should have filled when the text changed. | 212 // If wait_for_username is false, we should have filled when the text changed. |
| 211 if (!fill_data.wait_for_username) | 213 if (!fill_data.wait_for_username) |
| 212 return false; | 214 return false; |
| 213 | 215 |
| 214 WebKit::WebInputElement password = iter->second.password_field; | 216 WebKit::WebInputElement password = iter->second.password_field; |
| 215 if (!IsElementEditable(password)) | 217 if (!IsElementEditable(password)) |
| 216 return false; | 218 return false; |
| 217 | 219 |
| 218 WebKit::WebInputElement username = element; // We need a non-const. | 220 WebKit::WebInputElement username = element; // We need a non-const. |
| 219 | 221 |
| 220 // Do not set selection when ending an editing session, otherwise it can | 222 // Do not set selection when ending an editing session, otherwise it can |
| 221 // mess with focus. | 223 // mess with focus. |
| 222 FillUserNameAndPassword(&username, &password, fill_data, true, false); | 224 FillUserNameAndPassword(&username, &password, fill_data, true, false); |
| 223 return true; | 225 return true; |
| 224 } | 226 } |
| 225 | 227 |
| 226 bool PasswordAutocompleteManager::TextDidChangeInTextField( | 228 bool PasswordAutoFillManager::TextDidChangeInTextField( |
| 227 const WebKit::WebInputElement& element) { | 229 const WebKit::WebInputElement& element) { |
| 228 LoginToPasswordInfoMap::const_iterator iter = | 230 LoginToPasswordInfoMap::const_iterator iter = |
| 229 login_to_password_info_.find(element); | 231 login_to_password_info_.find(element); |
| 230 if (iter == login_to_password_info_.end()) | 232 if (iter == login_to_password_info_.end()) |
| 231 return false; | 233 return false; |
| 232 | 234 |
| 233 // The input text is being changed, so any autocompleted password is now | 235 // The input text is being changed, so any autofilled password is now |
| 234 // outdated. | 236 // outdated. |
| 235 WebKit::WebInputElement username = element; // We need a non-const. | 237 WebKit::WebInputElement username = element; // We need a non-const. |
| 236 WebKit::WebInputElement password = iter->second.password_field; | 238 WebKit::WebInputElement password = iter->second.password_field; |
| 237 SetElementAutofilled(&username, false); | 239 SetElementAutofilled(&username, false); |
| 238 if (password.isAutofilled()) { | 240 if (password.isAutofilled()) { |
| 239 password.setValue(string16()); | 241 password.setValue(string16()); |
| 240 SetElementAutofilled(&password, false); | 242 SetElementAutofilled(&password, false); |
| 241 } | 243 } |
| 242 | 244 |
| 243 // If wait_for_username is true we will fill when the username loses focus. | 245 // If wait_for_username is true we will fill when the username loses focus. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 255 // no further processing is required. | 257 // no further processing is required. |
| 256 if (iter->second.backspace_pressed_last) { | 258 if (iter->second.backspace_pressed_last) { |
| 257 ShowSuggestionPopup(iter->second.fill_data, username); | 259 ShowSuggestionPopup(iter->second.fill_data, username); |
| 258 return true; | 260 return true; |
| 259 } | 261 } |
| 260 | 262 |
| 261 WebKit::WebString name = element.nameForAutofill(); | 263 WebKit::WebString name = element.nameForAutofill(); |
| 262 if (name.isEmpty()) | 264 if (name.isEmpty()) |
| 263 return false; // If the field has no name, then we won't have values. | 265 return false; // If the field has no name, then we won't have values. |
| 264 | 266 |
| 265 // Don't attempt to autocomplete with values that are too large. | 267 // Don't attempt to autofill with values that are too large. |
| 266 if (element.value().length() > kMaximumTextSizeForAutocomplete) | 268 if (element.value().length() > kMaximumTextSizeForAutocomplete) |
| 267 return false; | 269 return false; |
| 268 | 270 |
| 269 // We post a task for doing the autocomplete as the caret position is not set | 271 // We post a task for doing the autocomplete as the caret position is not set |
| 270 // properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976) and | 272 // properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976) and |
| 271 // we need it to determine whether or not to trigger autocomplete. | 273 // we need it to determine whether or not to trigger autocomplete. |
| 272 MessageLoop::current()->PostTask(FROM_HERE, method_factory_.NewRunnableMethod( | 274 MessageLoop::current()->PostTask(FROM_HERE, method_factory_.NewRunnableMethod( |
| 273 &PasswordAutocompleteManager::PerformInlineAutocomplete, | 275 &PasswordAutoFillManager::PerformInlineAutocomplete, |
| 274 element, password, iter->second.fill_data)); | 276 element, password, iter->second.fill_data)); |
| 275 return true; | 277 return true; |
| 276 } | 278 } |
| 277 | 279 |
| 278 bool PasswordAutocompleteManager::TextFieldHandlingKeyDown( | 280 bool PasswordAutoFillManager::TextFieldHandlingKeyDown( |
| 279 const WebKit::WebInputElement& element, | 281 const WebKit::WebInputElement& element, |
| 280 const WebKit::WebKeyboardEvent& event) { | 282 const WebKit::WebKeyboardEvent& event) { |
| 281 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(element); | 283 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(element); |
| 282 if (iter == login_to_password_info_.end()) | 284 if (iter == login_to_password_info_.end()) |
| 283 return false; | 285 return false; |
| 284 | 286 |
| 285 int win_key_code = event.windowsKeyCode; | 287 int win_key_code = event.windowsKeyCode; |
| 286 iter->second.backspace_pressed_last = | 288 iter->second.backspace_pressed_last = |
| 287 (win_key_code == ui::VKEY_BACK || win_key_code == ui::VKEY_DELETE); | 289 (win_key_code == ui::VKEY_BACK || win_key_code == ui::VKEY_DELETE); |
| 288 return true; | 290 return true; |
| 289 } | 291 } |
| 290 | 292 |
| 291 bool PasswordAutocompleteManager::DidSelectAutoFillSuggestion( | 293 bool PasswordAutoFillManager::DidSelectAutoFillSuggestion( |
| 292 const WebKit::WebNode& node, | 294 const WebKit::WebNode& node, |
| 293 const WebKit::WebString& value) { | 295 const WebKit::WebString& value) { |
| 294 if (!node.isElementNode()) | 296 if (!node.isElementNode()) |
| 295 return false; | 297 return false; |
| 296 | 298 |
| 297 WebKit::WebElement element(static_cast<const WebKit::WebElement&>(node)); | 299 WebKit::WebElement element(static_cast<const WebKit::WebElement&>(node)); |
| 298 if (!element.hasTagName("input")) | 300 if (!element.hasTagName("input")) |
| 299 return false; | 301 return false; |
| 300 | 302 |
| 301 WebKit::WebInputElement user_input = element.to<WebKit::WebInputElement>(); | 303 WebKit::WebInputElement user_input = element.to<WebKit::WebInputElement>(); |
| 302 LoginToPasswordInfoMap::iterator iter = | 304 LoginToPasswordInfoMap::iterator iter = |
| 303 login_to_password_info_.find(user_input); | 305 login_to_password_info_.find(user_input); |
| 304 if (iter == login_to_password_info_.end()) | 306 if (iter == login_to_password_info_.end()) |
| 305 return false; | 307 return false; |
| 306 | 308 |
| 307 // Set the incoming |value| in the text field and |FillUserNameAndPassword| | 309 // Set the incoming |value| in the text field and |FillUserNameAndPassword| |
| 308 // will do the rest. | 310 // will do the rest. |
| 309 user_input.setValue(value); | 311 user_input.setValue(value); |
| 310 const webkit_glue::PasswordFormFillData& fill_data = iter->second.fill_data; | 312 const webkit_glue::PasswordFormFillData& fill_data = iter->second.fill_data; |
| 311 WebKit::WebInputElement password = iter->second.password_field; | 313 WebKit::WebInputElement password = iter->second.password_field; |
| 312 return FillUserNameAndPassword(&user_input, &password, fill_data, true, true); | 314 return FillUserNameAndPassword(&user_input, &password, fill_data, true, true); |
| 313 } | 315 } |
| 314 | 316 |
| 315 void PasswordAutocompleteManager::SendPasswordForms(WebKit::WebFrame* frame, | 317 void PasswordAutoFillManager::SendPasswordForms(WebKit::WebFrame* frame, |
| 316 bool only_visible) { | 318 bool only_visible) { |
| 317 // Make sure that this security origin is allowed to use password manager. | 319 // Make sure that this security origin is allowed to use password manager. |
| 318 WebKit::WebSecurityOrigin security_origin = frame->securityOrigin(); | 320 WebKit::WebSecurityOrigin security_origin = frame->securityOrigin(); |
| 319 if (!security_origin.canAccessPasswordManager()) | 321 if (!security_origin.canAccessPasswordManager()) |
| 320 return; | 322 return; |
| 321 | 323 |
| 322 WebKit::WebVector<WebKit::WebFormElement> forms; | 324 WebKit::WebVector<WebKit::WebFormElement> forms; |
| 323 frame->forms(forms); | 325 frame->forms(forms); |
| 324 | 326 |
| 325 std::vector<webkit_glue::PasswordForm> password_forms; | 327 std::vector<webkit_glue::PasswordForm> password_forms; |
| 326 for (size_t i = 0; i < forms.size(); ++i) { | 328 for (size_t i = 0; i < forms.size(); ++i) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 341 return; | 343 return; |
| 342 | 344 |
| 343 if (only_visible) { | 345 if (only_visible) { |
| 344 Send(new AutoFillHostMsg_PasswordFormsVisible( | 346 Send(new AutoFillHostMsg_PasswordFormsVisible( |
| 345 routing_id(), password_forms)); | 347 routing_id(), password_forms)); |
| 346 } else { | 348 } else { |
| 347 Send(new AutoFillHostMsg_PasswordFormsFound(routing_id(), password_forms)); | 349 Send(new AutoFillHostMsg_PasswordFormsFound(routing_id(), password_forms)); |
| 348 } | 350 } |
| 349 } | 351 } |
| 350 | 352 |
| 351 bool PasswordAutocompleteManager::OnMessageReceived( | 353 bool PasswordAutoFillManager::OnMessageReceived(const IPC::Message& message) { |
| 352 const IPC::Message& message) { | |
| 353 bool handled = true; | 354 bool handled = true; |
| 354 IPC_BEGIN_MESSAGE_MAP(PasswordAutocompleteManager, message) | 355 IPC_BEGIN_MESSAGE_MAP(PasswordAutoFillManager, message) |
| 355 IPC_MESSAGE_HANDLER(AutoFillMsg_FillPasswordForm, OnFillPasswordForm) | 356 IPC_MESSAGE_HANDLER(AutoFillMsg_FillPasswordForm, OnFillPasswordForm) |
| 356 IPC_MESSAGE_UNHANDLED(handled = false) | 357 IPC_MESSAGE_UNHANDLED(handled = false) |
| 357 IPC_END_MESSAGE_MAP() | 358 IPC_END_MESSAGE_MAP() |
| 358 return handled; | 359 return handled; |
| 359 } | 360 } |
| 360 | 361 |
| 361 void PasswordAutocompleteManager::DidFinishDocumentLoad( | 362 void PasswordAutoFillManager::DidFinishDocumentLoad(WebKit::WebFrame* frame) { |
| 362 WebKit::WebFrame* frame) { | |
| 363 SendPasswordForms(frame, false); | 363 SendPasswordForms(frame, false); |
| 364 } | 364 } |
| 365 | 365 |
| 366 void PasswordAutocompleteManager::DidFinishLoad(WebKit::WebFrame* frame) { | 366 void PasswordAutoFillManager::DidFinishLoad(WebKit::WebFrame* frame) { |
| 367 SendPasswordForms(frame, true); | 367 SendPasswordForms(frame, true); |
| 368 } | 368 } |
| 369 | 369 |
| 370 void PasswordAutocompleteManager::FrameDetached(WebKit::WebFrame* frame) { | 370 void PasswordAutoFillManager::FrameDetached(WebKit::WebFrame* frame) { |
| 371 FrameClosing(frame); | 371 FrameClosing(frame); |
| 372 } | 372 } |
| 373 | 373 |
| 374 void PasswordAutocompleteManager::FrameWillClose(WebKit::WebFrame* frame) { | 374 void PasswordAutoFillManager::FrameWillClose(WebKit::WebFrame* frame) { |
| 375 FrameClosing(frame); | 375 FrameClosing(frame); |
| 376 } | 376 } |
| 377 | 377 |
| 378 | 378 |
| 379 //////////////////////////////////////////////////////////////////////////////// | 379 //////////////////////////////////////////////////////////////////////////////// |
| 380 // PageClickListener implementation: | 380 // PageClickListener implementation: |
| 381 | 381 |
| 382 bool PasswordAutocompleteManager::InputElementClicked( | 382 bool PasswordAutoFillManager::InputElementClicked( |
| 383 const WebKit::WebInputElement& element, | 383 const WebKit::WebInputElement& element, |
| 384 bool was_focused, | 384 bool was_focused, |
| 385 bool is_focused) { | 385 bool is_focused) { |
| 386 // TODO(jcivelli): http://crbug.com/51644 Implement behavior. | 386 // TODO(jcivelli): http://crbug.com/51644 Implement behavior. |
| 387 return false; | 387 return false; |
| 388 } | 388 } |
| 389 | 389 |
| 390 void PasswordAutocompleteManager::OnFillPasswordForm( | 390 void PasswordAutoFillManager::OnFillPasswordForm( |
| 391 const webkit_glue::PasswordFormFillData& form_data) { | 391 const webkit_glue::PasswordFormFillData& form_data) { |
| 392 FormElementsList forms; | 392 FormElementsList forms; |
| 393 // We own the FormElements* in forms. | 393 // We own the FormElements* in forms. |
| 394 FindFormElements(render_view()->webview(), form_data.basic_data, &forms); | 394 FindFormElements(render_view()->webview(), form_data.basic_data, &forms); |
| 395 FormElementsList::iterator iter; | 395 FormElementsList::iterator iter; |
| 396 for (iter = forms.begin(); iter != forms.end(); ++iter) { | 396 for (iter = forms.begin(); iter != forms.end(); ++iter) { |
| 397 scoped_ptr<FormElements> form_elements(*iter); | 397 scoped_ptr<FormElements> form_elements(*iter); |
| 398 | 398 |
| 399 // If wait_for_username is true, we don't want to initially fill the form | 399 // If wait_for_username is true, we don't want to initially fill the form |
| 400 // until the user types in a valid username. | 400 // until the user types in a valid username. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 414 DCHECK(login_to_password_info_.find(username_element) == | 414 DCHECK(login_to_password_info_.find(username_element) == |
| 415 login_to_password_info_.end()); | 415 login_to_password_info_.end()); |
| 416 PasswordInfo password_info; | 416 PasswordInfo password_info; |
| 417 password_info.fill_data = form_data; | 417 password_info.fill_data = form_data; |
| 418 password_info.password_field = password_element; | 418 password_info.password_field = password_element; |
| 419 login_to_password_info_[username_element] = password_info; | 419 login_to_password_info_[username_element] = password_info; |
| 420 } | 420 } |
| 421 } | 421 } |
| 422 | 422 |
| 423 //////////////////////////////////////////////////////////////////////////////// | 423 //////////////////////////////////////////////////////////////////////////////// |
| 424 // PasswordAutocompleteManager, private: | 424 // PasswordAutoFillManager, private: |
| 425 | 425 |
| 426 void PasswordAutocompleteManager::GetSuggestions( | 426 void PasswordAutoFillManager::GetSuggestions( |
| 427 const webkit_glue::PasswordFormFillData& fill_data, | 427 const webkit_glue::PasswordFormFillData& fill_data, |
| 428 const string16& input, | 428 const string16& input, |
| 429 std::vector<string16>* suggestions) { | 429 std::vector<string16>* suggestions) { |
| 430 if (StartsWith(fill_data.basic_data.fields[0].value(), input, false)) | 430 if (StartsWith(fill_data.basic_data.fields[0].value(), input, false)) |
| 431 suggestions->push_back(fill_data.basic_data.fields[0].value()); | 431 suggestions->push_back(fill_data.basic_data.fields[0].value()); |
| 432 | 432 |
| 433 webkit_glue::PasswordFormFillData::LoginCollection::const_iterator iter; | 433 webkit_glue::PasswordFormFillData::LoginCollection::const_iterator iter; |
| 434 for (iter = fill_data.additional_logins.begin(); | 434 for (iter = fill_data.additional_logins.begin(); |
| 435 iter != fill_data.additional_logins.end(); ++iter) { | 435 iter != fill_data.additional_logins.end(); ++iter) { |
| 436 if (StartsWith(iter->first, input, false)) | 436 if (StartsWith(iter->first, input, false)) |
| 437 suggestions->push_back(iter->first); | 437 suggestions->push_back(iter->first); |
| 438 } | 438 } |
| 439 } | 439 } |
| 440 | 440 |
| 441 bool PasswordAutocompleteManager::ShowSuggestionPopup( | 441 bool PasswordAutoFillManager::ShowSuggestionPopup( |
| 442 const webkit_glue::PasswordFormFillData& fill_data, | 442 const webkit_glue::PasswordFormFillData& fill_data, |
| 443 const WebKit::WebInputElement& user_input) { | 443 const WebKit::WebInputElement& user_input) { |
| 444 WebKit::WebView* webview = user_input.document().frame()->view(); | 444 WebKit::WebView* webview = user_input.document().frame()->view(); |
| 445 if (!webview) | 445 if (!webview) |
| 446 return false; | 446 return false; |
| 447 | 447 |
| 448 std::vector<string16> suggestions; | 448 std::vector<string16> suggestions; |
| 449 GetSuggestions(fill_data, user_input.value(), &suggestions); | 449 GetSuggestions(fill_data, user_input.value(), &suggestions); |
| 450 if (suggestions.empty()) { | 450 if (suggestions.empty()) { |
| 451 webview->hidePopups(); | 451 webview->hidePopups(); |
| 452 return false; | 452 return false; |
| 453 } | 453 } |
| 454 | 454 |
| 455 std::vector<string16> labels(suggestions.size()); | 455 std::vector<string16> labels(suggestions.size()); |
| 456 std::vector<string16> icons(suggestions.size()); | 456 std::vector<string16> icons(suggestions.size()); |
| 457 std::vector<int> ids(suggestions.size(), 0); | 457 std::vector<int> ids(suggestions.size(), 0); |
| 458 webview->applyAutoFillSuggestions(user_input, suggestions, labels, icons, ids, | 458 webview->applyAutoFillSuggestions(user_input, suggestions, labels, icons, ids, |
| 459 -1); | 459 -1); |
| 460 return true; | 460 return true; |
| 461 } | 461 } |
| 462 | 462 |
| 463 bool PasswordAutocompleteManager::FillUserNameAndPassword( | 463 bool PasswordAutoFillManager::FillUserNameAndPassword( |
| 464 WebKit::WebInputElement* username_element, | 464 WebKit::WebInputElement* username_element, |
| 465 WebKit::WebInputElement* password_element, | 465 WebKit::WebInputElement* password_element, |
| 466 const webkit_glue::PasswordFormFillData& fill_data, | 466 const webkit_glue::PasswordFormFillData& fill_data, |
| 467 bool exact_username_match, | 467 bool exact_username_match, |
| 468 bool set_selection) { | 468 bool set_selection) { |
| 469 string16 current_username = username_element->value(); | 469 string16 current_username = username_element->value(); |
| 470 // username and password will contain the match found if any. | 470 // username and password will contain the match found if any. |
| 471 string16 username; | 471 string16 username; |
| 472 string16 password; | 472 string16 password; |
| 473 | 473 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 500 username.length()); | 500 username.length()); |
| 501 } | 501 } |
| 502 | 502 |
| 503 SetElementAutofilled(username_element, true); | 503 SetElementAutofilled(username_element, true); |
| 504 if (IsElementEditable(*password_element)) | 504 if (IsElementEditable(*password_element)) |
| 505 password_element->setValue(password); | 505 password_element->setValue(password); |
| 506 SetElementAutofilled(password_element, true); | 506 SetElementAutofilled(password_element, true); |
| 507 return true; | 507 return true; |
| 508 } | 508 } |
| 509 | 509 |
| 510 void PasswordAutocompleteManager::PerformInlineAutocomplete( | 510 void PasswordAutoFillManager::PerformInlineAutocomplete( |
| 511 const WebKit::WebInputElement& username_input, | 511 const WebKit::WebInputElement& username_input, |
| 512 const WebKit::WebInputElement& password_input, | 512 const WebKit::WebInputElement& password_input, |
| 513 const webkit_glue::PasswordFormFillData& fill_data) { | 513 const webkit_glue::PasswordFormFillData& fill_data) { |
| 514 DCHECK(!fill_data.wait_for_username); | 514 DCHECK(!fill_data.wait_for_username); |
| 515 | 515 |
| 516 // We need non-const versions of the username and password inputs. | 516 // We need non-const versions of the username and password inputs. |
| 517 WebKit::WebInputElement username = username_input; | 517 WebKit::WebInputElement username = username_input; |
| 518 WebKit::WebInputElement password = password_input; | 518 WebKit::WebInputElement password = password_input; |
| 519 | 519 |
| 520 // Don't inline autocomplete if the caret is not at the end. | 520 // Don't inline autocomplete if the caret is not at the end. |
| 521 // TODO(jcivelli): is there a better way to test the caret location? | 521 // TODO(jcivelli): is there a better way to test the caret location? |
| 522 if (username.selectionStart() != username.selectionEnd() || | 522 if (username.selectionStart() != username.selectionEnd() || |
| 523 username.selectionEnd() != static_cast<int>(username.value().length())) { | 523 username.selectionEnd() != static_cast<int>(username.value().length())) { |
| 524 return; | 524 return; |
| 525 } | 525 } |
| 526 | 526 |
| 527 // Show the popup with the list of available usernames. | 527 // Show the popup with the list of available usernames. |
| 528 ShowSuggestionPopup(fill_data, username); | 528 ShowSuggestionPopup(fill_data, username); |
| 529 | 529 |
| 530 // Fill the user and password field with the most relevant match. | 530 // Fill the user and password field with the most relevant match. |
| 531 FillUserNameAndPassword(&username, &password, fill_data, false, true); | 531 FillUserNameAndPassword(&username, &password, fill_data, false, true); |
| 532 } | 532 } |
| 533 | 533 |
| 534 void PasswordAutocompleteManager::FrameClosing(const WebKit::WebFrame* frame) { | 534 void PasswordAutoFillManager::FrameClosing(const WebKit::WebFrame* frame) { |
| 535 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); | 535 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); |
| 536 iter != login_to_password_info_.end();) { | 536 iter != login_to_password_info_.end();) { |
| 537 if (iter->first.document().frame() == frame) | 537 if (iter->first.document().frame() == frame) |
| 538 login_to_password_info_.erase(iter++); | 538 login_to_password_info_.erase(iter++); |
| 539 else | 539 else |
| 540 ++iter; | 540 ++iter; |
| 541 } | 541 } |
| 542 } | 542 } |
| 543 |
| 544 } // namespace autofill |
| OLD | NEW |