OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/renderer/password_autocomplete_manager.h" | 5 #include "chrome/renderer/password_autocomplete_manager.h" |
6 | 6 |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "base/scoped_ptr.h" | 8 #include "base/scoped_ptr.h" |
9 #include "chrome/common/render_messages.h" | 9 #include "chrome/common/render_messages.h" |
10 #include "chrome/renderer/render_view.h" | 10 #include "chrome/renderer/render_view.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 // in |data|, and add results to |result|. | 46 // in |data|, and add results to |result|. |
47 static bool FindFormInputElements(WebKit::WebFormElement* fe, | 47 static bool FindFormInputElements(WebKit::WebFormElement* fe, |
48 const webkit_glue::FormData& data, | 48 const webkit_glue::FormData& data, |
49 FormElements* result) { | 49 FormElements* result) { |
50 // Loop through the list of elements we need to find on the form in order to | 50 // Loop through the list of elements we need to find on the form in order to |
51 // autocomplete it. If we don't find any one of them, abort processing this | 51 // autocomplete it. If we don't find any one of them, abort processing this |
52 // form; it can't be the right one. | 52 // form; it can't be the right one. |
53 for (size_t j = 0; j < data.fields.size(); j++) { | 53 for (size_t j = 0; j < data.fields.size(); j++) { |
54 WebKit::WebVector<WebKit::WebNode> temp_elements; | 54 WebKit::WebVector<WebKit::WebNode> temp_elements; |
55 fe->getNamedElements(data.fields[j].name(), temp_elements); | 55 fe->getNamedElements(data.fields[j].name(), temp_elements); |
56 if (temp_elements.isEmpty()) { | 56 |
57 // We didn't find a required element. This is not the right form. | 57 // Match the first input element, if any. |
58 // Make sure no input elements from a partially matched form in this | 58 // |getNamedElements| may return non-input elements where the names match, |
59 // iteration remain in the result set. | 59 // so the results are filtered for input elements. |
60 // Note: clear will remove a reference from each InputElement. | 60 // If more than one match is made, then we have ambiguity (due to misuse |
| 61 // of "name" attribute) so is it considered not found. |
| 62 bool found_input = false; |
| 63 for (size_t i = 0; i < temp_elements.size(); ++i) { |
| 64 if (temp_elements[i].to<WebKit::WebElement>().hasTagName("input")) { |
| 65 // Check for a non-unique match. |
| 66 if (found_input) { |
| 67 found_input = false; |
| 68 break; |
| 69 } |
| 70 |
| 71 // This element matched, add it to our temporary result. It's possible |
| 72 // there are multiple matches, but for purposes of identifying the form |
| 73 // one suffices and if some function needs to deal with multiple |
| 74 // matching elements it can get at them through the FormElement*. |
| 75 // Note: This assignment adds a reference to the InputElement. |
| 76 result->input_elements[data.fields[j].name()] = |
| 77 temp_elements[i].to<WebKit::WebInputElement>(); |
| 78 found_input = true; |
| 79 } |
| 80 } |
| 81 |
| 82 // A required element was not found. This is not the right form. |
| 83 // Make sure no input elements from a partially matched form in this |
| 84 // iteration remain in the result set. |
| 85 // Note: clear will remove a reference from each InputElement. |
| 86 if (!found_input) { |
61 result->input_elements.clear(); | 87 result->input_elements.clear(); |
62 return false; | 88 return false; |
63 } | 89 } |
64 // This element matched, add it to our temporary result. It's possible there | |
65 // are multiple matches, but for purposes of identifying the form one | |
66 // suffices and if some function needs to deal with multiple matching | |
67 // elements it can get at them through the FormElement*. | |
68 // Note: This assignment adds a reference to the InputElement. | |
69 result->input_elements[data.fields[j].name()] = | |
70 temp_elements[0].to<WebKit::WebInputElement>(); | |
71 } | 90 } |
72 return true; | 91 return true; |
73 } | 92 } |
74 | 93 |
75 // Helper to locate form elements identified by |data|. | 94 // Helper to locate form elements identified by |data|. |
76 void FindFormElements(WebKit::WebView* view, | 95 void FindFormElements(WebKit::WebView* view, |
77 const webkit_glue::FormData& data, | 96 const webkit_glue::FormData& data, |
78 FormElementsList* results) { | 97 FormElementsList* results) { |
79 DCHECK(view); | 98 DCHECK(view); |
80 DCHECK(results); | 99 DCHECK(results); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 bool FillForm(FormElements* fe, const webkit_glue::FormData& data) { | 140 bool FillForm(FormElements* fe, const webkit_glue::FormData& data) { |
122 if (!fe->form_element.autoComplete()) | 141 if (!fe->form_element.autoComplete()) |
123 return false; | 142 return false; |
124 | 143 |
125 std::map<string16, string16> data_map; | 144 std::map<string16, string16> data_map; |
126 for (size_t i = 0; i < data.fields.size(); i++) | 145 for (size_t i = 0; i < data.fields.size(); i++) |
127 data_map[data.fields[i].name()] = data.fields[i].value(); | 146 data_map[data.fields[i].name()] = data.fields[i].value(); |
128 | 147 |
129 for (FormInputElementMap::iterator it = fe->input_elements.begin(); | 148 for (FormInputElementMap::iterator it = fe->input_elements.begin(); |
130 it != fe->input_elements.end(); ++it) { | 149 it != fe->input_elements.end(); ++it) { |
131 WebKit::WebInputElement& element = it->second; | 150 WebKit::WebInputElement element = it->second; |
132 if (!element.value().isEmpty()) // Don't overwrite pre-filled values. | 151 if (!element.value().isEmpty()) // Don't overwrite pre-filled values. |
133 continue; | 152 continue; |
134 if (element.isPasswordField() && | 153 if (element.isPasswordField() && |
135 (!element.isEnabledFormControl() || element.hasAttribute("readonly"))) { | 154 (!element.isEnabledFormControl() || element.hasAttribute("readonly"))) { |
136 continue; // Don't fill uneditable password fields. | 155 continue; // Don't fill uneditable password fields. |
137 } | 156 } |
138 // TODO(tkent): Check maxlength and pattern. | 157 // TODO(tkent): Check maxlength and pattern. |
139 element.setValue(data_map[it->first]); | 158 element.setValue(data_map[it->first]); |
140 element.setAutofilled(true); | 159 element.setAutofilled(true); |
141 element.dispatchFormControlChangeEvent(); | 160 element.dispatchFormControlChangeEvent(); |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 username_element->setSelectionRange(current_username.length(), | 509 username_element->setSelectionRange(current_username.length(), |
491 username.length()); | 510 username.length()); |
492 } | 511 } |
493 | 512 |
494 SetElementAutofilled(username_element, true); | 513 SetElementAutofilled(username_element, true); |
495 if (IsElementEditable(*password_element)) | 514 if (IsElementEditable(*password_element)) |
496 password_element->setValue(password); | 515 password_element->setValue(password); |
497 SetElementAutofilled(password_element, true); | 516 SetElementAutofilled(password_element, true); |
498 return true; | 517 return true; |
499 } | 518 } |
OLD | NEW |