Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1386)

Side by Side Diff: components/autofill/content/renderer/password_autofill_agent.cc

Issue 63273002: Rename WebKit namespace to blink (part 4) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698