| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/autofill/content/renderer/password_autofill_agent.h" | 5 #include "components/autofill/content/renderer/password_autofill_agent.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 #include "third_party/WebKit/public/web/WebView.h" | 30 #include "third_party/WebKit/public/web/WebView.h" |
| 31 #include "ui/events/keycodes/keyboard_codes.h" | 31 #include "ui/events/keycodes/keyboard_codes.h" |
| 32 | 32 |
| 33 namespace autofill { | 33 namespace autofill { |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 // The size above which we stop triggering autocomplete. | 36 // The size above which we stop triggering autocomplete. |
| 37 static const size_t kMaximumTextSizeForAutocomplete = 1000; | 37 static const size_t kMaximumTextSizeForAutocomplete = 1000; |
| 38 | 38 |
| 39 // Maps element names to the actual elements to simplify form filling. | 39 // Maps element names to the actual elements to simplify form filling. |
| 40 typedef std::map<base::string16, WebKit::WebInputElement> | 40 typedef std::map<base::string16, blink::WebInputElement> |
| 41 FormInputElementMap; | 41 FormInputElementMap; |
| 42 | 42 |
| 43 // Utility struct for form lookup and autofill. When we parse the DOM to look up | 43 // Utility struct for form lookup and autofill. When we parse the DOM to look up |
| 44 // a form, in addition to action and origin URL's we have to compare all | 44 // a form, in addition to action and origin URL's we have to compare all |
| 45 // necessary form elements. To avoid having to look these up again when we want | 45 // necessary form elements. To avoid having to look these up again when we want |
| 46 // to fill the form, the FindFormElements function stores the pointers | 46 // to fill the form, the FindFormElements function stores the pointers |
| 47 // in a FormElements* result, referenced to ensure they are safe to use. | 47 // in a FormElements* result, referenced to ensure they are safe to use. |
| 48 struct FormElements { | 48 struct FormElements { |
| 49 WebKit::WebFormElement form_element; | 49 blink::WebFormElement form_element; |
| 50 FormInputElementMap input_elements; | 50 FormInputElementMap input_elements; |
| 51 }; | 51 }; |
| 52 | 52 |
| 53 typedef std::vector<FormElements*> FormElementsList; | 53 typedef std::vector<FormElements*> FormElementsList; |
| 54 | 54 |
| 55 // Helper to search the given form element for the specified input elements | 55 // Helper to search the given form element for the specified input elements |
| 56 // in |data|, and add results to |result|. | 56 // in |data|, and add results to |result|. |
| 57 static bool FindFormInputElements(WebKit::WebFormElement* fe, | 57 static bool FindFormInputElements(blink::WebFormElement* fe, |
| 58 const FormData& data, | 58 const FormData& data, |
| 59 FormElements* result) { | 59 FormElements* result) { |
| 60 // Loop through the list of elements we need to find on the form in order to | 60 // Loop through the list of elements we need to find on the form in order to |
| 61 // autofill it. If we don't find any one of them, abort processing this | 61 // autofill it. If we don't find any one of them, abort processing this |
| 62 // form; it can't be the right one. | 62 // form; it can't be the right one. |
| 63 for (size_t j = 0; j < data.fields.size(); j++) { | 63 for (size_t j = 0; j < data.fields.size(); j++) { |
| 64 WebKit::WebVector<WebKit::WebNode> temp_elements; | 64 blink::WebVector<blink::WebNode> temp_elements; |
| 65 fe->getNamedElements(data.fields[j].name, temp_elements); | 65 fe->getNamedElements(data.fields[j].name, temp_elements); |
| 66 | 66 |
| 67 // Match the first input element, if any. | 67 // Match the first input element, if any. |
| 68 // |getNamedElements| may return non-input elements where the names match, | 68 // |getNamedElements| may return non-input elements where the names match, |
| 69 // so the results are filtered for input elements. | 69 // so the results are filtered for input elements. |
| 70 // If more than one match is made, then we have ambiguity (due to misuse | 70 // If more than one match is made, then we have ambiguity (due to misuse |
| 71 // of "name" attribute) so is it considered not found. | 71 // of "name" attribute) so is it considered not found. |
| 72 bool found_input = false; | 72 bool found_input = false; |
| 73 for (size_t i = 0; i < temp_elements.size(); ++i) { | 73 for (size_t i = 0; i < temp_elements.size(); ++i) { |
| 74 if (temp_elements[i].to<WebKit::WebElement>().hasTagName("input")) { | 74 if (temp_elements[i].to<blink::WebElement>().hasTagName("input")) { |
| 75 // Check for a non-unique match. | 75 // Check for a non-unique match. |
| 76 if (found_input) { | 76 if (found_input) { |
| 77 found_input = false; | 77 found_input = false; |
| 78 break; | 78 break; |
| 79 } | 79 } |
| 80 | 80 |
| 81 // Only fill saved passwords into password fields and usernames into | 81 // Only fill saved passwords into password fields and usernames into |
| 82 // text fields. | 82 // text fields. |
| 83 WebKit::WebInputElement input_element = | 83 blink::WebInputElement input_element = |
| 84 temp_elements[i].to<WebKit::WebInputElement>(); | 84 temp_elements[i].to<blink::WebInputElement>(); |
| 85 if (input_element.isPasswordField() != | 85 if (input_element.isPasswordField() != |
| 86 (data.fields[j].form_control_type == "password")) | 86 (data.fields[j].form_control_type == "password")) |
| 87 continue; | 87 continue; |
| 88 | 88 |
| 89 // This element matched, add it to our temporary result. It's possible | 89 // This element matched, add it to our temporary result. It's possible |
| 90 // there are multiple matches, but for purposes of identifying the form | 90 // there are multiple matches, but for purposes of identifying the form |
| 91 // one suffices and if some function needs to deal with multiple | 91 // one suffices and if some function needs to deal with multiple |
| 92 // matching elements it can get at them through the FormElement*. | 92 // matching elements it can get at them through the FormElement*. |
| 93 // Note: This assignment adds a reference to the InputElement. | 93 // Note: This assignment adds a reference to the InputElement. |
| 94 result->input_elements[data.fields[j].name] = input_element; | 94 result->input_elements[data.fields[j].name] = input_element; |
| 95 found_input = true; | 95 found_input = true; |
| 96 } | 96 } |
| 97 } | 97 } |
| 98 | 98 |
| 99 // A required element was not found. This is not the right form. | 99 // A required element was not found. This is not the right form. |
| 100 // Make sure no input elements from a partially matched form in this | 100 // Make sure no input elements from a partially matched form in this |
| 101 // iteration remain in the result set. | 101 // iteration remain in the result set. |
| 102 // Note: clear will remove a reference from each InputElement. | 102 // Note: clear will remove a reference from each InputElement. |
| 103 if (!found_input) { | 103 if (!found_input) { |
| 104 result->input_elements.clear(); | 104 result->input_elements.clear(); |
| 105 return false; | 105 return false; |
| 106 } | 106 } |
| 107 } | 107 } |
| 108 return true; | 108 return true; |
| 109 } | 109 } |
| 110 | 110 |
| 111 // Helper to locate form elements identified by |data|. | 111 // Helper to locate form elements identified by |data|. |
| 112 void FindFormElements(WebKit::WebView* view, | 112 void FindFormElements(blink::WebView* view, |
| 113 const FormData& data, | 113 const FormData& data, |
| 114 FormElementsList* results) { | 114 FormElementsList* results) { |
| 115 DCHECK(view); | 115 DCHECK(view); |
| 116 DCHECK(results); | 116 DCHECK(results); |
| 117 WebKit::WebFrame* main_frame = view->mainFrame(); | 117 blink::WebFrame* main_frame = view->mainFrame(); |
| 118 if (!main_frame) | 118 if (!main_frame) |
| 119 return; | 119 return; |
| 120 | 120 |
| 121 GURL::Replacements rep; | 121 GURL::Replacements rep; |
| 122 rep.ClearQuery(); | 122 rep.ClearQuery(); |
| 123 rep.ClearRef(); | 123 rep.ClearRef(); |
| 124 | 124 |
| 125 // Loop through each frame. | 125 // Loop through each frame. |
| 126 for (WebKit::WebFrame* f = main_frame; f; f = f->traverseNext(false)) { | 126 for (blink::WebFrame* f = main_frame; f; f = f->traverseNext(false)) { |
| 127 WebKit::WebDocument doc = f->document(); | 127 blink::WebDocument doc = f->document(); |
| 128 if (!doc.isHTMLDocument()) | 128 if (!doc.isHTMLDocument()) |
| 129 continue; | 129 continue; |
| 130 | 130 |
| 131 GURL full_origin(doc.url()); | 131 GURL full_origin(doc.url()); |
| 132 if (data.origin != full_origin.ReplaceComponents(rep)) | 132 if (data.origin != full_origin.ReplaceComponents(rep)) |
| 133 continue; | 133 continue; |
| 134 | 134 |
| 135 WebKit::WebVector<WebKit::WebFormElement> forms; | 135 blink::WebVector<blink::WebFormElement> forms; |
| 136 doc.forms(forms); | 136 doc.forms(forms); |
| 137 | 137 |
| 138 for (size_t i = 0; i < forms.size(); ++i) { | 138 for (size_t i = 0; i < forms.size(); ++i) { |
| 139 WebKit::WebFormElement fe = forms[i]; | 139 blink::WebFormElement fe = forms[i]; |
| 140 | 140 |
| 141 GURL full_action(f->document().completeURL(fe.action())); | 141 GURL full_action(f->document().completeURL(fe.action())); |
| 142 if (full_action.is_empty()) { | 142 if (full_action.is_empty()) { |
| 143 // The default action URL is the form's origin. | 143 // The default action URL is the form's origin. |
| 144 full_action = full_origin; | 144 full_action = full_origin; |
| 145 } | 145 } |
| 146 | 146 |
| 147 // Action URL must match. | 147 // Action URL must match. |
| 148 if (data.action != full_action.ReplaceComponents(rep)) | 148 if (data.action != full_action.ReplaceComponents(rep)) |
| 149 continue; | 149 continue; |
| 150 | 150 |
| 151 scoped_ptr<FormElements> curr_elements(new FormElements); | 151 scoped_ptr<FormElements> curr_elements(new FormElements); |
| 152 if (!FindFormInputElements(&fe, data, curr_elements.get())) | 152 if (!FindFormInputElements(&fe, data, curr_elements.get())) |
| 153 continue; | 153 continue; |
| 154 | 154 |
| 155 // We found the right element. | 155 // We found the right element. |
| 156 // Note: this assignment adds a reference to |fe|. | 156 // Note: this assignment adds a reference to |fe|. |
| 157 curr_elements->form_element = fe; | 157 curr_elements->form_element = fe; |
| 158 results->push_back(curr_elements.release()); | 158 results->push_back(curr_elements.release()); |
| 159 } | 159 } |
| 160 } | 160 } |
| 161 } | 161 } |
| 162 | 162 |
| 163 bool IsElementEditable(const WebKit::WebInputElement& element) { | 163 bool IsElementEditable(const blink::WebInputElement& element) { |
| 164 return element.isEnabled() && !element.isReadOnly(); | 164 return element.isEnabled() && !element.isReadOnly(); |
| 165 } | 165 } |
| 166 | 166 |
| 167 void SetElementAutofilled(WebKit::WebInputElement* element, bool autofilled) { | 167 void SetElementAutofilled(blink::WebInputElement* element, bool autofilled) { |
| 168 if (element->isAutofilled() == autofilled) | 168 if (element->isAutofilled() == autofilled) |
| 169 return; | 169 return; |
| 170 element->setAutofilled(autofilled); | 170 element->setAutofilled(autofilled); |
| 171 // Notify any changeEvent listeners. | 171 // Notify any changeEvent listeners. |
| 172 element->dispatchFormControlChangeEvent(); | 172 element->dispatchFormControlChangeEvent(); |
| 173 } | 173 } |
| 174 | 174 |
| 175 bool DoUsernamesMatch(const base::string16& username1, | 175 bool DoUsernamesMatch(const base::string16& username1, |
| 176 const base::string16& username2, | 176 const base::string16& username2, |
| 177 bool exact_match) { | 177 bool exact_match) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 189 : content::RenderViewObserver(render_view), | 189 : content::RenderViewObserver(render_view), |
| 190 usernames_usage_(NOTHING_TO_AUTOFILL), | 190 usernames_usage_(NOTHING_TO_AUTOFILL), |
| 191 web_view_(render_view->GetWebView()), | 191 web_view_(render_view->GetWebView()), |
| 192 weak_ptr_factory_(this) { | 192 weak_ptr_factory_(this) { |
| 193 } | 193 } |
| 194 | 194 |
| 195 PasswordAutofillAgent::~PasswordAutofillAgent() { | 195 PasswordAutofillAgent::~PasswordAutofillAgent() { |
| 196 } | 196 } |
| 197 | 197 |
| 198 bool PasswordAutofillAgent::TextFieldDidEndEditing( | 198 bool PasswordAutofillAgent::TextFieldDidEndEditing( |
| 199 const WebKit::WebInputElement& element) { | 199 const blink::WebInputElement& element) { |
| 200 LoginToPasswordInfoMap::const_iterator iter = | 200 LoginToPasswordInfoMap::const_iterator iter = |
| 201 login_to_password_info_.find(element); | 201 login_to_password_info_.find(element); |
| 202 if (iter == login_to_password_info_.end()) | 202 if (iter == login_to_password_info_.end()) |
| 203 return false; | 203 return false; |
| 204 | 204 |
| 205 const PasswordFormFillData& fill_data = | 205 const PasswordFormFillData& fill_data = |
| 206 iter->second.fill_data; | 206 iter->second.fill_data; |
| 207 | 207 |
| 208 // If wait_for_username is false, we should have filled when the text changed. | 208 // If wait_for_username is false, we should have filled when the text changed. |
| 209 if (!fill_data.wait_for_username) | 209 if (!fill_data.wait_for_username) |
| 210 return false; | 210 return false; |
| 211 | 211 |
| 212 WebKit::WebInputElement password = iter->second.password_field; | 212 blink::WebInputElement password = iter->second.password_field; |
| 213 if (!IsElementEditable(password)) | 213 if (!IsElementEditable(password)) |
| 214 return false; | 214 return false; |
| 215 | 215 |
| 216 WebKit::WebInputElement username = element; // We need a non-const. | 216 blink::WebInputElement username = element; // We need a non-const. |
| 217 | 217 |
| 218 // Do not set selection when ending an editing session, otherwise it can | 218 // Do not set selection when ending an editing session, otherwise it can |
| 219 // mess with focus. | 219 // mess with focus. |
| 220 FillUserNameAndPassword(&username, &password, fill_data, | 220 FillUserNameAndPassword(&username, &password, fill_data, |
| 221 true /* exact_username_match */, | 221 true /* exact_username_match */, |
| 222 false /* set_selection */); | 222 false /* set_selection */); |
| 223 return true; | 223 return true; |
| 224 } | 224 } |
| 225 | 225 |
| 226 bool PasswordAutofillAgent::TextDidChangeInTextField( | 226 bool PasswordAutofillAgent::TextDidChangeInTextField( |
| 227 const WebKit::WebInputElement& element) { | 227 const blink::WebInputElement& element) { |
| 228 LoginToPasswordInfoMap::const_iterator iter = | 228 LoginToPasswordInfoMap::const_iterator iter = |
| 229 login_to_password_info_.find(element); | 229 login_to_password_info_.find(element); |
| 230 if (iter == login_to_password_info_.end()) | 230 if (iter == login_to_password_info_.end()) |
| 231 return false; | 231 return false; |
| 232 | 232 |
| 233 // The input text is being changed, so any autofilled password is now | 233 // The input text is being changed, so any autofilled password is now |
| 234 // outdated. | 234 // outdated. |
| 235 WebKit::WebInputElement username = element; // We need a non-const. | 235 blink::WebInputElement username = element; // We need a non-const. |
| 236 WebKit::WebInputElement password = iter->second.password_field; | 236 blink::WebInputElement password = iter->second.password_field; |
| 237 SetElementAutofilled(&username, false); | 237 SetElementAutofilled(&username, false); |
| 238 if (password.isAutofilled()) { | 238 if (password.isAutofilled()) { |
| 239 password.setValue(base::string16()); | 239 password.setValue(base::string16()); |
| 240 SetElementAutofilled(&password, false); | 240 SetElementAutofilled(&password, false); |
| 241 } | 241 } |
| 242 | 242 |
| 243 // If wait_for_username is true we will fill when the username loses focus. | 243 // If wait_for_username is true we will fill when the username loses focus. |
| 244 if (iter->second.fill_data.wait_for_username) | 244 if (iter->second.fill_data.wait_for_username) |
| 245 return false; | 245 return false; |
| 246 | 246 |
| 247 if (!IsElementEditable(element) || | 247 if (!IsElementEditable(element) || |
| 248 !element.isText() || | 248 !element.isText() || |
| 249 !element.autoComplete()) { | 249 !element.autoComplete()) { |
| 250 return false; | 250 return false; |
| 251 } | 251 } |
| 252 | 252 |
| 253 // Don't inline autocomplete if the user is deleting, that would be confusing. | 253 // Don't inline autocomplete if the user is deleting, that would be confusing. |
| 254 // But refresh the popup. Note, since this is ours, return true to signal | 254 // But refresh the popup. Note, since this is ours, return true to signal |
| 255 // no further processing is required. | 255 // no further processing is required. |
| 256 if (iter->second.backspace_pressed_last) { | 256 if (iter->second.backspace_pressed_last) { |
| 257 ShowSuggestionPopup(iter->second.fill_data, username); | 257 ShowSuggestionPopup(iter->second.fill_data, username); |
| 258 return true; | 258 return true; |
| 259 } | 259 } |
| 260 | 260 |
| 261 WebKit::WebString name = element.nameForAutofill(); | 261 blink::WebString name = element.nameForAutofill(); |
| 262 if (name.isEmpty()) | 262 if (name.isEmpty()) |
| 263 return false; // If the field has no name, then we won't have values. | 263 return false; // If the field has no name, then we won't have values. |
| 264 | 264 |
| 265 // Don't attempt to autofill with values that are too large. | 265 // Don't attempt to autofill with values that are too large. |
| 266 if (element.value().length() > kMaximumTextSizeForAutocomplete) | 266 if (element.value().length() > kMaximumTextSizeForAutocomplete) |
| 267 return false; | 267 return false; |
| 268 | 268 |
| 269 // The caret position should have already been updated. | 269 // The caret position should have already been updated. |
| 270 PerformInlineAutocomplete(element, password, iter->second.fill_data); | 270 PerformInlineAutocomplete(element, password, iter->second.fill_data); |
| 271 return true; | 271 return true; |
| 272 } | 272 } |
| 273 | 273 |
| 274 bool PasswordAutofillAgent::TextFieldHandlingKeyDown( | 274 bool PasswordAutofillAgent::TextFieldHandlingKeyDown( |
| 275 const WebKit::WebInputElement& element, | 275 const blink::WebInputElement& element, |
| 276 const WebKit::WebKeyboardEvent& event) { | 276 const blink::WebKeyboardEvent& event) { |
| 277 // If using the new Autofill UI that lives in the browser, it will handle | 277 // If using the new Autofill UI that lives in the browser, it will handle |
| 278 // keypresses before this function. This is not currently an issue but if | 278 // keypresses before this function. This is not currently an issue but if |
| 279 // the keys handled there or here change, this issue may appear. | 279 // the keys handled there or here change, this issue may appear. |
| 280 | 280 |
| 281 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(element); | 281 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(element); |
| 282 if (iter == login_to_password_info_.end()) | 282 if (iter == login_to_password_info_.end()) |
| 283 return false; | 283 return false; |
| 284 | 284 |
| 285 int win_key_code = event.windowsKeyCode; | 285 int win_key_code = event.windowsKeyCode; |
| 286 iter->second.backspace_pressed_last = | 286 iter->second.backspace_pressed_last = |
| 287 (win_key_code == ui::VKEY_BACK || win_key_code == ui::VKEY_DELETE); | 287 (win_key_code == ui::VKEY_BACK || win_key_code == ui::VKEY_DELETE); |
| 288 return true; | 288 return true; |
| 289 } | 289 } |
| 290 | 290 |
| 291 bool PasswordAutofillAgent::DidAcceptAutofillSuggestion( | 291 bool PasswordAutofillAgent::DidAcceptAutofillSuggestion( |
| 292 const WebKit::WebNode& node, | 292 const blink::WebNode& node, |
| 293 const WebKit::WebString& value) { | 293 const blink::WebString& value) { |
| 294 WebKit::WebInputElement input; | 294 blink::WebInputElement input; |
| 295 PasswordInfo password; | 295 PasswordInfo password; |
| 296 if (!FindLoginInfo(node, &input, &password)) | 296 if (!FindLoginInfo(node, &input, &password)) |
| 297 return false; | 297 return false; |
| 298 | 298 |
| 299 // Set the incoming |value| in the text field and |FillUserNameAndPassword| | 299 // Set the incoming |value| in the text field and |FillUserNameAndPassword| |
| 300 // will do the rest. | 300 // will do the rest. |
| 301 input.setValue(value, true); | 301 input.setValue(value, true); |
| 302 return FillUserNameAndPassword(&input, &password.password_field, | 302 return FillUserNameAndPassword(&input, &password.password_field, |
| 303 password.fill_data, | 303 password.fill_data, |
| 304 true /* exact_username_match */, | 304 true /* exact_username_match */, |
| 305 true /* set_selection */); | 305 true /* set_selection */); |
| 306 } | 306 } |
| 307 | 307 |
| 308 bool PasswordAutofillAgent::DidClearAutofillSelection( | 308 bool PasswordAutofillAgent::DidClearAutofillSelection( |
| 309 const WebKit::WebNode& node) { | 309 const blink::WebNode& node) { |
| 310 WebKit::WebInputElement input; | 310 blink::WebInputElement input; |
| 311 PasswordInfo password; | 311 PasswordInfo password; |
| 312 return FindLoginInfo(node, &input, &password); | 312 return FindLoginInfo(node, &input, &password); |
| 313 } | 313 } |
| 314 | 314 |
| 315 bool PasswordAutofillAgent::ShowSuggestions( | 315 bool PasswordAutofillAgent::ShowSuggestions( |
| 316 const WebKit::WebInputElement& element) { | 316 const blink::WebInputElement& element) { |
| 317 LoginToPasswordInfoMap::const_iterator iter = | 317 LoginToPasswordInfoMap::const_iterator iter = |
| 318 login_to_password_info_.find(element); | 318 login_to_password_info_.find(element); |
| 319 if (iter == login_to_password_info_.end()) | 319 if (iter == login_to_password_info_.end()) |
| 320 return false; | 320 return false; |
| 321 | 321 |
| 322 return ShowSuggestionPopup(iter->second.fill_data, element); | 322 return ShowSuggestionPopup(iter->second.fill_data, element); |
| 323 } | 323 } |
| 324 | 324 |
| 325 bool PasswordAutofillAgent::OriginCanAccessPasswordManager( | 325 bool PasswordAutofillAgent::OriginCanAccessPasswordManager( |
| 326 const WebKit::WebSecurityOrigin& origin) { | 326 const blink::WebSecurityOrigin& origin) { |
| 327 return origin.canAccessPasswordManager(); | 327 return origin.canAccessPasswordManager(); |
| 328 } | 328 } |
| 329 | 329 |
| 330 void PasswordAutofillAgent::OnDynamicFormsSeen(WebKit::WebFrame* frame) { | 330 void PasswordAutofillAgent::OnDynamicFormsSeen(blink::WebFrame* frame) { |
| 331 SendPasswordForms(frame, false /* only_visible */); | 331 SendPasswordForms(frame, false /* only_visible */); |
| 332 } | 332 } |
| 333 | 333 |
| 334 void PasswordAutofillAgent::SendPasswordForms(WebKit::WebFrame* frame, | 334 void PasswordAutofillAgent::SendPasswordForms(blink::WebFrame* frame, |
| 335 bool only_visible) { | 335 bool only_visible) { |
| 336 // Make sure that this security origin is allowed to use password manager. | 336 // Make sure that this security origin is allowed to use password manager. |
| 337 WebKit::WebSecurityOrigin origin = frame->document().securityOrigin(); | 337 blink::WebSecurityOrigin origin = frame->document().securityOrigin(); |
| 338 if (!OriginCanAccessPasswordManager(origin)) | 338 if (!OriginCanAccessPasswordManager(origin)) |
| 339 return; | 339 return; |
| 340 | 340 |
| 341 // Checks whether the webpage is a redirect page or an empty page. | 341 // Checks whether the webpage is a redirect page or an empty page. |
| 342 if (IsWebpageEmpty(frame)) | 342 if (IsWebpageEmpty(frame)) |
| 343 return; | 343 return; |
| 344 | 344 |
| 345 WebKit::WebVector<WebKit::WebFormElement> forms; | 345 blink::WebVector<blink::WebFormElement> forms; |
| 346 frame->document().forms(forms); | 346 frame->document().forms(forms); |
| 347 | 347 |
| 348 std::vector<PasswordForm> password_forms; | 348 std::vector<PasswordForm> password_forms; |
| 349 for (size_t i = 0; i < forms.size(); ++i) { | 349 for (size_t i = 0; i < forms.size(); ++i) { |
| 350 const WebKit::WebFormElement& form = forms[i]; | 350 const blink::WebFormElement& form = forms[i]; |
| 351 | 351 |
| 352 // If requested, ignore non-rendered forms, e.g. those styled with | 352 // If requested, ignore non-rendered forms, e.g. those styled with |
| 353 // display:none. | 353 // display:none. |
| 354 if (only_visible && !IsWebNodeVisible(form)) | 354 if (only_visible && !IsWebNodeVisible(form)) |
| 355 continue; | 355 continue; |
| 356 | 356 |
| 357 scoped_ptr<PasswordForm> password_form(CreatePasswordForm(form)); | 357 scoped_ptr<PasswordForm> password_form(CreatePasswordForm(form)); |
| 358 if (password_form.get()) | 358 if (password_form.get()) |
| 359 password_forms.push_back(*password_form); | 359 password_forms.push_back(*password_form); |
| 360 } | 360 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 384 } | 384 } |
| 385 | 385 |
| 386 void PasswordAutofillAgent::DidStartLoading() { | 386 void PasswordAutofillAgent::DidStartLoading() { |
| 387 if (usernames_usage_ != NOTHING_TO_AUTOFILL) { | 387 if (usernames_usage_ != NOTHING_TO_AUTOFILL) { |
| 388 UMA_HISTOGRAM_ENUMERATION("PasswordManager.OtherPossibleUsernamesUsage", | 388 UMA_HISTOGRAM_ENUMERATION("PasswordManager.OtherPossibleUsernamesUsage", |
| 389 usernames_usage_, OTHER_POSSIBLE_USERNAMES_MAX); | 389 usernames_usage_, OTHER_POSSIBLE_USERNAMES_MAX); |
| 390 usernames_usage_ = NOTHING_TO_AUTOFILL; | 390 usernames_usage_ = NOTHING_TO_AUTOFILL; |
| 391 } | 391 } |
| 392 } | 392 } |
| 393 | 393 |
| 394 void PasswordAutofillAgent::DidFinishDocumentLoad(WebKit::WebFrame* frame) { | 394 void PasswordAutofillAgent::DidFinishDocumentLoad(blink::WebFrame* frame) { |
| 395 // The |frame| contents have been parsed, but not yet rendered. Let the | 395 // The |frame| contents have been parsed, but not yet rendered. Let the |
| 396 // PasswordManager know that forms are loaded, even though we can't yet tell | 396 // PasswordManager know that forms are loaded, even though we can't yet tell |
| 397 // whether they're visible. | 397 // whether they're visible. |
| 398 SendPasswordForms(frame, false); | 398 SendPasswordForms(frame, false); |
| 399 } | 399 } |
| 400 | 400 |
| 401 void PasswordAutofillAgent::DidFinishLoad(WebKit::WebFrame* frame) { | 401 void PasswordAutofillAgent::DidFinishLoad(blink::WebFrame* frame) { |
| 402 // The |frame| contents have been rendered. Let the PasswordManager know | 402 // The |frame| contents have been rendered. Let the PasswordManager know |
| 403 // which of the loaded frames are actually visible to the user. This also | 403 // which of the loaded frames are actually visible to the user. This also |
| 404 // triggers the "Save password?" infobar if the user just submitted a password | 404 // triggers the "Save password?" infobar if the user just submitted a password |
| 405 // form. | 405 // form. |
| 406 SendPasswordForms(frame, true); | 406 SendPasswordForms(frame, true); |
| 407 } | 407 } |
| 408 | 408 |
| 409 void PasswordAutofillAgent::FrameDetached(WebKit::WebFrame* frame) { | 409 void PasswordAutofillAgent::FrameDetached(blink::WebFrame* frame) { |
| 410 FrameClosing(frame); | 410 FrameClosing(frame); |
| 411 } | 411 } |
| 412 | 412 |
| 413 void PasswordAutofillAgent::FrameWillClose(WebKit::WebFrame* frame) { | 413 void PasswordAutofillAgent::FrameWillClose(blink::WebFrame* frame) { |
| 414 FrameClosing(frame); | 414 FrameClosing(frame); |
| 415 } | 415 } |
| 416 | 416 |
| 417 void PasswordAutofillAgent::WillSendSubmitEvent( | 417 void PasswordAutofillAgent::WillSendSubmitEvent( |
| 418 WebKit::WebFrame* frame, | 418 blink::WebFrame* frame, |
| 419 const WebKit::WebFormElement& form) { | 419 const blink::WebFormElement& form) { |
| 420 // Some login forms have onSubmit handlers that put a hash of the password | 420 // Some login forms have onSubmit handlers that put a hash of the password |
| 421 // into a hidden field and then clear the password (http://crbug.com/28910). | 421 // into a hidden field and then clear the password (http://crbug.com/28910). |
| 422 // This method gets called before any of those handlers run, so save away | 422 // This method gets called before any of those handlers run, so save away |
| 423 // a copy of the password in case it gets lost. | 423 // a copy of the password in case it gets lost. |
| 424 provisionally_saved_forms_[frame].reset(CreatePasswordForm(form).release()); | 424 provisionally_saved_forms_[frame].reset(CreatePasswordForm(form).release()); |
| 425 } | 425 } |
| 426 | 426 |
| 427 void PasswordAutofillAgent::WillSubmitForm(WebKit::WebFrame* frame, | 427 void PasswordAutofillAgent::WillSubmitForm(blink::WebFrame* frame, |
| 428 const WebKit::WebFormElement& form) { | 428 const blink::WebFormElement& form) { |
| 429 scoped_ptr<PasswordForm> submitted_form = CreatePasswordForm(form); | 429 scoped_ptr<PasswordForm> submitted_form = CreatePasswordForm(form); |
| 430 | 430 |
| 431 // If there is a provisionally saved password, copy over the previous | 431 // If there is a provisionally saved password, copy over the previous |
| 432 // password value so we get the user's typed password, not the value that | 432 // password value so we get the user's typed password, not the value that |
| 433 // may have been transformed for submit. | 433 // may have been transformed for submit. |
| 434 // TODO(gcasto): Do we need to have this action equality check? Is it trying | 434 // TODO(gcasto): Do we need to have this action equality check? Is it trying |
| 435 // to prevent accidentally copying over passwords from a different form? | 435 // to prevent accidentally copying over passwords from a different form? |
| 436 if (submitted_form) { | 436 if (submitted_form) { |
| 437 if (provisionally_saved_forms_[frame].get() && | 437 if (provisionally_saved_forms_[frame].get() && |
| 438 submitted_form->action == provisionally_saved_forms_[frame]->action) { | 438 submitted_form->action == provisionally_saved_forms_[frame]->action) { |
| 439 submitted_form->password_value = | 439 submitted_form->password_value = |
| 440 provisionally_saved_forms_[frame]->password_value; | 440 provisionally_saved_forms_[frame]->password_value; |
| 441 } | 441 } |
| 442 | 442 |
| 443 // Some observers depend on sending this information now instead of when | 443 // Some observers depend on sending this information now instead of when |
| 444 // the frame starts loading. If there are redirects that cause a new | 444 // the frame starts loading. If there are redirects that cause a new |
| 445 // RenderView to be instantiated (such as redirects to the WebStore) | 445 // RenderView to be instantiated (such as redirects to the WebStore) |
| 446 // we will never get to finish the load. | 446 // we will never get to finish the load. |
| 447 Send(new AutofillHostMsg_PasswordFormSubmitted(routing_id(), | 447 Send(new AutofillHostMsg_PasswordFormSubmitted(routing_id(), |
| 448 *submitted_form)); | 448 *submitted_form)); |
| 449 // Remove reference since we have already submitted this form. | 449 // Remove reference since we have already submitted this form. |
| 450 provisionally_saved_forms_.erase(frame); | 450 provisionally_saved_forms_.erase(frame); |
| 451 } | 451 } |
| 452 } | 452 } |
| 453 | 453 |
| 454 void PasswordAutofillAgent::DidStartProvisionalLoad(WebKit::WebFrame* frame) { | 454 void PasswordAutofillAgent::DidStartProvisionalLoad(blink::WebFrame* frame) { |
| 455 if (!frame->parent()) { | 455 if (!frame->parent()) { |
| 456 // If the navigation is not triggered by a user gesture, e.g. by some ajax | 456 // If the navigation is not triggered by a user gesture, e.g. by some ajax |
| 457 // callback, then inherit the submitted password form from the previous | 457 // callback, then inherit the submitted password form from the previous |
| 458 // state. This fixes the no password save issue for ajax login, tracked in | 458 // state. This fixes the no password save issue for ajax login, tracked in |
| 459 // [http://crbug/43219]. Note that there are still some sites that this | 459 // [http://crbug/43219]. Note that there are still some sites that this |
| 460 // fails for because they use some element other than a submit button to | 460 // fails for because they use some element other than a submit button to |
| 461 // trigger submission (which means WillSendSubmitEvent will not be called). | 461 // trigger submission (which means WillSendSubmitEvent will not be called). |
| 462 if (!WebKit::WebUserGestureIndicator::isProcessingUserGesture() && | 462 if (!blink::WebUserGestureIndicator::isProcessingUserGesture() && |
| 463 provisionally_saved_forms_[frame].get()) { | 463 provisionally_saved_forms_[frame].get()) { |
| 464 Send(new AutofillHostMsg_PasswordFormSubmitted( | 464 Send(new AutofillHostMsg_PasswordFormSubmitted( |
| 465 routing_id(), | 465 routing_id(), |
| 466 *provisionally_saved_forms_[frame])); | 466 *provisionally_saved_forms_[frame])); |
| 467 provisionally_saved_forms_.erase(frame); | 467 provisionally_saved_forms_.erase(frame); |
| 468 } | 468 } |
| 469 // Clear the whole map during main frame navigation. | 469 // Clear the whole map during main frame navigation. |
| 470 provisionally_saved_forms_.clear(); | 470 provisionally_saved_forms_.clear(); |
| 471 } | 471 } |
| 472 } | 472 } |
| 473 | 473 |
| 474 void PasswordAutofillAgent::OnFillPasswordForm( | 474 void PasswordAutofillAgent::OnFillPasswordForm( |
| 475 const PasswordFormFillData& form_data) { | 475 const PasswordFormFillData& form_data) { |
| 476 if (usernames_usage_ == NOTHING_TO_AUTOFILL) { | 476 if (usernames_usage_ == NOTHING_TO_AUTOFILL) { |
| 477 if (form_data.other_possible_usernames.size()) | 477 if (form_data.other_possible_usernames.size()) |
| 478 usernames_usage_ = OTHER_POSSIBLE_USERNAMES_PRESENT; | 478 usernames_usage_ = OTHER_POSSIBLE_USERNAMES_PRESENT; |
| 479 else if (usernames_usage_ == NOTHING_TO_AUTOFILL) | 479 else if (usernames_usage_ == NOTHING_TO_AUTOFILL) |
| 480 usernames_usage_ = OTHER_POSSIBLE_USERNAMES_ABSENT; | 480 usernames_usage_ = OTHER_POSSIBLE_USERNAMES_ABSENT; |
| 481 } | 481 } |
| 482 | 482 |
| 483 FormElementsList forms; | 483 FormElementsList forms; |
| 484 // We own the FormElements* in forms. | 484 // We own the FormElements* in forms. |
| 485 FindFormElements(render_view()->GetWebView(), form_data.basic_data, &forms); | 485 FindFormElements(render_view()->GetWebView(), form_data.basic_data, &forms); |
| 486 FormElementsList::iterator iter; | 486 FormElementsList::iterator iter; |
| 487 for (iter = forms.begin(); iter != forms.end(); ++iter) { | 487 for (iter = forms.begin(); iter != forms.end(); ++iter) { |
| 488 scoped_ptr<FormElements> form_elements(*iter); | 488 scoped_ptr<FormElements> form_elements(*iter); |
| 489 | 489 |
| 490 // Attach autocomplete listener to enable selecting alternate logins. | 490 // Attach autocomplete listener to enable selecting alternate logins. |
| 491 // First, get pointers to username element. | 491 // First, get pointers to username element. |
| 492 WebKit::WebInputElement username_element = | 492 blink::WebInputElement username_element = |
| 493 form_elements->input_elements[form_data.basic_data.fields[0].name]; | 493 form_elements->input_elements[form_data.basic_data.fields[0].name]; |
| 494 | 494 |
| 495 // Get pointer to password element. (We currently only support single | 495 // Get pointer to password element. (We currently only support single |
| 496 // password forms). | 496 // password forms). |
| 497 WebKit::WebInputElement password_element = | 497 blink::WebInputElement password_element = |
| 498 form_elements->input_elements[form_data.basic_data.fields[1].name]; | 498 form_elements->input_elements[form_data.basic_data.fields[1].name]; |
| 499 | 499 |
| 500 // If wait_for_username is true, we don't want to initially fill the form | 500 // If wait_for_username is true, we don't want to initially fill the form |
| 501 // until the user types in a valid username. | 501 // until the user types in a valid username. |
| 502 if (!form_data.wait_for_username) | 502 if (!form_data.wait_for_username) |
| 503 FillFormOnPasswordRecieved(form_data, username_element, password_element); | 503 FillFormOnPasswordRecieved(form_data, username_element, password_element); |
| 504 | 504 |
| 505 // We might have already filled this form if there are two <form> elements | 505 // We might have already filled this form if there are two <form> elements |
| 506 // with identical markup. | 506 // with identical markup. |
| 507 if (login_to_password_info_.find(username_element) != | 507 if (login_to_password_info_.find(username_element) != |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN; | 554 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN; |
| 555 suggestions->push_back(iter->second[i]); | 555 suggestions->push_back(iter->second[i]); |
| 556 realms->push_back(UTF8ToUTF16(iter->first.realm)); | 556 realms->push_back(UTF8ToUTF16(iter->first.realm)); |
| 557 } | 557 } |
| 558 } | 558 } |
| 559 } | 559 } |
| 560 } | 560 } |
| 561 | 561 |
| 562 bool PasswordAutofillAgent::ShowSuggestionPopup( | 562 bool PasswordAutofillAgent::ShowSuggestionPopup( |
| 563 const PasswordFormFillData& fill_data, | 563 const PasswordFormFillData& fill_data, |
| 564 const WebKit::WebInputElement& user_input) { | 564 const blink::WebInputElement& user_input) { |
| 565 WebKit::WebFrame* frame = user_input.document().frame(); | 565 blink::WebFrame* frame = user_input.document().frame(); |
| 566 if (!frame) | 566 if (!frame) |
| 567 return false; | 567 return false; |
| 568 | 568 |
| 569 WebKit::WebView* webview = frame->view(); | 569 blink::WebView* webview = frame->view(); |
| 570 if (!webview) | 570 if (!webview) |
| 571 return false; | 571 return false; |
| 572 | 572 |
| 573 std::vector<base::string16> suggestions; | 573 std::vector<base::string16> suggestions; |
| 574 std::vector<base::string16> realms; | 574 std::vector<base::string16> realms; |
| 575 GetSuggestions(fill_data, user_input.value(), &suggestions, &realms); | 575 GetSuggestions(fill_data, user_input.value(), &suggestions, &realms); |
| 576 DCHECK_EQ(suggestions.size(), realms.size()); | 576 DCHECK_EQ(suggestions.size(), realms.size()); |
| 577 | 577 |
| 578 FormData form; | 578 FormData form; |
| 579 FormFieldData field; | 579 FormFieldData field; |
| 580 FindFormAndFieldForInputElement( | 580 FindFormAndFieldForInputElement( |
| 581 user_input, &form, &field, REQUIRE_NONE); | 581 user_input, &form, &field, REQUIRE_NONE); |
| 582 | 582 |
| 583 WebKit::WebInputElement selected_element = user_input; | 583 blink::WebInputElement selected_element = user_input; |
| 584 gfx::Rect bounding_box(selected_element.boundsInViewportSpace()); | 584 gfx::Rect bounding_box(selected_element.boundsInViewportSpace()); |
| 585 | 585 |
| 586 float scale = web_view_->pageScaleFactor(); | 586 float scale = web_view_->pageScaleFactor(); |
| 587 gfx::RectF bounding_box_scaled(bounding_box.x() * scale, | 587 gfx::RectF bounding_box_scaled(bounding_box.x() * scale, |
| 588 bounding_box.y() * scale, | 588 bounding_box.y() * scale, |
| 589 bounding_box.width() * scale, | 589 bounding_box.width() * scale, |
| 590 bounding_box.height() * scale); | 590 bounding_box.height() * scale); |
| 591 Send(new AutofillHostMsg_ShowPasswordSuggestions(routing_id(), | 591 Send(new AutofillHostMsg_ShowPasswordSuggestions(routing_id(), |
| 592 field, | 592 field, |
| 593 bounding_box_scaled, | 593 bounding_box_scaled, |
| 594 suggestions, | 594 suggestions, |
| 595 realms)); | 595 realms)); |
| 596 return !suggestions.empty(); | 596 return !suggestions.empty(); |
| 597 } | 597 } |
| 598 | 598 |
| 599 void PasswordAutofillAgent::FillFormOnPasswordRecieved( | 599 void PasswordAutofillAgent::FillFormOnPasswordRecieved( |
| 600 const PasswordFormFillData& fill_data, | 600 const PasswordFormFillData& fill_data, |
| 601 WebKit::WebInputElement username_element, | 601 blink::WebInputElement username_element, |
| 602 WebKit::WebInputElement password_element) { | 602 blink::WebInputElement password_element) { |
| 603 if (!username_element.form().autoComplete()) | 603 if (!username_element.form().autoComplete()) |
| 604 return; | 604 return; |
| 605 | 605 |
| 606 // If we can't modify the password, don't try to set the username | 606 // If we can't modify the password, don't try to set the username |
| 607 if (!IsElementEditable(password_element) || !password_element.autoComplete()) | 607 if (!IsElementEditable(password_element) || !password_element.autoComplete()) |
| 608 return; | 608 return; |
| 609 | 609 |
| 610 // Try to set the username to the preferred name, but only if the field | 610 // Try to set the username to the preferred name, but only if the field |
| 611 // can be set and isn't prefilled. | 611 // can be set and isn't prefilled. |
| 612 if (IsElementEditable(username_element) && | 612 if (IsElementEditable(username_element) && |
| 613 username_element.autoComplete() && | 613 username_element.autoComplete() && |
| 614 username_element.value().isEmpty()) { | 614 username_element.value().isEmpty()) { |
| 615 // TODO(tkent): Check maxlength and pattern. | 615 // TODO(tkent): Check maxlength and pattern. |
| 616 username_element.setValue(fill_data.basic_data.fields[0].value); | 616 username_element.setValue(fill_data.basic_data.fields[0].value); |
| 617 } | 617 } |
| 618 | 618 |
| 619 // Fill if we have an exact match for the username. Note that this sets | 619 // Fill if we have an exact match for the username. Note that this sets |
| 620 // username to autofilled. | 620 // username to autofilled. |
| 621 FillUserNameAndPassword(&username_element, &password_element, fill_data, | 621 FillUserNameAndPassword(&username_element, &password_element, fill_data, |
| 622 true /* exact_username_match */, | 622 true /* exact_username_match */, |
| 623 false /* set_selection */); | 623 false /* set_selection */); |
| 624 } | 624 } |
| 625 | 625 |
| 626 bool PasswordAutofillAgent::FillUserNameAndPassword( | 626 bool PasswordAutofillAgent::FillUserNameAndPassword( |
| 627 WebKit::WebInputElement* username_element, | 627 blink::WebInputElement* username_element, |
| 628 WebKit::WebInputElement* password_element, | 628 blink::WebInputElement* password_element, |
| 629 const PasswordFormFillData& fill_data, | 629 const PasswordFormFillData& fill_data, |
| 630 bool exact_username_match, | 630 bool exact_username_match, |
| 631 bool set_selection) { | 631 bool set_selection) { |
| 632 base::string16 current_username = username_element->value(); | 632 base::string16 current_username = username_element->value(); |
| 633 // username and password will contain the match found if any. | 633 // username and password will contain the match found if any. |
| 634 base::string16 username; | 634 base::string16 username; |
| 635 base::string16 password; | 635 base::string16 password; |
| 636 | 636 |
| 637 // Look for any suitable matches to current field text. | 637 // Look for any suitable matches to current field text. |
| 638 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, current_username, | 638 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, current_username, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 // as is, don't autofill a password. | 698 // as is, don't autofill a password. |
| 699 return false; | 699 return false; |
| 700 } | 700 } |
| 701 | 701 |
| 702 password_element->setValue(password); | 702 password_element->setValue(password); |
| 703 SetElementAutofilled(password_element, true); | 703 SetElementAutofilled(password_element, true); |
| 704 return true; | 704 return true; |
| 705 } | 705 } |
| 706 | 706 |
| 707 void PasswordAutofillAgent::PerformInlineAutocomplete( | 707 void PasswordAutofillAgent::PerformInlineAutocomplete( |
| 708 const WebKit::WebInputElement& username_input, | 708 const blink::WebInputElement& username_input, |
| 709 const WebKit::WebInputElement& password_input, | 709 const blink::WebInputElement& password_input, |
| 710 const PasswordFormFillData& fill_data) { | 710 const PasswordFormFillData& fill_data) { |
| 711 DCHECK(!fill_data.wait_for_username); | 711 DCHECK(!fill_data.wait_for_username); |
| 712 | 712 |
| 713 // We need non-const versions of the username and password inputs. | 713 // We need non-const versions of the username and password inputs. |
| 714 WebKit::WebInputElement username = username_input; | 714 blink::WebInputElement username = username_input; |
| 715 WebKit::WebInputElement password = password_input; | 715 blink::WebInputElement password = password_input; |
| 716 | 716 |
| 717 // Don't inline autocomplete if the caret is not at the end. | 717 // Don't inline autocomplete if the caret is not at the end. |
| 718 // TODO(jcivelli): is there a better way to test the caret location? | 718 // TODO(jcivelli): is there a better way to test the caret location? |
| 719 if (username.selectionStart() != username.selectionEnd() || | 719 if (username.selectionStart() != username.selectionEnd() || |
| 720 username.selectionEnd() != static_cast<int>(username.value().length())) { | 720 username.selectionEnd() != static_cast<int>(username.value().length())) { |
| 721 return; | 721 return; |
| 722 } | 722 } |
| 723 | 723 |
| 724 // Show the popup with the list of available usernames. | 724 // Show the popup with the list of available usernames. |
| 725 ShowSuggestionPopup(fill_data, username); | 725 ShowSuggestionPopup(fill_data, username); |
| 726 | 726 |
| 727 | 727 |
| 728 #if !defined(OS_ANDROID) | 728 #if !defined(OS_ANDROID) |
| 729 // Fill the user and password field with the most relevant match. Android | 729 // Fill the user and password field with the most relevant match. Android |
| 730 // only fills in the fields after the user clicks on the suggestion popup. | 730 // only fills in the fields after the user clicks on the suggestion popup. |
| 731 FillUserNameAndPassword(&username, &password, fill_data, | 731 FillUserNameAndPassword(&username, &password, fill_data, |
| 732 false /* exact_username_match */, | 732 false /* exact_username_match */, |
| 733 true /* set_selection */); | 733 true /* set_selection */); |
| 734 #endif | 734 #endif |
| 735 } | 735 } |
| 736 | 736 |
| 737 void PasswordAutofillAgent::FrameClosing(const WebKit::WebFrame* frame) { | 737 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { |
| 738 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); | 738 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); |
| 739 iter != login_to_password_info_.end();) { | 739 iter != login_to_password_info_.end();) { |
| 740 if (iter->first.document().frame() == frame) | 740 if (iter->first.document().frame() == frame) |
| 741 login_to_password_info_.erase(iter++); | 741 login_to_password_info_.erase(iter++); |
| 742 else | 742 else |
| 743 ++iter; | 743 ++iter; |
| 744 } | 744 } |
| 745 } | 745 } |
| 746 | 746 |
| 747 bool PasswordAutofillAgent::FindLoginInfo(const WebKit::WebNode& node, | 747 bool PasswordAutofillAgent::FindLoginInfo(const blink::WebNode& node, |
| 748 WebKit::WebInputElement* found_input, | 748 blink::WebInputElement* found_input, |
| 749 PasswordInfo* found_password) { | 749 PasswordInfo* found_password) { |
| 750 if (!node.isElementNode()) | 750 if (!node.isElementNode()) |
| 751 return false; | 751 return false; |
| 752 | 752 |
| 753 WebKit::WebElement element = node.toConst<WebKit::WebElement>(); | 753 blink::WebElement element = node.toConst<blink::WebElement>(); |
| 754 if (!element.hasTagName("input")) | 754 if (!element.hasTagName("input")) |
| 755 return false; | 755 return false; |
| 756 | 756 |
| 757 WebKit::WebInputElement input = element.to<WebKit::WebInputElement>(); | 757 blink::WebInputElement input = element.to<blink::WebInputElement>(); |
| 758 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); | 758 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); |
| 759 if (iter == login_to_password_info_.end()) | 759 if (iter == login_to_password_info_.end()) |
| 760 return false; | 760 return false; |
| 761 | 761 |
| 762 *found_input = input; | 762 *found_input = input; |
| 763 *found_password = iter->second; | 763 *found_password = iter->second; |
| 764 return true; | 764 return true; |
| 765 } | 765 } |
| 766 | 766 |
| 767 } // namespace autofill | 767 } // namespace autofill |
| OLD | NEW |