| 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 |