summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjcivelli@google.com <jcivelli@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-22 22:57:44 +0000
committerjcivelli@google.com <jcivelli@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-22 22:57:44 +0000
commit679f128fc208f1d983c4e5913f108ae4ff018e6b (patch)
tree719fd7f47eb63c7416344ff9362f8b1bf6e3ee98
parent540659481e1a9f87872566b59d15ba1ce75d1c1f (diff)
downloadchromium_src-679f128fc208f1d983c4e5913f108ae4ff018e6b.zip
chromium_src-679f128fc208f1d983c4e5913f108ae4ff018e6b.tar.gz
chromium_src-679f128fc208f1d983c4e5913f108ae4ff018e6b.tar.bz2
This CL creates a new class AutofillHelper that factors out the autofill related code out of render_view.cc.
This is to limit the bloating of RenderView code, which would soon get even worse once we move the Webkit autofill to Chrome. There is no logic change in this CL. BUG=None TEST=Make sure form autofill and autocomplete work as expected. Review URL: http://codereview.chromium.org/2834060 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@53413 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/chrome_renderer.gypi2
-rw-r--r--chrome/renderer/autofill_helper.cc239
-rw-r--r--chrome/renderer/autofill_helper.h124
-rw-r--r--chrome/renderer/password_autocomplete_manager.cc47
-rw-r--r--chrome/renderer/password_autocomplete_manager.h11
-rw-r--r--chrome/renderer/render_view.cc215
-rw-r--r--chrome/renderer/render_view.h52
7 files changed, 441 insertions, 249 deletions
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index 1f98725..4cb668d 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -42,6 +42,8 @@
# But app/ is the wrong directory for them.
# Better is to remove the dep of *_tests on renderer, but in the
# short term I'd like the build to work.
+ 'renderer/autofill_helper.cc',
+ 'renderer/autofill_helper.h',
'renderer/automation/dom_automation_controller.cc',
'renderer/automation/dom_automation_controller.h',
'renderer/automation/dom_automation_v8_extension.cc',
diff --git a/chrome/renderer/autofill_helper.cc b/chrome/renderer/autofill_helper.cc
new file mode 100644
index 0000000..2c6d6c8
--- /dev/null
+++ b/chrome/renderer/autofill_helper.cc
@@ -0,0 +1,239 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/autofill_helper.h"
+
+#include "app/l10n_util.h"
+#include "chrome/renderer/form_manager.h"
+#include "chrome/renderer/render_view.h"
+#include "grit/generated_resources.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFormControlElement.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
+#include "webkit/glue/password_form.h"
+
+using WebKit::WebFormControlElement;
+using WebKit::WebFormElement;
+using WebKit::WebFrame;
+using WebKit::WebInputElement;
+using WebKit::WebNode;
+using WebKit::WebString;
+
+AutoFillHelper::AutoFillHelper(RenderView* render_view)
+ : render_view_(render_view),
+ autofill_query_id_(0),
+ autofill_action_(AUTOFILL_NONE),
+ suggestions_clear_index_(-1),
+ suggestions_options_index_(-1) {
+}
+
+void AutoFillHelper::QueryAutocompleteSuggestions(const WebNode& node,
+ const WebString& name,
+ const WebString& value) {
+ static int query_counter = 0;
+ autofill_query_id_ = query_counter++;
+ autofill_query_node_ = node;
+
+ const WebFormControlElement& element = node.toConst<WebFormControlElement>();
+ webkit_glue::FormField field;
+ FormManager::WebFormControlElementToFormField(element, true, &field);
+
+ // WebFormControlElementToFormField does not scrape the DOM for the field
+ // label, so find the label here.
+ // TODO(jhawkins): Add form and field identities so we can use the cached form
+ // data in FormManager.
+ field.set_label(FormManager::LabelForElement(element));
+
+ bool form_autofilled = form_manager_.FormWithNodeIsAutoFilled(node);
+ render_view_->Send(new ViewHostMsg_QueryFormFieldAutoFill(
+ render_view_->routing_id(), autofill_query_id_, form_autofilled, field));
+}
+
+void AutoFillHelper::RemoveAutocompleteSuggestion(
+ const WebKit::WebString& name, const WebKit::WebString& value) {
+ // The index of clear & options will have shifted down.
+ if (suggestions_clear_index_ != -1)
+ suggestions_clear_index_--;
+ if (suggestions_options_index_ != -1)
+ suggestions_options_index_--;
+
+ render_view_->Send(new ViewHostMsg_RemoveAutocompleteEntry(
+ render_view_->routing_id(), name, value));
+}
+
+void AutoFillHelper::SuggestionsReceived(int query_id,
+ const std::vector<string16>& values,
+ const std::vector<string16>& labels,
+ const std::vector<int>& unique_ids) {
+ WebKit::WebView* web_view = render_view_->webview();
+ if (!web_view || query_id != autofill_query_id_)
+ return;
+
+ // Any popup currently showing is now obsolete.
+ web_view->hidePopups();
+
+ // No suggestions: nothing to do.
+ if (values.empty())
+ return;
+
+ std::vector<string16> v(values);
+ std::vector<string16> l(labels);
+ std::vector<int> ids(unique_ids);
+ int separator_index = -1;
+
+ // The form has been auto-filled, so give the user the chance to clear the
+ // form. Append the 'Clear form' menu item.
+ if (form_manager_.FormWithNodeIsAutoFilled(autofill_query_node_)) {
+ v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM));
+ l.push_back(string16());
+ ids.push_back(0);
+ suggestions_clear_index_ = v.size() - 1;
+ separator_index = values.size();
+ }
+
+ // Only include "AutoFill Options" special menu item if we have AutoFill
+ // items, identified by |unique_ids| having at least one valid value.
+ bool show_options = false;
+ for (size_t i = 0; i < ids.size(); ++i) {
+ if (ids[i] != 0) {
+ show_options = true;
+ break;
+ }
+ }
+ if (show_options) {
+ // Append the 'AutoFill Options...' menu item.
+ v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS));
+ l.push_back(string16());
+ ids.push_back(0);
+ suggestions_options_index_ = v.size() - 1;
+ separator_index = values.size();
+ }
+
+ // Send to WebKit for display.
+ if (!v.empty()) {
+ web_view->applyAutoFillSuggestions(
+ autofill_query_node_, v, l, ids, separator_index);
+ }
+}
+
+void AutoFillHelper::FormDataFilled(int query_id,
+ const webkit_glue::FormData& form) {
+ if (!render_view_->webview() || query_id != autofill_query_id_)
+ return;
+
+ switch (autofill_action_) {
+ case AUTOFILL_FILL:
+ form_manager_.FillForm(form, autofill_query_node_);
+ break;
+ case AUTOFILL_PREVIEW:
+ form_manager_.PreviewForm(form);
+ break;
+ default:
+ NOTREACHED();
+ }
+ autofill_action_ = AUTOFILL_NONE;
+}
+
+void AutoFillHelper::DidSelectAutoFillSuggestion(const WebNode& node,
+ const WebString& value,
+ const WebString& label,
+ int unique_id) {
+ DidClearAutoFillSelection(node);
+ QueryAutoFillFormData(node, value, label, unique_id, AUTOFILL_PREVIEW);
+}
+
+void AutoFillHelper::DidAcceptAutoFillSuggestion(const WebNode& node,
+ const WebString& value,
+ const WebString& label,
+ int unique_id,
+ unsigned index) {
+ if (suggestions_options_index_ != -1 &&
+ index == static_cast<unsigned>(suggestions_options_index_)) {
+ // User selected 'AutoFill Options'.
+ render_view_->Send(new ViewHostMsg_ShowAutoFillDialog(
+ render_view_->routing_id()));
+ } else if (suggestions_clear_index_ != -1 &&
+ index == static_cast<unsigned>(suggestions_clear_index_)) {
+ // User selected 'Clear form'.
+ // The form has been auto-filled, so give the user the chance to clear the
+ // form.
+ form_manager_.ClearFormWithNode(node);
+ } else if (form_manager_.FormWithNodeIsAutoFilled(node) || !unique_id) {
+ // User selected an Autocomplete entry, so we fill directly.
+ WebInputElement element = node.toConst<WebInputElement>();
+ element.setValue(value);
+
+ WebFrame* webframe = node.document().frame();
+ if (webframe)
+ webframe->notifiyPasswordListenerOfAutocomplete(element);
+ } else {
+ // Fill the values for the whole form.
+ QueryAutoFillFormData(node, value, label, unique_id, AUTOFILL_FILL);
+ }
+
+ suggestions_clear_index_ = -1;
+ suggestions_options_index_ = -1;
+}
+
+void AutoFillHelper::DidClearAutoFillSelection(const WebNode& node) {
+ webkit_glue::FormData form;
+ const WebFormControlElement element = node.toConst<WebFormControlElement>();
+ if (!form_manager_.FindFormWithFormControlElement(
+ element, FormManager::REQUIRE_NONE, &form)) {
+ return;
+ }
+ form_manager_.ClearPreviewedForm(form);
+}
+
+void AutoFillHelper::FrameContentsAvailable(WebFrame* frame) {
+ form_manager_.ExtractForms(frame);
+ SendForms(frame);
+}
+
+void AutoFillHelper::FrameWillClose(WebFrame* frame) {
+ form_manager_.ResetFrame(frame);
+}
+
+void AutoFillHelper::QueryAutoFillFormData(const WebNode& node,
+ const WebString& value,
+ const WebString& label,
+ int unique_id,
+ AutoFillAction action) {
+ static int query_counter = 0;
+ autofill_query_id_ = query_counter++;
+
+ webkit_glue::FormData form;
+ const WebInputElement element = node.toConst<WebInputElement>();
+ if (!form_manager_.FindFormWithFormControlElement(
+ element, FormManager::REQUIRE_NONE, &form))
+ return;
+
+ autofill_action_ = action;
+ render_view_->Send(new ViewHostMsg_FillAutoFillFormData(
+ render_view_->routing_id(), autofill_query_id_, form, value, label,
+ unique_id));
+}
+
+void AutoFillHelper::SendForms(WebFrame* frame) {
+ // TODO(jhawkins): Use FormManager once we have strict ordering of form
+ // control elements in the cache.
+ WebKit::WebVector<WebFormElement> web_forms;
+ frame->forms(web_forms);
+
+ std::vector<webkit_glue::FormData> forms;
+ for (size_t i = 0; i < web_forms.size(); ++i) {
+ const WebFormElement& web_form = web_forms[i];
+
+ webkit_glue::FormData form;
+ if (FormManager::WebFormElementToFormData(
+ web_form, FormManager::REQUIRE_NONE, false, &form)) {
+ forms.push_back(form);
+ }
+ }
+
+ if (!forms.empty()) {
+ render_view_->Send(new ViewHostMsg_FormsSeen(render_view_->routing_id(),
+ forms));
+ }
+}
diff --git a/chrome/renderer/autofill_helper.h b/chrome/renderer/autofill_helper.h
new file mode 100644
index 0000000..4395144
--- /dev/null
+++ b/chrome/renderer/autofill_helper.h
@@ -0,0 +1,124 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_RENDERER_AUTOFILL_HELPER_H_
+#define CHROME_RENDERER_AUTOFILL_HELPER_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "chrome/renderer/form_manager.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebNode.h"
+
+class RenderView;
+
+namespace WebKit {
+class WebInputElement;
+class WebString;
+}
+
+// AutoFillHelper deals with autofill related communications between WebKit and
+// the browser. There is one AutofillHelper per RenderView.
+// This code was originally part of RenderView.
+// Note that autofill encompasses:
+// - single text field suggestions, that we usually refer to as Autocomplete
+// - entire form fill based on one field entry, refered as form AutoFill.
+
+class AutoFillHelper {
+ public:
+ explicit AutoFillHelper(RenderView* render_view);
+
+ // Queries the browser for Autocomplete suggestion for the given |node|.
+ // (Autocomplete means suggestions for a single text input.)
+ void QueryAutocompleteSuggestions(const WebKit::WebNode& node,
+ const WebKit::WebString& name,
+ const WebKit::WebString& value);
+
+ // Removes the Autocomplete suggestion |value| for the field names |name|.
+ void RemoveAutocompleteSuggestion(const WebKit::WebString& name,
+ const WebKit::WebString& value);
+
+ // Called when we have received Autofill suggestions from the browser.
+ void SuggestionsReceived(int query_id,
+ const std::vector<string16>& values,
+ const std::vector<string16>& labels,
+ const std::vector<int>& unique_ids);
+
+ // Called when we have received suggestions for an entire form from the
+ // browser.
+ void FormDataFilled(int query_id, const webkit_glue::FormData& form);
+
+ // Called by Webkit when the user has selected a suggestion in the popup (this
+ // happens when the user hovers over an suggestion or navigates the popup with
+ // the arrow keys).
+ void DidSelectAutoFillSuggestion(const WebKit::WebNode& node,
+ const WebKit::WebString& value,
+ const WebKit::WebString& label,
+ int unique_id);
+
+ // Called by Webkit when the user has accepted a suggestion in the popup.
+ void DidAcceptAutoFillSuggestion(const WebKit::WebNode& node,
+ const WebKit::WebString& value,
+ const WebKit::WebString& label,
+ int unique_id,
+ unsigned index);
+
+ // Called by WebKit when the user has cleared the selection from the AutoFill
+ // suggestions popup. This happens when a user uses the arrow keys to
+ // navigate outside the range of possible selections, or when the popup
+ // closes.
+ void DidClearAutoFillSelection(const WebKit::WebNode& node);
+
+ // Called when the frame contents are available. Extracts the forms from that
+ // frame and sends them to the browser for parsing.
+ void FrameContentsAvailable(WebKit::WebFrame* frame);
+
+ // Called before a frame is closed. Gives us an oppotunity to clean-up.
+ void FrameWillClose(WebKit::WebFrame* frame);
+
+ private:
+ enum AutoFillAction {
+ AUTOFILL_NONE, // No state set.
+ AUTOFILL_FILL, // Fill the AutoFill form data.
+ AUTOFILL_PREVIEW, // Preview the AutoFill form data.
+ };
+
+ // Queries the AutoFillManager for form data for the form containing |node|.
+ // |value| is the current text in the field, and |unique_id| is the selected
+ // profile's unique ID. |action| specifies whether to Fill or Preview the
+ // values returned from the AutoFillManager.
+ void QueryAutoFillFormData(const WebKit::WebNode& node,
+ const WebKit::WebString& value,
+ const WebKit::WebString& label,
+ int unique_id,
+ AutoFillAction action);
+
+ // Scans the given frame for forms and sends them up to the browser.
+ void SendForms(WebKit::WebFrame* frame);
+
+ // Weak reference.
+ RenderView* render_view_;
+
+ FormManager form_manager_;
+
+ // The ID of the last request sent for form field AutoFill. Used to ignore
+ // out of date responses.
+ int autofill_query_id_;
+
+ // The node corresponding to the last request sent for form field AutoFill.
+ WebKit::WebNode autofill_query_node_;
+
+ // The action to take when receiving AutoFill data from the AutoFillManager.
+ AutoFillAction autofill_action_;
+
+ // The menu index of the "Clear" menu item.
+ int suggestions_clear_index_;
+
+ // The menu index of the "AutoFill options..." menu item.
+ int suggestions_options_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutoFillHelper);
+};
+
+#endif // CHROME_RENDERER_AUTOFILL_HELPER_H_
diff --git a/chrome/renderer/password_autocomplete_manager.cc b/chrome/renderer/password_autocomplete_manager.cc
index f8f10ec..0cc3732 100644
--- a/chrome/renderer/password_autocomplete_manager.cc
+++ b/chrome/renderer/password_autocomplete_manager.cc
@@ -7,14 +7,18 @@
#include "base/keyboard_codes.h"
#include "base/message_loop.h"
#include "base/scoped_ptr.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/renderer/render_view.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/WebKit/chromium/public/WebElement.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFormElement.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
#include "webkit/glue/form_field.h"
+#include "webkit/glue/password_form.h"
#include "webkit/glue/password_form_dom_manager.h"
namespace {
@@ -166,7 +170,8 @@ bool DoUsernamesMatch(const string16& username1,
PasswordAutocompleteManager::PasswordAutocompleteManager(
RenderView* render_view)
- : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
+ : render_view_(render_view),
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
}
PasswordAutocompleteManager::~PasswordAutocompleteManager() {
@@ -338,6 +343,43 @@ void PasswordAutocompleteManager::PerformInlineAutocomplete(
FillUserNameAndPassword(&username, &password, fill_data, false);
}
+void PasswordAutocompleteManager::SendPasswordForms(WebKit::WebFrame* frame,
+ bool only_visible) {
+ // Make sure that this security origin is allowed to use password manager.
+ WebKit::WebSecurityOrigin security_origin = frame->securityOrigin();
+ if (!security_origin.canAccessPasswordManager())
+ return;
+
+ WebKit::WebVector<WebKit::WebFormElement> forms;
+ frame->forms(forms);
+
+ std::vector<webkit_glue::PasswordForm> password_forms;
+ for (size_t i = 0; i < forms.size(); ++i) {
+ const WebKit::WebFormElement& form = forms[i];
+
+ // Respect autocomplete=off.
+ if (!form.autoComplete())
+ continue;
+ if (only_visible && !form.hasNonEmptyBoundingBox())
+ continue;
+ scoped_ptr<webkit_glue::PasswordForm> password_form(
+ webkit_glue::PasswordFormDomManager::CreatePasswordForm(form));
+ if (password_form.get())
+ password_forms.push_back(*password_form);
+ }
+
+ if (password_forms.empty())
+ return;
+
+ if (only_visible) {
+ render_view_->Send(
+ new ViewHostMsg_PasswordFormsVisible(GetRoutingID(), password_forms));
+ } else {
+ render_view_->Send(
+ new ViewHostMsg_PasswordFormsFound(GetRoutingID(), password_forms));
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
// PasswordAutocompleteManager, private:
@@ -414,3 +456,6 @@ bool PasswordAutocompleteManager::FillUserNameAndPassword(
return true;
}
+int PasswordAutocompleteManager::GetRoutingID() const {
+ return render_view_->routing_id();
+}
diff --git a/chrome/renderer/password_autocomplete_manager.h b/chrome/renderer/password_autocomplete_manager.h
index 5e2eee2..297decc 100644
--- a/chrome/renderer/password_autocomplete_manager.h
+++ b/chrome/renderer/password_autocomplete_manager.h
@@ -48,6 +48,10 @@ class PasswordAutocompleteManager {
const WebKit::WebInputElement& password,
const webkit_glue::PasswordFormFillData& fill_data);
+ // Scans the given frame for password forms and sends them up to the browser.
+ // If |only_visible| is true, only forms visible in the layout are sent.
+ void SendPasswordForms(WebKit::WebFrame* frame, bool only_visible);
+
// WebViewClient editor related calls forwarded by the RenderView.
void TextFieldDidBeginEditing(const WebKit::WebInputElement& element);
void TextFieldDidEndEditing(const WebKit::WebInputElement& element);
@@ -79,6 +83,13 @@ class PasswordAutocompleteManager {
const webkit_glue::PasswordFormFillData& fill_data,
bool exact_username_match);
+ // Convenience method that returns the routing ID of the render view we are
+ // associated with.
+ int GetRoutingID() const;
+
+ // Weak reference.
+ RenderView* render_view_;
+
// The logins we have filled so far with their associated info.
LoginToPasswordInfoMap login_to_password_info_;
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index e6eccfa..55fa0c2 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -123,7 +123,6 @@
#include "webkit/glue/media/buffered_data_source.h"
#include "webkit/glue/media/simple_data_source.h"
#include "webkit/glue/media/video_renderer_impl.h"
-#include "webkit/glue/password_form.h"
#include "webkit/glue/plugins/default_plugin_shared.h"
#include "webkit/glue/plugins/pepper_webplugin_impl.h"
#include "webkit/glue/plugins/plugin_list.h"
@@ -434,14 +433,11 @@ RenderView::RenderView(RenderThreadBase* render_thread,
spelling_panel_visible_(false),
view_type_(ViewType::INVALID),
browser_window_id_(-1),
- autofill_query_id_(0),
- autofill_action_(AUTOFILL_NONE),
- suggestions_clear_index_(-1),
- suggestions_options_index_(-1),
ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(translate_helper_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(password_autocomplete_manager_(this)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(autofill_helper_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(cookie_jar_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(
notification_provider_(new NotificationProvider(this))),
@@ -1520,68 +1516,12 @@ void RenderView::OnAutoFillSuggestionsReturned(
const std::vector<string16>& values,
const std::vector<string16>& labels,
const std::vector<int>& unique_ids) {
- if (!webview() || query_id != autofill_query_id_)
- return;
-
- // Any popup currently showing is now obsolete.
- webview()->hidePopups();
-
- // No suggestions: nothing to do.
- if (values.empty())
- return;
-
- std::vector<string16> v(values);
- std::vector<string16> l(labels);
- std::vector<int> ids(unique_ids);
- int separator_index = -1;
-
- // The form has been auto-filled, so give the user the chance to clear the
- // form. Append the 'Clear form' menu item.
- if (form_manager_.FormWithNodeIsAutoFilled(autofill_query_node_)) {
- v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM));
- l.push_back(string16());
- ids.push_back(0);
- suggestions_clear_index_ = v.size() - 1;
- separator_index = values.size();
- }
-
- size_t autofill_item_count = 0;
- for (size_t i = 0; i < ids.size(); ++i) {
- if (ids[i] != 0)
- autofill_item_count++;
- }
-
- // Only include "AutoFill Options" special menu item if we have AutoFill
- // items, identified by |unique_ids| having at least one valid value.
- if (autofill_item_count > 0) {
- // Append the 'AutoFill Options...' menu item.
- v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS));
- l.push_back(string16());
- ids.push_back(0);
- suggestions_options_index_ = v.size() - 1;
- separator_index = values.size();
- }
-
- // Send to WebKit for display.
- if (!v.empty()) {
- webview()->applyAutoFillSuggestions(
- autofill_query_node_, v, l, ids, separator_index);
- }
+ autofill_helper_.SuggestionsReceived(query_id, values, labels, unique_ids);
}
void RenderView::OnAutoFillFormDataFilled(int query_id,
const webkit_glue::FormData& form) {
- if (!webview() || query_id != autofill_query_id_)
- return;
-
- DCHECK_NE(AUTOFILL_NONE, autofill_action_);
-
- if (autofill_action_ == AUTOFILL_FILL)
- form_manager_.FillForm(form, autofill_query_node_);
- else if (autofill_action_ == AUTOFILL_PREVIEW)
- form_manager_.PreviewForm(form);
-
- autofill_action_ = AUTOFILL_NONE;
+ autofill_helper_.FormDataFilled(query_id, form);
}
void RenderView::OnAllowScriptToClose(bool script_can_close) {
@@ -2146,36 +2086,12 @@ void RenderView::didUpdateInspectorSetting(const WebString& key,
void RenderView::queryAutofillSuggestions(const WebNode& node,
const WebString& name,
const WebString& value) {
- static int query_counter = 0;
- autofill_query_id_ = query_counter++;
- autofill_query_node_ = node;
-
- const WebFormControlElement& element =
- node.toConst<WebFormControlElement>();
-
- webkit_glue::FormField field;
- FormManager::WebFormControlElementToFormField(element, true, &field);
-
- // WebFormControlElementToFormField does not scrape the DOM for the field
- // label, so find the label here.
- // TODO(jhawkins): Add form and field identities so we can use the cached form
- // data in FormManager.
- field.set_label(FormManager::LabelForElement(element));
-
- bool form_autofilled = form_manager_.FormWithNodeIsAutoFilled(node);
- Send(new ViewHostMsg_QueryFormFieldAutoFill(
- routing_id_, autofill_query_id_, form_autofilled, field));
+ autofill_helper_.QueryAutocompleteSuggestions(node, name, value);
}
void RenderView::removeAutofillSuggestions(const WebString& name,
const WebString& value) {
- // The index of clear & options will have shifted down.
- if (suggestions_clear_index_ != -1)
- suggestions_clear_index_--;
- if (suggestions_options_index_ != -1)
- suggestions_options_index_--;
-
- Send(new ViewHostMsg_RemoveAutocompleteEntry(routing_id_, name, value));
+ autofill_helper_.RemoveAutocompleteSuggestion(name, value);
}
void RenderView::didAcceptAutoFillSuggestion(const WebKit::WebNode& node,
@@ -2183,49 +2099,19 @@ void RenderView::didAcceptAutoFillSuggestion(const WebKit::WebNode& node,
const WebKit::WebString& label,
int unique_id,
unsigned index) {
- if (suggestions_options_index_ != -1 &&
- index == static_cast<unsigned>(suggestions_options_index_)) {
- // User selected 'AutoFill Options'.
- Send(new ViewHostMsg_ShowAutoFillDialog(routing_id_));
- } else if (suggestions_clear_index_ != -1 &&
- index == static_cast<unsigned>(suggestions_clear_index_)) {
- // User selected 'Clear form'.
- // The form has been auto-filled, so give the user the chance to clear the
- // form.
- form_manager_.ClearFormWithNode(node);
- } else if (form_manager_.FormWithNodeIsAutoFilled(node) || !unique_id) {
- // User selected an Autocomplete entry, so we fill directly.
- WebInputElement element = node.toConst<WebInputElement>();
- element.setValue(value);
-
- WebFrame* webframe = node.document().frame();
- if (webframe) {
- webframe->notifiyPasswordListenerOfAutocomplete(element);
- }
- } else {
- // Fill the values for the whole form.
- QueryAutoFillFormData(node, value, label, unique_id, AUTOFILL_FILL);
- }
-
- suggestions_clear_index_ = -1;
- suggestions_options_index_ = -1;
+ autofill_helper_.DidAcceptAutoFillSuggestion(node, value, label, unique_id,
+ index);
}
void RenderView::didSelectAutoFillSuggestion(const WebKit::WebNode& node,
const WebKit::WebString& value,
const WebKit::WebString& label,
int unique_id) {
- didClearAutoFillSelection(node);
- QueryAutoFillFormData(node, value, label, unique_id, AUTOFILL_PREVIEW);
+ autofill_helper_.DidSelectAutoFillSuggestion(node, value, label, unique_id);
}
void RenderView::didClearAutoFillSelection(const WebKit::WebNode& node) {
- webkit_glue::FormData form;
- const WebFormControlElement element = node.toConst<WebFormControlElement>();
- if (!form_manager_.FindFormWithFormControlElement(
- element, FormManager::REQUIRE_NONE, &form))
- return;
- form_manager_.ClearPreviewedForm(form);
+ autofill_helper_.DidClearAutoFillSelection(node);
}
void RenderView::didAcceptAutocompleteSuggestion(
@@ -2421,7 +2307,7 @@ void RenderView::willClose(WebFrame* frame) {
NavigationState* navigation_state = NavigationState::FromDataSource(ds);
navigation_state->user_script_idle_scheduler()->Cancel();
- form_manager_.ResetFrame(frame);
+ autofill_helper_.FrameWillClose(frame);
}
bool RenderView::allowImages(WebFrame* frame, bool enabled_per_settings) {
@@ -2947,10 +2833,8 @@ void RenderView::didFinishDocumentLoad(WebFrame* frame) {
// The document has now been fully loaded. Scan for forms to be sent up to
// the browser.
- // TODO(jhawkins): Make these use the FormManager.
- form_manager_.ExtractForms(frame);
- SendForms(frame);
- SendPasswordForms(frame, false);
+ autofill_helper_.FrameContentsAvailable(frame);
+ password_autocomplete_manager_.SendPasswordForms(frame, false);
// Check whether we have new encoding name.
UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
@@ -2997,7 +2881,7 @@ void RenderView::didFinishLoad(WebFrame* frame) {
navigation_state->user_script_idle_scheduler()->DidFinishLoad();
// Let the password manager know which password forms are actually visible.
- SendPasswordForms(frame, true);
+ password_autocomplete_manager_.SendPasswordForms(frame, true);
}
void RenderView::didNavigateWithinPage(
@@ -5013,26 +4897,6 @@ void RenderView::focusAccessibilityObject(
#endif
}
-void RenderView::SendForms(WebFrame* frame) {
- // TODO(jhawkins): Use FormManager once we have strict ordering of form
- // control elements in the cache.
- WebVector<WebFormElement> web_forms;
- frame->forms(web_forms);
-
- std::vector<FormData> forms;
- for (size_t i = 0; i < web_forms.size(); ++i) {
- const WebFormElement& web_form = web_forms[i];
-
- FormData form;
- if (FormManager::WebFormElementToFormData(
- web_form, FormManager::REQUIRE_NONE, false, &form))
- forms.push_back(form);
- }
-
- if (!forms.empty())
- Send(new ViewHostMsg_FormsSeen(routing_id_, forms));
-}
-
void RenderView::didChangeAccessibilityObjectState(
const WebKit::WebAccessibilityObject& acc_obj) {
#if defined(OS_WIN)
@@ -5058,38 +4922,6 @@ void RenderView::didChangeAccessibilityObjectState(
#endif
}
-void RenderView::SendPasswordForms(WebFrame* frame, bool only_visible) {
- // Make sure that this security origin is allowed to use password manager.
- WebSecurityOrigin security_origin = frame->securityOrigin();
- if (!security_origin.canAccessPasswordManager())
- return;
-
- WebVector<WebFormElement> forms;
- frame->forms(forms);
-
- std::vector<PasswordForm> password_forms;
- for (size_t i = 0; i < forms.size(); ++i) {
- const WebFormElement& form = forms[i];
-
- // Respect autocomplete=off.
- if (!form.autoComplete())
- continue;
- if (only_visible && !form.hasNonEmptyBoundingBox())
- continue;
- scoped_ptr<PasswordForm> password_form(
- PasswordFormDomManager::CreatePasswordForm(form));
- if (password_form.get())
- password_forms.push_back(*password_form);
- }
-
- if (password_forms.empty())
- return;
- if (only_visible)
- Send(new ViewHostMsg_PasswordFormsVisible(routing_id_, password_forms));
- else
- Send(new ViewHostMsg_PasswordFormsFound(routing_id_, password_forms));
-}
-
void RenderView::Print(WebFrame* frame, bool script_initiated) {
DCHECK(frame);
if (print_helper_.get() == NULL) {
@@ -5306,8 +5138,7 @@ void RenderView::OnPageTranslated() {
return;
// The page is translated, so try to extract the form data again.
- form_manager_.ExtractForms(frame);
- SendForms(frame);
+ autofill_helper_.FrameContentsAvailable(frame);
}
WebKit::WebGeolocationService* RenderView::geolocationService() {
@@ -5355,21 +5186,3 @@ bool RenderView::IsNonLocalTopLevelNavigation(
return false;
}
-void RenderView::QueryAutoFillFormData(const WebKit::WebNode& node,
- const WebKit::WebString& value,
- const WebKit::WebString& label,
- int unique_id,
- AutoFillAction action) {
- static int query_counter = 0;
- autofill_query_id_ = query_counter++;
-
- webkit_glue::FormData form;
- const WebInputElement element = node.toConst<WebInputElement>();
- if (!form_manager_.FindFormWithFormControlElement(
- element, FormManager::REQUIRE_NONE, &form))
- return;
-
- autofill_action_ = action;
- Send(new ViewHostMsg_FillAutoFillFormData(
- routing_id_, autofill_query_id_, form, value, label, unique_id));
-}
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 72bdad5..4974d1c 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -31,11 +31,11 @@
#include "chrome/common/renderer_preferences.h"
#include "chrome/common/translate_errors.h"
#include "chrome/common/view_types.h"
+#include "chrome/renderer/autofill_helper.h"
#include "chrome/renderer/automation/dom_automation_controller.h"
#include "chrome/renderer/dom_ui_bindings.h"
#include "chrome/renderer/extensions/extension_process_bindings.h"
#include "chrome/renderer/external_host_bindings.h"
-#include "chrome/renderer/form_manager.h"
#include "chrome/renderer/notification_provider.h"
#include "chrome/renderer/password_autocomplete_manager.h"
#include "chrome/renderer/pepper_plugin_delegate_impl.h"
@@ -603,18 +603,10 @@ class RenderView : public RenderWidget,
#endif
FRIEND_TEST(RenderViewTest, JSBlockSentAfterPageLoad);
FRIEND_TEST(RenderViewTest, UpdateTargetURLWithInvalidURL);
- FRIEND_TEST(RenderViewTest, SendForms);
- FRIEND_TEST(RenderViewTest, FillFormElement);
typedef std::map<GURL, ContentSettings> HostContentSettings;
typedef std::map<GURL, int> HostZoomLevels;
- enum AutoFillAction {
- AUTOFILL_NONE, // No state set.
- AUTOFILL_FILL, // Fill the AutoFill form data.
- AUTOFILL_PREVIEW, // Preview the AutoFill form data.
- };
-
enum ErrorPageType {
DNS_ERROR,
HTTP_404,
@@ -939,23 +931,6 @@ class RenderView : public RenderWidget,
void Print(WebKit::WebFrame* frame, bool script_initiated);
- // Queries the AutoFillManager for form data for the form containing |node|.
- // |value| is the current text in the field, and |unique_id| is the selected
- // profile's unique ID. |action| specifies whether to Fill or Preview the
- // values returned from the AutoFillManager.
- void QueryAutoFillFormData(const WebKit::WebNode& node,
- const WebKit::WebString& value,
- const WebKit::WebString& label,
- int unique_id,
- AutoFillAction action);
-
- // Scans the given frame for forms and sends them up to the browser.
- void SendForms(WebKit::WebFrame* frame);
-
- // Scans the given frame for password forms and sends them up to the browser.
- // If |only_visible| is true, only forms visible in the layout are sent
- void SendPasswordForms(WebKit::WebFrame* frame, bool only_visible);
-
// Returns whether the page associated with |document| is a candidate for
// translation. Some pages can explictly specify (via a meta-tag) that they
// should not be translated.
@@ -1173,25 +1148,6 @@ class RenderView : public RenderWidget,
// https://bugs.webkit.org/show_bug.cgi?id=32807.
base::RepeatingTimer<RenderView> preferred_size_change_timer_;
- // AutoFill ------------------------------------------------------------------
-
- // The id of the last request sent for form field AutoFill. Used to ignore
- // out of date responses.
- int autofill_query_id_;
-
- // The id of the node corresponding to the last request sent for form field
- // AutoFill.
- WebKit::WebNode autofill_query_node_;
-
- // The action to take when receiving AutoFill data from the AutoFillManager.
- AutoFillAction autofill_action_;
-
- // The menu index of the "Clear" menu item.
- int suggestions_clear_index_;
-
- // The menu index of the "AutoFill options..." menu item.
- int suggestions_options_index_;
-
// Plugins -------------------------------------------------------------------
// Remember the first uninstalled plugin, so that we can ask the plugin
@@ -1213,8 +1169,6 @@ class RenderView : public RenderWidget,
// Helper objects ------------------------------------------------------------
- FormManager form_manager_;
-
ScopedRunnableMethodFactory<RenderView> method_factory_;
// Responsible for translating the page contents to other languages.
@@ -1223,6 +1177,10 @@ class RenderView : public RenderWidget,
// Responsible for automatically filling login and password textfields.
PasswordAutocompleteManager password_autocomplete_manager_;
+ // Responsible for filling forms (AutoFill) and single text entries
+ // (Autocomplete).
+ AutoFillHelper autofill_helper_;
+
RendererWebCookieJarImpl cookie_jar_;
// Provides access to this renderer from the remote Inspector UI.