Chromium Code Reviews| 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/autofill_helper.h" | 5 #include "chrome/renderer/autofill_helper.h" |
| 6 | 6 |
| 7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
| 8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
| 9 #include "chrome/common/chrome_constants.h" | 9 #include "chrome/common/chrome_constants.h" |
| 10 #include "chrome/renderer/form_manager.h" | 10 #include "chrome/renderer/form_manager.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 } // namespace | 47 } // namespace |
| 48 | 48 |
| 49 AutoFillHelper::AutoFillHelper(RenderView* render_view) | 49 AutoFillHelper::AutoFillHelper(RenderView* render_view) |
| 50 : render_view_(render_view), | 50 : render_view_(render_view), |
| 51 autofill_query_id_(0), | 51 autofill_query_id_(0), |
| 52 autofill_action_(AUTOFILL_NONE), | 52 autofill_action_(AUTOFILL_NONE), |
| 53 suggestions_clear_index_(-1), | 53 suggestions_clear_index_(-1), |
| 54 suggestions_options_index_(-1) { | 54 suggestions_options_index_(-1) { |
| 55 } | 55 } |
| 56 | 56 |
| 57 void AutoFillHelper::QueryAutoFillSuggestions(const WebNode& node) { | 57 void AutoFillHelper::QueryAutoFillSuggestions(const WebNode& node, |
| 58 bool autofill_disabled) { | |
| 58 static int query_counter = 0; | 59 static int query_counter = 0; |
| 59 autofill_query_id_ = query_counter++; | 60 autofill_query_id_ = query_counter++; |
| 60 autofill_query_node_ = node; | 61 autofill_query_node_ = node; |
| 61 | 62 |
| 62 const WebFormControlElement& element = node.toConst<WebFormControlElement>(); | 63 const WebFormControlElement& element = node.toConst<WebFormControlElement>(); |
| 63 webkit_glue::FormField field; | 64 webkit_glue::FormField field; |
| 64 FormManager::WebFormControlElementToFormField( | 65 FormManager::WebFormControlElementToFormField( |
| 65 element, FormManager::EXTRACT_VALUE, &field); | 66 element, FormManager::EXTRACT_VALUE, &field); |
| 66 | 67 |
| 67 // WebFormControlElementToFormField does not scrape the DOM for the field | 68 // WebFormControlElementToFormField does not scrape the DOM for the field |
| 68 // label, so find the label here. | 69 // label, so find the label here. |
| 69 // TODO(jhawkins): Add form and field identities so we can use the cached form | 70 // TODO(jhawkins): Add form and field identities so we can use the cached form |
| 70 // data in FormManager. | 71 // data in FormManager. |
| 71 field.set_label(FormManager::LabelForElement(element)); | 72 field.set_label(FormManager::LabelForElement(element)); |
| 72 | 73 |
| 73 bool field_autofilled = NodeIsAutoFilled(node); | 74 bool field_autofilled = NodeIsAutoFilled(node); |
| 74 render_view_->Send(new ViewHostMsg_QueryFormFieldAutoFill( | 75 render_view_->Send(new ViewHostMsg_QueryFormFieldAutoFill( |
| 75 render_view_->routing_id(), autofill_query_id_, field_autofilled, field)); | 76 render_view_->routing_id(), autofill_query_id_, field_autofilled, field, |
| 77 autofill_disabled)); | |
| 76 } | 78 } |
| 77 | 79 |
| 78 void AutoFillHelper::RemoveAutocompleteSuggestion( | 80 void AutoFillHelper::RemoveAutocompleteSuggestion( |
| 79 const WebKit::WebString& name, const WebKit::WebString& value) { | 81 const WebKit::WebString& name, const WebKit::WebString& value) { |
| 80 // The index of clear & options will have shifted down. | 82 // The index of clear & options will have shifted down. |
| 81 if (suggestions_clear_index_ != -1) | 83 if (suggestions_clear_index_ != -1) |
| 82 suggestions_clear_index_--; | 84 suggestions_clear_index_--; |
| 83 if (suggestions_options_index_ != -1) | 85 if (suggestions_options_index_ != -1) |
| 84 suggestions_options_index_--; | 86 suggestions_options_index_--; |
| 85 | 87 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 116 i.push_back(string16()); | 118 i.push_back(string16()); |
| 117 ids.push_back(0); | 119 ids.push_back(0); |
| 118 suggestions_clear_index_ = v.size() - 1; | 120 suggestions_clear_index_ = v.size() - 1; |
| 119 separator_index = values.size(); | 121 separator_index = values.size(); |
| 120 } | 122 } |
| 121 | 123 |
| 122 // Only include "AutoFill Options" special menu item if we have AutoFill | 124 // Only include "AutoFill Options" special menu item if we have AutoFill |
| 123 // items, identified by |unique_ids| having at least one valid value. | 125 // items, identified by |unique_ids| having at least one valid value. |
| 124 bool show_options = false; | 126 bool show_options = false; |
| 125 for (size_t i = 0; i < ids.size(); ++i) { | 127 for (size_t i = 0; i < ids.size(); ++i) { |
| 126 if (ids[i] != 0) { | 128 if (ids[i] > 0) { |
| 127 show_options = true; | 129 show_options = true; |
| 128 break; | 130 break; |
| 129 } | 131 } |
| 130 } | 132 } |
| 131 if (show_options) { | 133 if (show_options) { |
| 132 // Append the 'Chrome Autofill options' menu item; | 134 // Append the 'Chrome Autofill options' menu item; |
| 133 v.push_back(l10n_util::GetStringFUTF16(IDS_AUTOFILL_OPTIONS_POPUP, | 135 v.push_back(l10n_util::GetStringFUTF16(IDS_AUTOFILL_OPTIONS_POPUP, |
| 134 WideToUTF16(chrome::kBrowserAppName))); | 136 WideToUTF16(chrome::kBrowserAppName))); |
| 135 l.push_back(string16()); | 137 l.push_back(string16()); |
| 136 i.push_back(string16()); | 138 i.push_back(string16()); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 | 221 |
| 220 void AutoFillHelper::FrameWillClose(WebFrame* frame) { | 222 void AutoFillHelper::FrameWillClose(WebFrame* frame) { |
| 221 form_manager_.ResetFrame(frame); | 223 form_manager_.ResetFrame(frame); |
| 222 } | 224 } |
| 223 | 225 |
| 224 void AutoFillHelper::FrameDetached(WebFrame* frame) { | 226 void AutoFillHelper::FrameDetached(WebFrame* frame) { |
| 225 form_manager_.ResetFrame(frame); | 227 form_manager_.ResetFrame(frame); |
| 226 } | 228 } |
| 227 | 229 |
| 228 void AutoFillHelper::TextDidChangeInTextField(const WebInputElement& element) { | 230 void AutoFillHelper::TextDidChangeInTextField(const WebInputElement& element) { |
| 229 ShowSuggestions(element, false, true); | 231 ShowSuggestions(element, false, true, false); |
| 230 } | 232 } |
| 231 | 233 |
| 232 bool AutoFillHelper::InputElementClicked(const WebInputElement& element, | 234 bool AutoFillHelper::InputElementClicked(const WebInputElement& element, |
| 233 bool was_focused, | 235 bool was_focused, |
| 234 bool is_focused) { | 236 bool is_focused) { |
| 235 if (was_focused) | 237 if (was_focused) |
| 236 ShowSuggestions(element, true, false); | 238 ShowSuggestions(element, true, false, true); |
| 237 return false; | 239 return false; |
| 238 } | 240 } |
| 239 | 241 |
| 242 void AutoFillHelper::ShowSuggestions(const WebInputElement& element, | |
| 243 bool autofill_on_empty_values, | |
| 244 bool requires_caret_at_end, | |
| 245 bool display_warning_if_disabled) { | |
| 246 bool autofill_disabled = !element.isEnabledFormControl() || | |
| 247 !element.isText() || element.isPasswordField() || | |
| 248 !element.autoComplete() || element.isReadOnly(); | |
| 249 if (autofill_disabled && !display_warning_if_disabled) | |
| 250 return; | |
| 240 | 251 |
| 241 void AutoFillHelper::ShowSuggestions( | 252 // If the field has no name, then we won't have values. |
| 242 const WebInputElement& const_element, | 253 if (element.nameForAutofill().isEmpty()) |
| 243 bool autofill_on_empty_values, | |
| 244 bool requires_caret_at_end) { | |
| 245 // We need to call non-const methods. | |
| 246 WebInputElement element(const_element); | |
| 247 if (!element.isEnabledFormControl() || | |
| 248 !element.isText() || | |
| 249 element.isPasswordField() || | |
| 250 !element.autoComplete() || element.isReadOnly()) { | |
| 251 return; | |
| 252 } | |
| 253 | |
| 254 WebString name = element.nameForAutofill(); | |
| 255 if (name.isEmpty()) // If the field has no name, then we won't have values. | |
| 256 return; | 254 return; |
| 257 | 255 |
| 258 // Don't attempt to autofill with values that are too large. | 256 // Don't attempt to autofill with values that are too large. |
| 259 WebString value = element.value(); | 257 WebString value = element.value(); |
| 260 if (value.length() > kMaximumTextSizeForAutoFill) | 258 if (value.length() > kMaximumTextSizeForAutoFill) |
| 261 return; | 259 return; |
| 262 | 260 |
| 263 if (!autofill_on_empty_values && value.isEmpty()) | 261 if (!autofill_on_empty_values && value.isEmpty()) |
| 264 return; | 262 return; |
| 265 | 263 |
| 266 if (requires_caret_at_end && | 264 if (requires_caret_at_end && |
| 267 (element.selectionStart() != element.selectionEnd() || | 265 (element.selectionStart() != element.selectionEnd() || |
| 268 element.selectionEnd() != static_cast<int>(value.length()))) { | 266 element.selectionEnd() != static_cast<int>(value.length()))) |
| 269 return; | 267 return; |
| 270 } | |
| 271 | 268 |
| 272 QueryAutoFillSuggestions(element); | 269 QueryAutoFillSuggestions(element, autofill_disabled); |
|
dhollowa
2010/11/12 01:52:03
Could we avoid the IPC call here in the case that
Ilya Sherman
2010/11/12 05:15:38
The thing is, we don't want to show a warning if t
| |
| 273 } | 270 } |
| 274 | 271 |
| 275 void AutoFillHelper::QueryAutoFillFormData(const WebNode& node, | 272 void AutoFillHelper::QueryAutoFillFormData(const WebNode& node, |
| 276 int unique_id, | 273 int unique_id, |
| 277 AutoFillAction action) { | 274 AutoFillAction action) { |
| 278 static int query_counter = 0; | 275 static int query_counter = 0; |
| 279 autofill_query_id_ = query_counter++; | 276 autofill_query_id_ = query_counter++; |
| 280 | 277 |
| 281 webkit_glue::FormData form; | 278 webkit_glue::FormData form; |
| 282 const WebInputElement element = node.toConst<WebInputElement>(); | 279 const WebInputElement element = node.toConst<WebInputElement>(); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 305 FormManager::EXTRACT_NONE, &form)) { | 302 FormManager::EXTRACT_NONE, &form)) { |
| 306 forms.push_back(form); | 303 forms.push_back(form); |
| 307 } | 304 } |
| 308 } | 305 } |
| 309 | 306 |
| 310 if (!forms.empty()) { | 307 if (!forms.empty()) { |
| 311 render_view_->Send(new ViewHostMsg_FormsSeen(render_view_->routing_id(), | 308 render_view_->Send(new ViewHostMsg_FormsSeen(render_view_->routing_id(), |
| 312 forms)); | 309 forms)); |
| 313 } | 310 } |
| 314 } | 311 } |
| OLD | NEW |