summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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.