summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/chrome_renderer.gypi2
-rw-r--r--chrome/renderer/autofill_helper.cc265
-rw-r--r--chrome/renderer/autofill_helper.h119
-rw-r--r--chrome/renderer/device_orientation_dispatcher.cc10
-rw-r--r--chrome/renderer/device_orientation_dispatcher.h16
-rw-r--r--chrome/renderer/devtools_agent.cc55
-rw-r--r--chrome/renderer/devtools_agent.h35
-rw-r--r--chrome/renderer/devtools_client.cc38
-rw-r--r--chrome/renderer/devtools_client.h18
-rw-r--r--chrome/renderer/geolocation_dispatcher.cc20
-rw-r--r--chrome/renderer/geolocation_dispatcher.h13
-rw-r--r--chrome/renderer/notification_provider.cc36
-rw-r--r--chrome/renderer/notification_provider.h29
-rw-r--r--chrome/renderer/page_click_tracker.cc59
-rw-r--r--chrome/renderer/page_click_tracker.h33
-rw-r--r--chrome/renderer/page_click_tracker_unittest.cc12
-rw-r--r--chrome/renderer/password_autocomplete_manager.cc98
-rw-r--r--chrome/renderer/password_autocomplete_manager.h38
-rw-r--r--chrome/renderer/password_autocomplete_manager_unittest.cc17
-rw-r--r--chrome/renderer/render_view.cc348
-rw-r--r--chrome/renderer/render_view.h127
-rw-r--r--chrome/renderer/render_view_browsertest.cc27
-rw-r--r--chrome/renderer/render_view_observer.cc33
-rw-r--r--chrome/renderer/render_view_observer.h63
-rw-r--r--chrome/renderer/speech_input_dispatcher.cc17
-rw-r--r--chrome/renderer/speech_input_dispatcher.h16
-rw-r--r--chrome/test/render_view_test.cc17
-rw-r--r--chrome/test/render_view_test.h5
28 files changed, 772 insertions, 794 deletions
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index ebbd838..f1b33f6 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -164,6 +164,8 @@
'renderer/render_view.cc',
'renderer/render_view_linux.cc',
'renderer/render_view.h',
+ 'renderer/render_view_observer.cc',
+ 'renderer/render_view_observer.h',
'renderer/render_widget.cc',
'renderer/render_widget.h',
'renderer/render_widget_fullscreen.cc',
diff --git a/chrome/renderer/autofill_helper.cc b/chrome/renderer/autofill_helper.cc
index b383504..a429577 100644
--- a/chrome/renderer/autofill_helper.cc
+++ b/chrome/renderer/autofill_helper.cc
@@ -7,7 +7,9 @@
#include "app/l10n_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_constants.h"
+#include "chrome/common/render_messages.h"
#include "chrome/renderer/form_manager.h"
+#include "chrome/renderer/password_autocomplete_manager.h"
#include "chrome/renderer/render_view.h"
#include "grit/generated_resources.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h"
@@ -36,34 +38,168 @@ const size_t kMaximumTextSizeForAutoFill = 1000;
} // namespace
-AutoFillHelper::AutoFillHelper(RenderView* render_view)
- : render_view_(render_view),
+AutoFillHelper::AutoFillHelper(
+ RenderView* render_view,
+ PasswordAutocompleteManager* password_autocomplete_manager)
+ : RenderViewObserver(render_view),
+ password_autocomplete_manager_(password_autocomplete_manager),
autofill_query_id_(0),
autofill_action_(AUTOFILL_NONE),
display_warning_if_disabled_(false),
was_query_node_autofilled_(false),
suggestions_clear_index_(-1),
- suggestions_options_index_(-1) {
+ suggestions_options_index_(-1),
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
}
-void AutoFillHelper::RemoveAutocompleteSuggestion(const WebString& name,
- const WebString& value) {
+bool AutoFillHelper::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(AutoFillHelper, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_AutoFillSuggestionsReturned,
+ OnSuggestionsReturned)
+ IPC_MESSAGE_HANDLER(ViewMsg_AutoFillFormDataFilled, OnFormDataFilled)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void AutoFillHelper::DidFinishDocumentLoad(WebKit::WebFrame* frame) {
+ // The document has now been fully loaded. Scan for forms to be sent up to
+ // the browser.
+ form_manager_.ExtractForms(frame);
+ SendForms(frame);
+}
+
+void AutoFillHelper::FrameDetached(WebKit::WebFrame* frame) {
+ form_manager_.ResetFrame(frame);
+}
+
+void AutoFillHelper::FrameWillClose(WebKit::WebFrame* frame) {
+ form_manager_.ResetFrame(frame);
+}
+
+void AutoFillHelper::FrameTranslated(WebKit::WebFrame* frame) {
+ // The page is translated, so try to extract the form data again.
+ DidFinishDocumentLoad(frame);
+}
+
+bool AutoFillHelper::InputElementClicked(const WebInputElement& element,
+ bool was_focused,
+ bool is_focused) {
+ if (was_focused)
+ ShowSuggestions(element, true, false, true);
+ return false;
+}
+
+void AutoFillHelper::didAcceptAutoFillSuggestion(const WebKit::WebNode& node,
+ const WebKit::WebString& value,
+ 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'.
+ form_manager_.ClearFormWithNode(node);
+ } else if (!unique_id) {
+ // User selected an Autocomplete entry, so we fill directly.
+ WebInputElement element = node.toConst<WebInputElement>();
+
+ string16 substring = value;
+ substring = substring.substr(0, element.maxLength());
+ element.setValue(substring);
+
+ WebFrame* webframe = node.document().frame();
+ if (webframe)
+ webframe->notifiyPasswordListenerOfAutocomplete(element);
+ } else {
+ // Fill the values for the whole form.
+ FillAutoFillFormData(node, unique_id, AUTOFILL_FILL);
+ }
+
+ suggestions_clear_index_ = -1;
+ suggestions_options_index_ = -1;
+}
+
+void AutoFillHelper::didSelectAutoFillSuggestion(const WebKit::WebNode& node,
+ const WebKit::WebString& value,
+ const WebKit::WebString& label,
+ int unique_id) {
+ DCHECK_GE(unique_id, 0);
+
+ didClearAutoFillSelection(node);
+ FillAutoFillFormData(node, unique_id, AUTOFILL_PREVIEW);
+}
+
+void AutoFillHelper::didClearAutoFillSelection(const WebKit::WebNode& node) {
+ form_manager_.ClearPreviewedFormWithNode(node, was_query_node_autofilled_);
+}
+
+void AutoFillHelper::didAcceptAutocompleteSuggestion(
+ const WebKit::WebInputElement& user_element) {
+ bool result = password_autocomplete_manager_->FillPassword(user_element);
+ // Since this user name was selected from a suggestion list, we should always
+ // have password for it.
+ DCHECK(result);
+}
+
+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));
+ Send(new ViewHostMsg_RemoveAutocompleteEntry(routing_id(), name, value));
+}
+
+void AutoFillHelper::textFieldDidEndEditing(
+ const WebKit::WebInputElement& element) {
+ password_autocomplete_manager_->TextFieldDidEndEditing(element);
+}
+
+void AutoFillHelper::textFieldDidChange(
+ const WebKit::WebInputElement& element) {
+ // We post a task for doing the AutoFill as the caret position is not set
+ // properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976) and
+ // it is needed to trigger autofill.
+ method_factory_.RevokeAll();
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &AutoFillHelper::TextFieldDidChangeImpl, element));
+}
+
+void AutoFillHelper::TextFieldDidChangeImpl(
+ const WebKit::WebInputElement& element) {
+ if (password_autocomplete_manager_->TextDidChangeInTextField(element))
+ return;
+
+ ShowSuggestions(element, false, true, false);
+}
+
+void AutoFillHelper::textFieldDidReceiveKeyDown(
+ const WebKit::WebInputElement& element,
+ const WebKit::WebKeyboardEvent& event) {
+ password_autocomplete_manager_->TextFieldHandlingKeyDown(element, event);
+
+ if (event.windowsKeyCode == ui::VKEY_DOWN ||
+ event.windowsKeyCode == ui::VKEY_UP)
+ ShowSuggestions(element, true, true, true);
}
-void AutoFillHelper::SuggestionsReceived(int query_id,
- const std::vector<string16>& values,
- const std::vector<string16>& labels,
- const std::vector<string16>& icons,
- const std::vector<int>& unique_ids) {
- WebKit::WebView* web_view = render_view_->webview();
+void AutoFillHelper::OnSuggestionsReturned(
+ int query_id,
+ const std::vector<string16>& values,
+ const std::vector<string16>& labels,
+ const std::vector<string16>& icons,
+ const std::vector<int>& unique_ids) {
+ WebKit::WebView* web_view = render_view()->webview();
if (!web_view || query_id != autofill_query_id_)
return;
@@ -131,13 +267,12 @@ void AutoFillHelper::SuggestionsReceived(int query_id,
autofill_query_node_, v, l, i, ids, separator_index);
}
- render_view_->Send(new ViewHostMsg_DidShowAutoFillSuggestions(
- render_view_->routing_id()));
+ Send(new ViewHostMsg_DidShowAutoFillSuggestions(routing_id()));
}
-void AutoFillHelper::FormDataFilled(int query_id,
- const webkit_glue::FormData& form) {
- if (!render_view_->webview() || query_id != autofill_query_id_)
+void AutoFillHelper::OnFormDataFilled(
+ int query_id, const webkit_glue::FormData& form) {
+ if (!render_view()->webview() || query_id != autofill_query_id_)
return;
switch (autofill_action_) {
@@ -151,85 +286,7 @@ void AutoFillHelper::FormDataFilled(int query_id,
NOTREACHED();
}
autofill_action_ = AUTOFILL_NONE;
- render_view_->Send(new ViewHostMsg_DidFillAutoFillFormData(
- render_view_->routing_id()));
-}
-
-void AutoFillHelper::DidSelectAutoFillSuggestion(const WebNode& node,
- int unique_id) {
- DCHECK_GE(unique_id, 0);
-
- DidClearAutoFillSelection(node);
- FillAutoFillFormData(node, unique_id, AUTOFILL_PREVIEW);
-}
-
-void AutoFillHelper::DidAcceptAutoFillSuggestion(const WebNode& node,
- const WebString& value,
- 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'.
- form_manager_.ClearFormWithNode(node);
- } else if (!unique_id) {
- // User selected an Autocomplete entry, so we fill directly.
- WebInputElement element = node.toConst<WebInputElement>();
-
- string16 substring = value;
- substring = substring.substr(0, element.maxLength());
- element.setValue(substring);
-
- WebFrame* webframe = node.document().frame();
- if (webframe)
- webframe->notifiyPasswordListenerOfAutocomplete(element);
- } else {
- // Fill the values for the whole form.
- FillAutoFillFormData(node, unique_id, AUTOFILL_FILL);
- }
-
- suggestions_clear_index_ = -1;
- suggestions_options_index_ = -1;
-}
-
-void AutoFillHelper::DidClearAutoFillSelection(const WebNode& node) {
- form_manager_.ClearPreviewedFormWithNode(node, was_query_node_autofilled_);
-}
-
-void AutoFillHelper::FrameContentsAvailable(WebFrame* frame) {
- form_manager_.ExtractForms(frame);
- SendForms(frame);
-}
-
-void AutoFillHelper::FrameWillClose(WebFrame* frame) {
- form_manager_.ResetFrame(frame);
-}
-
-void AutoFillHelper::FrameDetached(WebFrame* frame) {
- form_manager_.ResetFrame(frame);
-}
-
-void AutoFillHelper::TextDidChangeInTextField(const WebInputElement& element) {
- ShowSuggestions(element, false, true, false);
-}
-
-void AutoFillHelper::KeyDownInTextField(const WebInputElement& element,
- const WebKeyboardEvent& event) {
- if (event.windowsKeyCode == ui::VKEY_DOWN ||
- event.windowsKeyCode == ui::VKEY_UP)
- ShowSuggestions(element, true, true, true);
-}
-
-bool AutoFillHelper::InputElementClicked(const WebInputElement& element,
- bool was_focused,
- bool is_focused) {
- if (was_focused)
- ShowSuggestions(element, true, false, true);
- return false;
+ Send(new ViewHostMsg_DidFillAutoFillFormData(routing_id()));
}
void AutoFillHelper::ShowSuggestions(const WebInputElement& element,
@@ -273,8 +330,8 @@ void AutoFillHelper::QueryAutoFillSuggestions(
if (!FindFormAndFieldForNode(node, &form, &field))
return;
- render_view_->Send(new ViewHostMsg_QueryFormFieldAutoFill(
- render_view_->routing_id(), autofill_query_id_, form, field));
+ Send(new ViewHostMsg_QueryFormFieldAutoFill(
+ routing_id(), autofill_query_id_, form, field));
}
void AutoFillHelper::FillAutoFillFormData(const WebNode& node,
@@ -290,8 +347,8 @@ void AutoFillHelper::FillAutoFillFormData(const WebNode& node,
autofill_action_ = action;
was_query_node_autofilled_ = field.is_autofilled();
- render_view_->Send(new ViewHostMsg_FillAutoFillFormData(
- render_view_->routing_id(), autofill_query_id_, form, field, unique_id));
+ Send(new ViewHostMsg_FillAutoFillFormData(
+ routing_id(), autofill_query_id_, form, field, unique_id));
}
void AutoFillHelper::SendForms(WebFrame* frame) {
@@ -312,10 +369,8 @@ void AutoFillHelper::SendForms(WebFrame* frame) {
}
}
- if (!forms.empty()) {
- render_view_->Send(new ViewHostMsg_FormsSeen(render_view_->routing_id(),
- forms));
- }
+ if (!forms.empty())
+ Send(new ViewHostMsg_FormsSeen(routing_id(), forms));
}
bool AutoFillHelper::FindFormAndFieldForNode(const WebNode& node,
diff --git a/chrome/renderer/autofill_helper.h b/chrome/renderer/autofill_helper.h
index c948bcf..d639bd1 100644
--- a/chrome/renderer/autofill_helper.h
+++ b/chrome/renderer/autofill_helper.h
@@ -10,17 +10,14 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/task.h"
#include "chrome/renderer/form_manager.h"
#include "chrome/renderer/page_click_listener.h"
+#include "chrome/renderer/render_view_observer.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebAutoFillClient.h"
#include "third_party/WebKit/WebKit/chromium/public/WebNode.h"
-class RenderView;
-
-namespace WebKit {
-class WebInputElement;
-class WebKeyboardEvent;
-class WebString;
-}
+class PasswordAutocompleteManager;
// AutoFillHelper deals with AutoFill related communications between WebKit and
// the browser. There is one AutofillHelper per RenderView.
@@ -29,63 +26,34 @@ class WebString;
// - single text field suggestions, that we usually refer to as Autocomplete
// - entire form fill based on one field entry, referred to as form AutoFill.
-class AutoFillHelper : public PageClickListener {
+class AutoFillHelper : public RenderViewObserver,
+ public PageClickListener,
+ public WebKit::WebAutoFillClient {
public:
- explicit AutoFillHelper(RenderView* render_view);
-
- // Removes the Autocomplete suggestion |value| for the field named |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<string16>& icons,
- 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,
- 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,
- 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 opportunity to clean up.
- // DEPRECATED.
- void FrameWillClose(WebKit::WebFrame* frame);
-
- // Called when |frame| is detached from the view. Gives us an opportunity to
- // clean up.
- void FrameDetached(WebKit::WebFrame* frame);
-
- // WebViewClient editor call forwarded by the RenderView.
- void TextDidChangeInTextField(const WebKit::WebInputElement& element);
-
- // WebViewClient editor call forwarded by the RenderView. For lower level
- // event translation. Specifically, for down/up key presses in an input
- // element.
- void KeyDownInTextField(const WebKit::WebInputElement& element,
- const WebKit::WebKeyboardEvent& event);
+ // PasswordAutocompleteManager is guaranteed to outlive AutoFillHelper.
+ AutoFillHelper(RenderView* render_view,
+ PasswordAutocompleteManager* password_autocomplete_manager);
+
+ // WebKit::WebAutoFillClient implementation. Public for tests.
+ virtual void didAcceptAutoFillSuggestion(const WebKit::WebNode& node,
+ const WebKit::WebString& value,
+ const WebKit::WebString& label,
+ int unique_id,
+ unsigned index);
+ virtual void didSelectAutoFillSuggestion(const WebKit::WebNode& node,
+ const WebKit::WebString& value,
+ const WebKit::WebString& label,
+ int unique_id);
+ virtual void didClearAutoFillSelection(const WebKit::WebNode& node);
+ virtual void didAcceptAutocompleteSuggestion(
+ const WebKit::WebInputElement& element);
+ virtual void removeAutocompleteSuggestion(const WebKit::WebString& name,
+ const WebKit::WebString& value);
+ virtual void textFieldDidEndEditing(const WebKit::WebInputElement& element);
+ virtual void textFieldDidChange(const WebKit::WebInputElement& element);
+ virtual void textFieldDidReceiveKeyDown(
+ const WebKit::WebInputElement& element,
+ const WebKit::WebKeyboardEvent& event);
private:
enum AutoFillAction {
@@ -94,11 +62,29 @@ class AutoFillHelper : public PageClickListener {
AUTOFILL_PREVIEW, // Preview the AutoFill form data.
};
+ // RenderView::Observer implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message);
+ virtual void DidFinishDocumentLoad(WebKit::WebFrame* frame);
+ virtual void FrameDetached(WebKit::WebFrame* frame);
+ virtual void FrameWillClose(WebKit::WebFrame* frame);
+ virtual void FrameTranslated(WebKit::WebFrame* frame);
+
// PageClickListener implementation:
virtual bool InputElementClicked(const WebKit::WebInputElement& element,
bool was_focused,
bool is_focused);
+ void OnSuggestionsReturned(int query_id,
+ const std::vector<string16>& values,
+ const std::vector<string16>& labels,
+ const std::vector<string16>& icons,
+ const std::vector<int>& unique_ids);
+ void OnFormDataFilled(int query_id, const webkit_glue::FormData& form);
+
+ // Called in a posted task by textFieldDidChange() to work-around a WebKit bug
+ // http://bugs.webkit.org/show_bug.cgi?id=16976
+ void TextFieldDidChangeImpl(const WebKit::WebInputElement& element);
+
// Shows the autocomplete suggestions for |element|.
// This call is asynchronous and may or may not lead to the showing of a
// suggestion popup (no popup is shown if there are no available suggestions).
@@ -138,11 +124,10 @@ class AutoFillHelper : public PageClickListener {
webkit_glue::FormData* form,
webkit_glue::FormField* field) WARN_UNUSED_RESULT;
- // Weak reference.
- RenderView* render_view_;
-
FormManager form_manager_;
+ PasswordAutocompleteManager* password_autocomplete_manager_;
+
// The ID of the last request sent for form field AutoFill. Used to ignore
// out of date responses.
int autofill_query_id_;
@@ -165,6 +150,8 @@ class AutoFillHelper : public PageClickListener {
// The menu index of the "AutoFill options..." menu item.
int suggestions_options_index_;
+ ScopedRunnableMethodFactory<AutoFillHelper> method_factory_;
+
DISALLOW_COPY_AND_ASSIGN(AutoFillHelper);
};
diff --git a/chrome/renderer/device_orientation_dispatcher.cc b/chrome/renderer/device_orientation_dispatcher.cc
index edf9d03..d5e443d 100644
--- a/chrome/renderer/device_orientation_dispatcher.cc
+++ b/chrome/renderer/device_orientation_dispatcher.cc
@@ -4,14 +4,14 @@
#include "chrome/renderer/device_orientation_dispatcher.h"
+#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
-#include "chrome/renderer/render_view.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDeviceOrientation.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDeviceOrientationController.h"
DeviceOrientationDispatcher::DeviceOrientationDispatcher(
RenderView* render_view)
- : render_view_(render_view),
+ : RenderViewObserver(render_view),
controller_(NULL),
started_(false) {
}
@@ -37,14 +37,12 @@ void DeviceOrientationDispatcher::setController(
}
void DeviceOrientationDispatcher::startUpdating() {
- render_view_->Send(new ViewHostMsg_DeviceOrientation_StartUpdating(
- render_view_->routing_id()));
+ Send(new ViewHostMsg_DeviceOrientation_StartUpdating(routing_id()));
started_ = true;
}
void DeviceOrientationDispatcher::stopUpdating() {
- render_view_->Send(new ViewHostMsg_DeviceOrientation_StopUpdating(
- render_view_->routing_id()));
+ Send(new ViewHostMsg_DeviceOrientation_StopUpdating(routing_id()));
started_ = false;
}
diff --git a/chrome/renderer/device_orientation_dispatcher.h b/chrome/renderer/device_orientation_dispatcher.h
index 88c1ef5..d60a470 100644
--- a/chrome/renderer/device_orientation_dispatcher.h
+++ b/chrome/renderer/device_orientation_dispatcher.h
@@ -8,21 +8,21 @@
#include "third_party/WebKit/WebKit/chromium/public/WebDeviceOrientationClient.h"
#include "base/scoped_ptr.h"
-#include "ipc/ipc_channel.h"
+#include "chrome/renderer/render_view_observer.h"
-class RenderView;
namespace WebKit { class WebDeviceOrientation; }
struct ViewMsg_DeviceOrientationUpdated_Params;
-class DeviceOrientationDispatcher : public WebKit::WebDeviceOrientationClient,
- public IPC::Channel::Listener {
+class DeviceOrientationDispatcher : public RenderViewObserver,
+ public WebKit::WebDeviceOrientationClient {
public:
- explicit DeviceOrientationDispatcher(RenderView* render_view);
+ DeviceOrientationDispatcher(RenderView* render_view);
virtual ~DeviceOrientationDispatcher();
- // IPC::Channel::Implementation.
- bool OnMessageReceived(const IPC::Message& msg);
+ private:
+ // RenderView::Observer implementation.
+ bool OnMessageReceived(const IPC::Message& message);
// From WebKit::WebDeviceOrientationClient.
virtual void setController(
@@ -31,11 +31,9 @@ class DeviceOrientationDispatcher : public WebKit::WebDeviceOrientationClient,
virtual void stopUpdating();
virtual WebKit::WebDeviceOrientation lastOrientation() const;
- private:
void OnDeviceOrientationUpdated(
const ViewMsg_DeviceOrientationUpdated_Params& p);
- RenderView* render_view_;
scoped_ptr<WebKit::WebDeviceOrientationController> controller_;
scoped_ptr<WebKit::WebDeviceOrientation> last_orientation_;
bool started_;
diff --git a/chrome/renderer/devtools_agent.cc b/chrome/renderer/devtools_agent.cc
index ca1ef3a..1d88a4d 100644
--- a/chrome/renderer/devtools_agent.cc
+++ b/chrome/renderer/devtools_agent.cc
@@ -53,24 +53,16 @@ class WebKitClientMessageLoopImpl
// static
std::map<int, DevToolsAgent*> DevToolsAgent::agent_for_routing_id_;
-DevToolsAgent::DevToolsAgent(int routing_id, RenderView* render_view)
- : routing_id_(routing_id),
- render_view_(render_view) {
- agent_for_routing_id_[routing_id] = this;
+DevToolsAgent::DevToolsAgent(RenderView* render_view)
+ : RenderViewObserver(render_view) {
+ agent_for_routing_id_[routing_id()] = this;
CommandLine* cmd = CommandLine::ForCurrentProcess();
- expose_v8_debugger_protocol_ =cmd->HasSwitch(switches::kRemoteShellPort);
+ expose_v8_debugger_protocol_ = cmd->HasSwitch(switches::kRemoteShellPort);
}
DevToolsAgent::~DevToolsAgent() {
- agent_for_routing_id_.erase(routing_id_);
-}
-
-void DevToolsAgent::OnNavigate() {
- WebDevToolsAgent* web_agent = GetWebAgent();
- if (web_agent) {
- web_agent->didNavigate();
- }
+ agent_for_routing_id_.erase(routing_id());
}
// Called on the Renderer thread.
@@ -85,33 +77,35 @@ bool DevToolsAgent::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(DevToolsAgentMsg_InspectElement, OnInspectElement)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
+
+ if (message.type() == ViewMsg_Navigate::ID)
+ OnNavigate(); // Don't want to swallow the message.
+
return handled;
}
void DevToolsAgent::sendMessageToInspectorFrontend(
const WebKit::WebString& message) {
- IPC::Message* m = new ViewHostMsg_ForwardToDevToolsClient(
- routing_id_,
- DevToolsClientMsg_DispatchOnInspectorFrontend(message.utf8()));
- render_view_->Send(m);
+ Send(new ViewHostMsg_ForwardToDevToolsClient(
+ routing_id(),
+ DevToolsClientMsg_DispatchOnInspectorFrontend(message.utf8())));
}
void DevToolsAgent::sendDebuggerOutput(const WebKit::WebString& data) {
- IPC::Message* m = new ViewHostMsg_ForwardToDevToolsClient(
- routing_id_,
- DevToolsClientMsg_DebuggerOutput(data.utf8()));
- render_view_->Send(m);
+ Send(new ViewHostMsg_ForwardToDevToolsClient(
+ routing_id(),
+ DevToolsClientMsg_DebuggerOutput(data.utf8())));
}
int DevToolsAgent::hostIdentifier() {
- return routing_id_;
+ return routing_id();
}
void DevToolsAgent::runtimeFeatureStateChanged(
const WebKit::WebString& feature,
bool enabled) {
- render_view_->Send(new ViewHostMsg_DevToolsRuntimePropertyChanged(
- routing_id_,
+ Send(new ViewHostMsg_DevToolsRuntimePropertyChanged(
+ routing_id(),
feature.utf8(),
enabled ? "true" : "false"));
}
@@ -119,8 +113,8 @@ void DevToolsAgent::runtimeFeatureStateChanged(
void DevToolsAgent::runtimePropertyChanged(
const WebKit::WebString& name,
const WebKit::WebString& value) {
- render_view_->Send(new ViewHostMsg_DevToolsRuntimePropertyChanged(
- routing_id_,
+ Send(new ViewHostMsg_DevToolsRuntimePropertyChanged(
+ routing_id(),
name.utf8(),
value.utf8()));
}
@@ -191,8 +185,15 @@ void DevToolsAgent::OnInspectElement(int x, int y) {
}
}
+void DevToolsAgent::OnNavigate() {
+ WebDevToolsAgent* web_agent = GetWebAgent();
+ if (web_agent) {
+ web_agent->didNavigate();
+ }
+}
+
WebDevToolsAgent* DevToolsAgent::GetWebAgent() {
- WebView* web_view = render_view_->webview();
+ WebView* web_view = render_view()->webview();
if (!web_view)
return NULL;
return web_view->devToolsAgent();
diff --git a/chrome/renderer/devtools_agent.h b/chrome/renderer/devtools_agent.h
index 4b1b465..8f0f7f4 100644
--- a/chrome/renderer/devtools_agent.h
+++ b/chrome/renderer/devtools_agent.h
@@ -11,29 +11,34 @@
#include "base/basictypes.h"
#include "chrome/common/devtools_messages.h"
-#include "ipc/ipc_channel.h"
+#include "chrome/renderer/render_view_observer.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDevToolsAgentClient.h"
namespace WebKit {
class WebDevToolsAgent;
}
-class RenderView;
struct DevToolsMessageData;
// DevToolsAgent belongs to the inspectable RenderView and provides Glue's
// agents with the communication capabilities. All messages from/to Glue's
-// agents infrastructure are flowing through this comminucation agent.
+// agents infrastructure are flowing through this communication agent.
// There is a corresponding DevToolsClient object on the client side.
-class DevToolsAgent : public WebKit::WebDevToolsAgentClient,
- public IPC::Channel::Listener {
+class DevToolsAgent : public RenderViewObserver,
+ public WebKit::WebDevToolsAgentClient {
public:
- DevToolsAgent(int routing_id, RenderView* view);
+ explicit DevToolsAgent(RenderView* render_view);
virtual ~DevToolsAgent();
- void OnNavigate();
+ // Returns agent instance for its host id.
+ static DevToolsAgent* FromHostId(int host_id);
+
+ WebKit::WebDevToolsAgent* GetWebAgent();
- // IPC::Channel::Listener implementation.
+ private:
+ friend class DevToolsAgentFilter;
+
+ // RenderView::Observer implementation.
virtual bool OnMessageReceived(const IPC::Message& message);
// WebDevToolsAgentClient implementation
@@ -50,26 +55,16 @@ class DevToolsAgent : public WebKit::WebDevToolsAgentClient,
createClientMessageLoop();
virtual bool exposeV8DebuggerProtocol();
- // Returns agent instance for its host id.
- static DevToolsAgent* FromHostId(int host_id);
-
- RenderView* render_view() { return render_view_; }
-
- WebKit::WebDevToolsAgent* GetWebAgent();
-
- private:
- friend class DevToolsAgentFilter;
-
void OnAttach(const DevToolsRuntimeProperties& runtime_properties);
void OnDetach();
void OnFrontendLoaded();
void OnDispatchOnInspectorBackend(const std::string& message);
void OnInspectElement(int x, int y);
+ void OnSetApuAgentEnabled(bool enabled);
+ void OnNavigate();
static std::map<int, DevToolsAgent*> agent_for_routing_id_;
- int routing_id_; // View routing id that we can access from IO thread.
- RenderView* render_view_;
bool expose_v8_debugger_protocol_;
DISALLOW_COPY_AND_ASSIGN(DevToolsAgent);
diff --git a/chrome/renderer/devtools_client.cc b/chrome/renderer/devtools_client.cc
index eea0b46..1f14035 100644
--- a/chrome/renderer/devtools_client.cc
+++ b/chrome/renderer/devtools_client.cc
@@ -18,12 +18,12 @@
using WebKit::WebDevToolsFrontend;
using WebKit::WebString;
-DevToolsClient::DevToolsClient(RenderView* view)
- : render_view_(view) {
+DevToolsClient::DevToolsClient(RenderView* render_view)
+ : RenderViewObserver(render_view) {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
web_tools_frontend_.reset(
WebDevToolsFrontend::create(
- view->webview(),
+ render_view->webview(),
this,
ASCIIToUTF16(command_line.GetSwitchValueASCII(switches::kLang))));
}
@@ -31,10 +31,9 @@ DevToolsClient::DevToolsClient(RenderView* view)
DevToolsClient::~DevToolsClient() {
}
-void DevToolsClient::Send(const IPC::Message& tools_agent_message) {
- render_view_->Send(new ViewHostMsg_ForwardToDevToolsAgent(
- render_view_->routing_id(),
- tools_agent_message));
+void DevToolsClient::SendToAgent(const IPC::Message& tools_agent_message) {
+ Send(new ViewHostMsg_ForwardToDevToolsAgent(
+ routing_id(), tools_agent_message));
}
bool DevToolsClient::OnMessageReceived(const IPC::Message& message) {
@@ -51,41 +50,36 @@ bool DevToolsClient::OnMessageReceived(const IPC::Message& message) {
}
void DevToolsClient::sendFrontendLoaded() {
- Send(DevToolsAgentMsg_FrontendLoaded());
+ SendToAgent(DevToolsAgentMsg_FrontendLoaded());
}
void DevToolsClient::sendMessageToBackend(const WebString& message) {
- Send(DevToolsAgentMsg_DispatchOnInspectorBackend(message.utf8()));
+ SendToAgent(DevToolsAgentMsg_DispatchOnInspectorBackend(message.utf8()));
}
void DevToolsClient::sendDebuggerCommandToAgent(const WebString& command) {
- Send(DevToolsAgentMsg_DebuggerCommand(command.utf8()));
+ SendToAgent(DevToolsAgentMsg_DebuggerCommand(command.utf8()));
}
void DevToolsClient::activateWindow() {
- render_view_->Send(new ViewHostMsg_ActivateDevToolsWindow(
- render_view_->routing_id()));
+ Send(new ViewHostMsg_ActivateDevToolsWindow(routing_id()));
}
void DevToolsClient::closeWindow() {
- render_view_->Send(new ViewHostMsg_CloseDevToolsWindow(
- render_view_->routing_id()));
+ Send(new ViewHostMsg_CloseDevToolsWindow(routing_id()));
}
void DevToolsClient::requestDockWindow() {
- render_view_->Send(new ViewHostMsg_RequestDockDevToolsWindow(
- render_view_->routing_id()));
+ Send(new ViewHostMsg_RequestDockDevToolsWindow(routing_id()));
}
void DevToolsClient::requestUndockWindow() {
- render_view_->Send(new ViewHostMsg_RequestUndockDevToolsWindow(
- render_view_->routing_id()));
+ Send(new ViewHostMsg_RequestUndockDevToolsWindow(routing_id()));
}
-void DevToolsClient::OnDispatchOnInspectorFrontend(
- const std::string& message) {
- web_tools_frontend_->dispatchOnInspectorFrontend(
- WebString::fromUTF8(message));
+void DevToolsClient::OnDispatchOnInspectorFrontend(const std::string& message) {
+ web_tools_frontend_->dispatchOnInspectorFrontend(
+ WebString::fromUTF8(message));
}
bool DevToolsClient::shouldHideScriptsPanel() {
diff --git a/chrome/renderer/devtools_client.h b/chrome/renderer/devtools_client.h
index 463dc35..fbd7ccc 100644
--- a/chrome/renderer/devtools_client.h
+++ b/chrome/renderer/devtools_client.h
@@ -10,11 +10,10 @@
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
-#include "ipc/ipc_channel.h"
+#include "chrome/renderer/render_view_observer.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDevToolsFrontendClient.h"
class MessageLoop;
-class RenderView;
namespace WebKit {
class WebDevToolsFrontend;
@@ -29,14 +28,15 @@ struct DevToolsMessageData;
// corresponding DevToolsAgent object.
// TODO(yurys): now the client is almost empty later it will delegate calls to
// code in glue
-class DevToolsClient : public WebKit::WebDevToolsFrontendClient,
- public IPC::Channel::Listener {
+class DevToolsClient : public RenderViewObserver,
+ public WebKit::WebDevToolsFrontendClient {
public:
- explicit DevToolsClient(RenderView* view);
+ explicit DevToolsClient(RenderView* render_view);
virtual ~DevToolsClient();
- // IPC::Channel::Listener implementation.
- bool OnMessageReceived(const IPC::Message& message);
+ private:
+ // RenderView::Observer implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message);
// WebDevToolsFrontendClient implementation
virtual void sendFrontendLoaded();
@@ -50,13 +50,11 @@ class DevToolsClient : public WebKit::WebDevToolsFrontendClient,
virtual bool shouldHideScriptsPanel();
- private:
void OnDispatchOnInspectorFrontend(const std::string& message);
// Sends message to DevToolsAgent.
- void Send(const IPC::Message& tools_agent_message);
+ void SendToAgent(const IPC::Message& tools_agent_message);
- RenderView* render_view_; // host render view
scoped_ptr<WebKit::WebDevToolsFrontend> web_tools_frontend_;
DISALLOW_COPY_AND_ASSIGN(DevToolsClient);
diff --git a/chrome/renderer/geolocation_dispatcher.cc b/chrome/renderer/geolocation_dispatcher.cc
index aefc346..c6aa51b 100644
--- a/chrome/renderer/geolocation_dispatcher.cc
+++ b/chrome/renderer/geolocation_dispatcher.cc
@@ -4,8 +4,7 @@
#include "chrome/renderer/geolocation_dispatcher.h"
-#include "chrome/renderer/render_view.h"
-#include "ipc/ipc_message.h"
+#include "chrome/common/render_messages.h"
#include "third_party/WebKit/WebKit/chromium/public/WebGeolocationPermissionRequest.h"
#include "third_party/WebKit/WebKit/chromium/public/WebGeolocationPermissionRequestManager.h"
#include "third_party/WebKit/WebKit/chromium/public/WebGeolocationClient.h"
@@ -16,7 +15,7 @@
using namespace WebKit;
GeolocationDispatcher::GeolocationDispatcher(RenderView* render_view)
- : render_view_(render_view),
+ : RenderViewObserver(render_view),
pending_permissions_(new WebGeolocationPermissionRequestManager()),
enable_high_accuracy_(false),
updating_(false) {
@@ -43,14 +42,13 @@ void GeolocationDispatcher::geolocationDestroyed() {
void GeolocationDispatcher::startUpdating() {
GURL url;
- render_view_->Send(new ViewHostMsg_Geolocation_StartUpdating(
- render_view_->routing_id(), url, enable_high_accuracy_));
+ Send(new ViewHostMsg_Geolocation_StartUpdating(
+ routing_id(), url, enable_high_accuracy_));
updating_ = true;
}
void GeolocationDispatcher::stopUpdating() {
- render_view_->Send(new ViewHostMsg_Geolocation_StopUpdating(
- render_view_->routing_id()));
+ Send(new ViewHostMsg_Geolocation_StopUpdating(routing_id()));
updating_ = false;
}
@@ -85,8 +83,8 @@ void GeolocationDispatcher::requestPermission(
const WebGeolocationPermissionRequest& permissionRequest) {
int bridge_id = pending_permissions_->add(permissionRequest);
string16 origin = permissionRequest.securityOrigin().toString();
- render_view_->Send(new ViewHostMsg_Geolocation_RequestPermission(
- render_view_->routing_id(), bridge_id, GURL(origin)));
+ Send(new ViewHostMsg_Geolocation_RequestPermission(
+ routing_id(), bridge_id, GURL(origin)));
}
// TODO(jknotten): Change the messages to use a security origin, so no
@@ -97,8 +95,8 @@ void GeolocationDispatcher::cancelPermissionRequest(
if (!pending_permissions_->remove(permissionRequest, bridge_id))
return;
string16 origin = permissionRequest.securityOrigin().toString();
- render_view_->Send(new ViewHostMsg_Geolocation_CancelPermissionRequest(
- render_view_->routing_id(), bridge_id, GURL(origin)));
+ Send(new ViewHostMsg_Geolocation_CancelPermissionRequest(
+ routing_id(), bridge_id, GURL(origin)));
}
// Permission for using geolocation has been set.
diff --git a/chrome/renderer/geolocation_dispatcher.h b/chrome/renderer/geolocation_dispatcher.h
index 846e8e8..e9f3d41 100644
--- a/chrome/renderer/geolocation_dispatcher.h
+++ b/chrome/renderer/geolocation_dispatcher.h
@@ -7,10 +7,10 @@
#pragma once
#include "base/scoped_ptr.h"
+#include "chrome/renderer/render_view_observer.h"
#include "third_party/WebKit/WebKit/chromium/public/WebGeolocationClient.h"
#include "third_party/WebKit/WebKit/chromium/public/WebGeolocationController.h"
-class RenderView;
struct Geoposition;
namespace WebKit {
@@ -21,19 +21,17 @@ class WebGeolocationPosition;
class WebSecurityOrigin;
}
-namespace IPC {
-class Message;
-}
-
// GeolocationDispatcher is a delegate for Geolocation messages used by
// WebKit.
// It's the complement of GeolocationDispatcherHost (owned by RenderViewHost).
-class GeolocationDispatcher : public WebKit::WebGeolocationClient {
+class GeolocationDispatcher : public RenderViewObserver,
+ public WebKit::WebGeolocationClient {
public:
explicit GeolocationDispatcher(RenderView* render_view);
virtual ~GeolocationDispatcher();
- // IPC
+ private:
+ // RenderView::Observer implementation.
bool OnMessageReceived(const IPC::Message& message);
// WebGeolocationClient
@@ -48,7 +46,6 @@ class GeolocationDispatcher : public WebKit::WebGeolocationClient {
virtual void cancelPermissionRequest(
const WebKit::WebGeolocationPermissionRequest& permissionRequest);
- private:
// Permission for using geolocation has been set.
void OnGeolocationPermissionSet(int bridge_id, bool is_allowed);
diff --git a/chrome/renderer/notification_provider.cc b/chrome/renderer/notification_provider.cc
index 0196d0c..e5e87f9 100644
--- a/chrome/renderer/notification_provider.cc
+++ b/chrome/renderer/notification_provider.cc
@@ -25,8 +25,8 @@ using WebKit::WebSecurityOrigin;
using WebKit::WebString;
using WebKit::WebURL;
-NotificationProvider::NotificationProvider(RenderView* view)
- : view_(view) {
+NotificationProvider::NotificationProvider(RenderView* render_view)
+ : RenderViewObserver(render_view) {
}
NotificationProvider::~NotificationProvider() {
@@ -46,7 +46,7 @@ void NotificationProvider::cancel(const WebNotification& notification) {
bool id_found = manager_.GetId(notification, id);
// Won't be found if the notification has already been closed by the user.
if (id_found)
- Send(new ViewHostMsg_CancelDesktopNotification(view_->routing_id(), id));
+ Send(new ViewHostMsg_CancelDesktopNotification(routing_id(), id));
}
void NotificationProvider::objectDestroyed(
@@ -62,7 +62,7 @@ WebNotificationPresenter::Permission NotificationProvider::checkPermission(
const WebURL& url) {
int permission;
Send(new ViewHostMsg_CheckNotificationPermission(
- view_->routing_id(),
+ routing_id(),
url,
&permission));
return static_cast<WebNotificationPresenter::Permission>(permission);
@@ -72,12 +72,12 @@ void NotificationProvider::requestPermission(
const WebSecurityOrigin& origin,
WebNotificationPermissionCallback* callback) {
// We only request permission in response to a user gesture.
- if (!view_->webview()->mainFrame()->isProcessingUserGesture())
+ if (!render_view()->webview()->mainFrame()->isProcessingUserGesture())
return;
int id = manager_.RegisterPermissionRequest(callback);
- Send(new ViewHostMsg_RequestNotificationPermission(view_->routing_id(),
+ Send(new ViewHostMsg_RequestNotificationPermission(routing_id(),
GURL(origin.toString()),
id));
}
@@ -93,11 +93,11 @@ bool NotificationProvider::OnMessageReceived(const IPC::Message& message) {
OnPermissionRequestComplete);
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
- return handled;
-}
-void NotificationProvider::OnNavigate() {
- manager_.Clear();
+ if (message.type() == ViewMsg_Navigate::ID)
+ OnNavigate(); // Don't want to swallow the message.
+
+ return handled;
}
bool NotificationProvider::ShowHTML(const WebNotification& notification,
@@ -113,13 +113,13 @@ bool NotificationProvider::ShowHTML(const WebNotification& notification,
DCHECK(notification.isHTML());
ViewHostMsg_ShowNotification_Params params;
- params.origin = GURL(view_->webview()->mainFrame()->url()).GetOrigin();
+ params.origin =
+ GURL(render_view()->webview()->mainFrame()->url()).GetOrigin();
params.is_html = true;
params.contents_url = notification.url();
params.notification_id = id;
params.replace_id = notification.replaceId();
- return Send(new ViewHostMsg_ShowDesktopNotification(view_->routing_id(),
- params));
+ return Send(new ViewHostMsg_ShowDesktopNotification(routing_id(), params));
}
bool NotificationProvider::ShowText(const WebNotification& notification,
@@ -127,7 +127,8 @@ bool NotificationProvider::ShowText(const WebNotification& notification,
DCHECK(!notification.isHTML());
ViewHostMsg_ShowNotification_Params params;
params.is_html = false;
- params.origin = GURL(view_->webview()->mainFrame()->url()).GetOrigin();
+ params.origin = GURL(
+ render_view()->webview()->mainFrame()->url()).GetOrigin();
params.icon_url = notification.iconURL();
params.title = notification.title();
params.body = notification.body();
@@ -135,8 +136,7 @@ bool NotificationProvider::ShowText(const WebNotification& notification,
params.notification_id = id;
params.replace_id = notification.replaceId();
- return Send(new ViewHostMsg_ShowDesktopNotification(view_->routing_id(),
- params));
+ return Send(new ViewHostMsg_ShowDesktopNotification(routing_id(), params));
}
void NotificationProvider::OnDisplay(int id) {
@@ -184,6 +184,6 @@ void NotificationProvider::OnPermissionRequestComplete(int id) {
manager_.OnPermissionRequestComplete(id);
}
-bool NotificationProvider::Send(IPC::Message* message) {
- return RenderThread::current()->Send(message);
+void NotificationProvider::OnNavigate() {
+ manager_.Clear();
}
diff --git a/chrome/renderer/notification_provider.h b/chrome/renderer/notification_provider.h
index 1ba84b2..85cccff 100644
--- a/chrome/renderer/notification_provider.h
+++ b/chrome/renderer/notification_provider.h
@@ -7,23 +7,26 @@
#pragma once
#include "chrome/common/desktop_notifications/active_notification_tracker.h"
-#include "ipc/ipc_channel.h"
+#include "chrome/renderer/render_view_observer.h"
#include "third_party/WebKit/WebKit/chromium/public/WebNotification.h"
#include "third_party/WebKit/WebKit/chromium/public/WebNotificationPresenter.h"
-class RenderView;
namespace WebKit {
class WebNotificationPermissionCallback;
}
// NotificationProvider class is owned by the RenderView. Only
-// to be used on the UI thread.
-class NotificationProvider : public WebKit::WebNotificationPresenter,
- public IPC::Channel::Listener {
+// to be used on the main thread.
+class NotificationProvider : public RenderViewObserver,
+ public WebKit::WebNotificationPresenter {
public:
- explicit NotificationProvider(RenderView* view);
+ explicit NotificationProvider(RenderView* render_view);
virtual ~NotificationProvider();
+ private:
+ // RenderView::Observer implementation.
+ bool OnMessageReceived(const IPC::Message& message);
+
// WebKit::WebNotificationPresenter interface.
virtual bool show(const WebKit::WebNotification& proxy);
virtual void cancel(const WebKit::WebNotification& proxy);
@@ -33,13 +36,6 @@ class NotificationProvider : public WebKit::WebNotificationPresenter,
virtual void requestPermission(const WebKit::WebSecurityOrigin& origin,
WebKit::WebNotificationPermissionCallback* callback);
- // IPC::Channel::Listener implementation.
- bool OnMessageReceived(const IPC::Message& message);
-
- // Called when the RenderView navigates.
- void OnNavigate();
-
- private:
// Internal methods used to show notifications.
bool ShowHTML(const WebKit::WebNotification& notification, int id);
bool ShowText(const WebKit::WebNotification& notification, int id);
@@ -50,12 +46,7 @@ class NotificationProvider : public WebKit::WebNotificationPresenter,
void OnClose(int id, bool by_user);
void OnClick(int id);
void OnPermissionRequestComplete(int id);
-
- bool Send(IPC::Message* message);
-
- // Non-owned pointer to the RenderView object which created and owns
- // this object.
- RenderView* view_;
+ void OnNavigate();
// A tracker object which manages the active notifications and the IDs
// that are used to refer to them over IPC.
diff --git a/chrome/renderer/page_click_tracker.cc b/chrome/renderer/page_click_tracker.cc
index c974808..c11494e 100644
--- a/chrome/renderer/page_click_tracker.cc
+++ b/chrome/renderer/page_click_tracker.cc
@@ -26,12 +26,12 @@ using WebKit::WebString;
using WebKit::WebView;
PageClickTracker::PageClickTracker(RenderView* render_view)
- : render_view_(render_view),
+ : RenderViewObserver(render_view),
was_focused_(false) {
}
PageClickTracker::~PageClickTracker() {
- // Note that even though RenderView calls StopTrackingFrame when notified that
+ // Note that even though RenderView calls FrameDetached when notified that
// a frame was closed, it might not always get that notification from WebKit
// for all frames.
// By the time we get here, the frame could have been destroyed so we cannot
@@ -39,27 +39,6 @@ PageClickTracker::~PageClickTracker() {
// be invalid.
}
-void PageClickTracker::StartTrackingFrame(WebFrame* frame) {
- tracked_frames_.push_back(frame);
- frame->document().addEventListener("mousedown", this, false);
-}
-
-void PageClickTracker::StopTrackingFrame(WebFrame* frame, bool frame_detached) {
- FrameList::iterator iter =
- std::find(tracked_frames_.begin(), tracked_frames_.end(), frame);
- if (iter == tracked_frames_.end()) {
- // Some frames might never load contents so we may not have a listener on
- // them. Calling removeEventListener() on them would trigger an assert, so
- // we need to keep track of which frames we are listening to.
- return;
- }
- tracked_frames_.erase(iter);
- // If the frame has been detached, all event listeners have already been
- // removed.
- if (!frame_detached)
- frame->document().removeEventListener("mousedown", this, false);
-}
-
void PageClickTracker::DidHandleMouseEvent(const WebMouseEvent& event) {
if (event.type != WebInputEvent::MouseDown ||
last_node_clicked_.isNull()) {
@@ -98,6 +77,38 @@ void PageClickTracker::RemoveListener(PageClickListener* listener) {
listeners_.RemoveObserver(listener);
}
+bool PageClickTracker::OnMessageReceived(const IPC::Message& message) {
+ if (message.type() == ViewMsg_HandleInputEvent::ID) {
+ void* iter = NULL;
+ const char* data;
+ int data_length;
+ if (message.ReadData(&iter, &data, &data_length)) {
+ const WebInputEvent* input_event =
+ reinterpret_cast<const WebInputEvent*>(data);
+ if (WebInputEvent::isMouseEventType(input_event->type))
+ DidHandleMouseEvent(*(static_cast<const WebMouseEvent*>(input_event)));
+ }
+ }
+ return false;
+}
+
+void PageClickTracker::DidFinishDocumentLoad(WebKit::WebFrame* frame) {
+ tracked_frames_.push_back(frame);
+ frame->document().addEventListener("mousedown", this, false);
+}
+
+void PageClickTracker::FrameDetached(WebKit::WebFrame* frame) {
+ FrameList::iterator iter =
+ std::find(tracked_frames_.begin(), tracked_frames_.end(), frame);
+ if (iter == tracked_frames_.end()) {
+ // Some frames might never load contents so we may not have a listener on
+ // them. Calling removeEventListener() on them would trigger an assert, so
+ // we need to keep track of which frames we are listening to.
+ return;
+ }
+ tracked_frames_.erase(iter);
+}
+
void PageClickTracker::handleEvent(const WebDOMEvent& event) {
last_node_clicked_.reset();
@@ -117,7 +128,7 @@ void PageClickTracker::handleEvent(const WebDOMEvent& event) {
}
WebNode PageClickTracker::GetFocusedNode() {
- WebView* web_view = render_view_->webview();
+ WebView* web_view = render_view()->webview();
if (!web_view)
return WebNode();
diff --git a/chrome/renderer/page_click_tracker.h b/chrome/renderer/page_click_tracker.h
index 492237c..d765310 100644
--- a/chrome/renderer/page_click_tracker.h
+++ b/chrome/renderer/page_click_tracker.h
@@ -9,17 +9,12 @@
#include "base/basictypes.h"
#include "base/observer_list.h"
+#include "chrome/renderer/render_view_observer.h"
#include "third_party/WebKit/WebKit/chromium/public/WebDOMEventListener.h"
#include "third_party/WebKit/WebKit/chromium/public/WebNode.h"
class PageClickListener;
-class RenderView;
-namespace WebKit {
-class WebFrame;
-class WebDOMEvent;
-class WebMouseEvent;
-}
// This class is responsible for tracking clicks on elements in web pages and
// notifiying the associated listener when a node is clicked.
@@ -33,23 +28,12 @@ class WebMouseEvent;
// could easily be changed to report click on any type of WebNode.
//
// There is one PageClickTracker per RenderView.
-
-class PageClickTracker : public WebKit::WebDOMEventListener {
+class PageClickTracker : public RenderViewObserver,
+ public WebKit::WebDOMEventListener {
public:
explicit PageClickTracker(RenderView* render_view);
virtual ~PageClickTracker();
- // Starts reporting node clicks for |frame| on the listener previously
- // specified with SetListener().
- void StartTrackingFrame(WebKit::WebFrame* frame);
-
- // Stops reporting node clicks for |frame|. |frame_detached| should be true
- // if the frame has already been detached.
- void StopTrackingFrame(WebKit::WebFrame* frame, bool frame_detached);
-
- // Called after the mouse event |event| has been processed by WebKit.
- void DidHandleMouseEvent(const WebKit::WebMouseEvent& event);
-
// Adds/removes a listener for getting notification when an element is
// clicked. Note that the order of insertion is important as a listener when
// notified can decide to stop the propagation of the event (so that listeners
@@ -58,9 +42,17 @@ class PageClickTracker : public WebKit::WebDOMEventListener {
void RemoveListener(PageClickListener* listener);
private:
+ // RenderView::Observer implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message);
+ virtual void DidFinishDocumentLoad(WebKit::WebFrame* frame);
+ virtual void FrameDetached(WebKit::WebFrame* frame);
+
// WebKit::WebDOMEventListener implementation.
virtual void handleEvent(const WebKit::WebDOMEvent& event);
+ // Called after the mouse event |event| has been processed by WebKit.
+ void DidHandleMouseEvent(const WebKit::WebMouseEvent& event);
+
// Returns the currently focused node in the associated render view.
// That node may be null.
WebKit::WebNode GetFocusedNode();
@@ -68,9 +60,6 @@ class PageClickTracker : public WebKit::WebDOMEventListener {
// The last node that was clicked and had focus.
WebKit::WebNode last_node_clicked_;
- // The render view we are associated with.
- RenderView* render_view_;
-
// Whether the last clicked node had focused before it was clicked.
bool was_focused_;
diff --git a/chrome/renderer/page_click_tracker_unittest.cc b/chrome/renderer/page_click_tracker_unittest.cc
index dcba0bb..fcb4463 100644
--- a/chrome/renderer/page_click_tracker_unittest.cc
+++ b/chrome/renderer/page_click_tracker_unittest.cc
@@ -49,10 +49,14 @@ class TestPageClickListener : public PageClickListener {
// Tests that PageClickTracker does notify correctly when a node is clicked.
TEST_F(RenderViewTest, PageClickTracker) {
+ // RenderView creates PageClickTracker but it doesn't keep it around. Rather
+ // than make it do so for the test, we create a new object.
+ PageClickTracker* page_click_tracker = new PageClickTracker(view_);
+
TestPageClickListener test_listener1;
TestPageClickListener test_listener2;
- view_->page_click_tracker()->AddListener(&test_listener1);
- view_->page_click_tracker()->AddListener(&test_listener2);
+ page_click_tracker->AddListener(&test_listener1);
+ page_click_tracker->AddListener(&test_listener2);
LoadHTML("<form>"
" <input type='text' id='text'></input><br>"
@@ -106,14 +110,14 @@ TEST_F(RenderViewTest, PageClickTracker) {
test_listener1.ClearResults();
// Make sure removing a listener work.
- view_->page_click_tracker()->RemoveListener(&test_listener1);
+ page_click_tracker->RemoveListener(&test_listener1);
EXPECT_TRUE(SimulateElementClick("text"));
EXPECT_FALSE(test_listener1.called_);
EXPECT_TRUE(test_listener2.called_);
test_listener2.ClearResults();
// Make sure we don't choke when no listeners are registered.
- view_->page_click_tracker()->RemoveListener(&test_listener2);
+ page_click_tracker->RemoveListener(&test_listener2);
EXPECT_TRUE(SimulateElementClick("text"));
EXPECT_FALSE(test_listener1.called_);
EXPECT_FALSE(test_listener2.called_);
diff --git a/chrome/renderer/password_autocomplete_manager.cc b/chrome/renderer/password_autocomplete_manager.cc
index 2c59b7d..ac1a90c 100644
--- a/chrome/renderer/password_autocomplete_manager.cc
+++ b/chrome/renderer/password_autocomplete_manager.cc
@@ -171,47 +171,13 @@ bool DoUsernamesMatch(const string16& username1,
PasswordAutocompleteManager::PasswordAutocompleteManager(
RenderView* render_view)
- : render_view_(render_view),
+ : RenderViewObserver(render_view),
ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
}
PasswordAutocompleteManager::~PasswordAutocompleteManager() {
}
-void PasswordAutocompleteManager::ReceivedPasswordFormFillData(
- WebKit::WebView* view,
- const webkit_glue::PasswordFormFillData& form_data) {
- FormElementsList forms;
- // We own the FormElements* in forms.
- FindFormElements(view, form_data.basic_data, &forms);
- FormElementsList::iterator iter;
- for (iter = forms.begin(); iter != forms.end(); ++iter) {
- scoped_ptr<FormElements> form_elements(*iter);
-
- // If wait_for_username is true, we don't want to initially fill the form
- // until the user types in a valid username.
- if (!form_data.wait_for_username)
- FillForm(form_elements.get(), form_data.basic_data);
-
- // Attach autocomplete listener to enable selecting alternate logins.
- // First, get pointers to username element.
- WebKit::WebInputElement username_element =
- form_elements->input_elements[form_data.basic_data.fields[0].name()];
-
- // Get pointer to password element. (We currently only support single
- // password forms).
- WebKit::WebInputElement password_element =
- form_elements->input_elements[form_data.basic_data.fields[1].name()];
-
- DCHECK(login_to_password_info_.find(username_element) ==
- login_to_password_info_.end());
- PasswordInfo password_info;
- password_info.fill_data = form_data;
- password_info.password_field = password_element;
- login_to_password_info_[username_element] = password_info;
- }
-}
-
void PasswordAutocompleteManager::FrameClosing(const WebKit::WebFrame* frame) {
for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin();
iter != login_to_password_info_.end();) {
@@ -376,14 +342,31 @@ void PasswordAutocompleteManager::SendPasswordForms(WebKit::WebFrame* frame,
return;
if (only_visible) {
- render_view_->Send(
- new ViewHostMsg_PasswordFormsVisible(GetRoutingID(), password_forms));
+ Send(new ViewHostMsg_PasswordFormsVisible(routing_id(), password_forms));
} else {
- render_view_->Send(
- new ViewHostMsg_PasswordFormsFound(GetRoutingID(), password_forms));
+ Send(new ViewHostMsg_PasswordFormsFound(routing_id(), password_forms));
}
}
+bool PasswordAutocompleteManager::OnMessageReceived(
+ const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(PasswordAutocompleteManager, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void PasswordAutocompleteManager::DidFinishDocumentLoad(
+ WebKit::WebFrame* frame) {
+ SendPasswordForms(frame, false);
+}
+
+void PasswordAutocompleteManager::DidFinishLoad(WebKit::WebFrame* frame) {
+ SendPasswordForms(frame, true);
+}
+
////////////////////////////////////////////////////////////////////////////////
// PageClickListener implementation:
@@ -395,6 +378,39 @@ bool PasswordAutocompleteManager::InputElementClicked(
return false;
}
+void PasswordAutocompleteManager::OnFillPasswordForm(
+ const webkit_glue::PasswordFormFillData& form_data) {
+ FormElementsList forms;
+ // We own the FormElements* in forms.
+ FindFormElements(render_view()->webview(), form_data.basic_data, &forms);
+ FormElementsList::iterator iter;
+ for (iter = forms.begin(); iter != forms.end(); ++iter) {
+ scoped_ptr<FormElements> form_elements(*iter);
+
+ // If wait_for_username is true, we don't want to initially fill the form
+ // until the user types in a valid username.
+ if (!form_data.wait_for_username)
+ FillForm(form_elements.get(), form_data.basic_data);
+
+ // Attach autocomplete listener to enable selecting alternate logins.
+ // First, get pointers to username element.
+ WebKit::WebInputElement username_element =
+ form_elements->input_elements[form_data.basic_data.fields[0].name()];
+
+ // Get pointer to password element. (We currently only support single
+ // password forms).
+ WebKit::WebInputElement password_element =
+ form_elements->input_elements[form_data.basic_data.fields[1].name()];
+
+ DCHECK(login_to_password_info_.find(username_element) ==
+ login_to_password_info_.end());
+ PasswordInfo password_info;
+ password_info.fill_data = form_data;
+ password_info.password_field = password_element;
+ login_to_password_info_[username_element] = password_info;
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
// PasswordAutocompleteManager, private:
@@ -481,7 +497,3 @@ bool PasswordAutocompleteManager::FillUserNameAndPassword(
SetElementAutofilled(password_element, true);
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 c4e4b2f..f2aa112 100644
--- a/chrome/renderer/password_autocomplete_manager.h
+++ b/chrome/renderer/password_autocomplete_manager.h
@@ -11,28 +11,23 @@
#include "base/task.h"
#include "chrome/renderer/page_click_listener.h"
+#include "chrome/renderer/render_view_observer.h"
#include "webkit/glue/password_form_dom_manager.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputElement.h"
-class RenderView;
namespace WebKit {
+class WebInputElement;
class WebKeyboardEvent;
-class WebView;
}
// This class is responsible for filling password forms.
// There is one PasswordAutocompleteManager per RenderView.
-class PasswordAutocompleteManager : public PageClickListener {
+class PasswordAutocompleteManager : public RenderViewObserver,
+ public PageClickListener {
public:
explicit PasswordAutocompleteManager(RenderView* render_view);
virtual ~PasswordAutocompleteManager();
- // Invoked by the renderer when it receives the password info from the
- // browser. This triggers a password autocomplete (if wait_for_username is
- // false on |form_data|).
- void ReceivedPasswordFormFillData(WebKit::WebView* view,
- const webkit_glue::PasswordFormFillData& form_data);
-
// Invoked when the passed frame is closing. Gives us a chance to clear any
// reference we may have to elements in that frame.
void FrameClosing(const WebKit::WebFrame* frame);
@@ -50,10 +45,6 @@ class PasswordAutocompleteManager : public PageClickListener {
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.
// If they return true, it indicates the event was consumed and should not
// be used for any other autofill activity.
@@ -63,6 +54,8 @@ class PasswordAutocompleteManager : public PageClickListener {
const WebKit::WebKeyboardEvent& event);
private:
+ friend class PasswordAutocompleteManagerTest;
+
struct PasswordInfo {
WebKit::WebInputElement password_field;
webkit_glue::PasswordFormFillData fill_data;
@@ -71,11 +64,23 @@ class PasswordAutocompleteManager : public PageClickListener {
};
typedef std::map<WebKit::WebElement, PasswordInfo> LoginToPasswordInfoMap;
+ // RenderView::Observer implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message);
+ virtual void DidFinishDocumentLoad(WebKit::WebFrame* frame);
+ virtual void DidFinishLoad(WebKit::WebFrame* frame);
+
// PageClickListener implementation:
virtual bool InputElementClicked(const WebKit::WebInputElement& element,
bool was_focused,
bool is_focused);
+ void OnFillPasswordForm(
+ const webkit_glue::PasswordFormFillData& form_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);
+
void GetSuggestions(
const webkit_glue::PasswordFormFillData& fill_data,
const string16& input,
@@ -92,13 +97,6 @@ class PasswordAutocompleteManager : public PageClickListener {
bool exact_username_match,
bool set_selection);
- // 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/password_autocomplete_manager_unittest.cc b/chrome/renderer/password_autocomplete_manager_unittest.cc
index fd6546f..7f378b96 100644
--- a/chrome/renderer/password_autocomplete_manager_unittest.cc
+++ b/chrome/renderer/password_autocomplete_manager_unittest.cc
@@ -4,6 +4,7 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
+#include "chrome/renderer/autofill_helper.h"
#include "chrome/renderer/password_autocomplete_manager.h"
#include "chrome/test/render_view_test.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -62,7 +63,7 @@ class PasswordAutocompleteManagerTest : public RenderViewTest {
void SimulateOnFillPasswordForm(
const PasswordFormFillData& fill_data) {
ViewMsg_FillPasswordForm msg(0, fill_data);
- view_->OnMessageReceived(msg);
+ password_autocomplete_->OnMessageReceived(msg);
}
virtual void SetUp() {
@@ -117,7 +118,7 @@ class PasswordAutocompleteManagerTest : public RenderViewTest {
username_element_.setValue(WebString::fromUTF8(username));
if (move_caret_to_end)
username_element_.setSelectionRange(username.length(), username.length());
- view_->textFieldDidChange(username_element_);
+ autofill_helper_->textFieldDidChange(username_element_);
// Processing is delayed because of a WebKit bug, see
// PasswordAutocompleteManager::TextDidChangeInTextField() for details.
MessageLoop::current()->RunAllPending();
@@ -127,7 +128,7 @@ class PasswordAutocompleteManagerTest : public RenderViewTest {
ui::KeyboardCode key_code) {
WebKit::WebKeyboardEvent key_event;
key_event.windowsKeyCode = key_code;
- view_->textFieldDidReceiveKeyDown(element, key_event);
+ autofill_helper_->textFieldDidReceiveKeyDown(element, key_event);
}
void CheckTextFieldsState(const std::string& username,
@@ -243,16 +244,16 @@ TEST_F(PasswordAutocompleteManagerTest, WaitUsername) {
// Autocomplete should happen only when the username textfield is blurred with
// a full match.
username_element_.setValue("a");
- view_->textFieldDidEndEditing(username_element_);
+ autofill_helper_->textFieldDidEndEditing(username_element_);
CheckTextFieldsState("a", false, "", false);
username_element_.setValue("al");
- view_->textFieldDidEndEditing(username_element_);
+ autofill_helper_->textFieldDidEndEditing(username_element_);
CheckTextFieldsState("al", false, "", false);
username_element_.setValue("alices");
- view_->textFieldDidEndEditing(username_element_);
+ autofill_helper_->textFieldDidEndEditing(username_element_);
CheckTextFieldsState("alices", false, "", false);
username_element_.setValue(ASCIIToUTF16(kAliceUsername));
- view_->textFieldDidEndEditing(username_element_);
+ autofill_helper_->textFieldDidEndEditing(username_element_);
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
}
@@ -326,7 +327,7 @@ TEST_F(PasswordAutocompleteManagerTest, SuggestionSelect) {
// WebView does: it sets the element value then calls
// didAcceptAutocompleteSuggestion on the renderer.
username_element_.setValue(ASCIIToUTF16(kAliceUsername));
- view_->didAcceptAutocompleteSuggestion(username_element_);
+ autofill_helper_->didAcceptAutocompleteSuggestion(username_element_);
// Autocomplete should have kicked in.
CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 19fd677..a2ca602 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -78,6 +78,7 @@
#include "chrome/renderer/print_web_view_helper.h"
#include "chrome/renderer/render_process.h"
#include "chrome/renderer/render_thread.h"
+#include "chrome/renderer/render_view_observer.h"
#include "chrome/renderer/render_view_visitor.h"
#include "chrome/renderer/render_widget_fullscreen.h"
#include "chrome/renderer/render_widget_fullscreen_pepper.h"
@@ -520,10 +521,16 @@ struct RenderView::PendingFileChooser {
};
RenderView::RenderView(RenderThreadBase* render_thread,
- const WebPreferences& webkit_preferences,
- int64 session_storage_namespace_id)
+ gfx::NativeViewId parent_hwnd,
+ int32 opener_id,
+ const RendererPreferences& renderer_prefs,
+ const WebPreferences& webkit_prefs,
+ SharedRenderViewCounter* counter,
+ int32 routing_id,
+ int64 session_storage_namespace_id,
+ const string16& frame_name)
: RenderWidget(render_thread, WebKit::WebPopupTypeNone),
- webkit_preferences_(webkit_preferences),
+ webkit_preferences_(webkit_prefs),
send_content_state_immediately_(false),
enabled_bindings_(0),
send_preferred_size_changes_(false),
@@ -548,16 +555,16 @@ RenderView::RenderView(RenderThreadBase* render_thread,
browser_window_id_(-1),
ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(page_info_method_factory_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(autofill_method_factory_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(accessibility_method_factory_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(translate_helper_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(cookie_jar_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- notification_provider_(new NotificationProvider(this))),
+ devtools_client_(NULL),
+ geolocation_dispatcher_(NULL),
+ speech_input_dispatcher_(NULL),
+ device_orientation_dispatcher_(NULL),
accessibility_ack_pending_(false),
pending_app_icon_requests_(0),
session_storage_namespace_id_(session_storage_namespace_id),
- decrement_shared_popup_at_destruction_(false),
custom_menu_listener_(NULL) {
#if defined(OS_MACOSX)
// On Mac, the select popups are rendered by the browser.
@@ -565,14 +572,7 @@ RenderView::RenderView(RenderThreadBase* render_thread,
// in single-process mode.
WebKit::WebView::setUseExternalPopupMenus(true);
#endif
- password_autocomplete_manager_.reset(new PasswordAutocompleteManager(this));
- autofill_helper_.reset(new AutoFillHelper(this));
- page_click_tracker_.reset(new PageClickTracker(this));
- // Note that the order of insertion of the listeners is important.
- // The password_autocomplete_manager_ takes the first shot at processing the
- // notification and can stop the propagation.
- page_click_tracker_->AddListener(password_autocomplete_manager_.get());
- page_click_tracker_->AddListener(autofill_helper_.get());
+
ClearBlockedContentSettings();
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableClientSidePhishingDetection)) {
@@ -583,6 +583,66 @@ RenderView::RenderView(RenderThreadBase* render_thread,
phishing_delegate_->SetPhishingScorer(thread->phishing_scorer());
}
}
+
+ routing_id_ = routing_id;
+ if (opener_id != MSG_ROUTING_NONE)
+ opener_id_ = opener_id;
+
+ if (counter) {
+ shared_popup_counter_ = counter;
+ shared_popup_counter_->data++;
+ decrement_shared_popup_at_destruction_ = true;
+ } else {
+ shared_popup_counter_ = new SharedRenderViewCounter(0);
+ decrement_shared_popup_at_destruction_ = false;
+ }
+
+ notification_provider_ = new NotificationProvider(this);
+
+ devtools_agent_ = new DevToolsAgent(this);
+ PasswordAutocompleteManager* password_autocomplete_manager =
+ new PasswordAutocompleteManager(this);
+ AutoFillHelper* autofill_helper = new AutoFillHelper(
+ this, password_autocomplete_manager);
+
+ webwidget_ = WebView::create(this, devtools_agent_, autofill_helper);
+ g_view_map.Get().insert(std::make_pair(webview(), this));
+ webkit_preferences_.Apply(webview());
+ webview()->initializeMainFrame(this);
+ if (!frame_name.empty())
+ webview()->mainFrame()->setName(frame_name);
+
+ OnSetRendererPrefs(renderer_prefs);
+
+ render_thread_->AddRoute(routing_id_, this);
+ // Take a reference on behalf of the RenderThread. This will be balanced
+ // when we receive ViewMsg_Close.
+ AddRef();
+
+ // If this is a popup, we must wait for the CreatingNew_ACK message before
+ // completing initialization. Otherwise, we can finish it now.
+ if (opener_id == MSG_ROUTING_NONE) {
+ did_show_ = true;
+ CompleteInit(parent_hwnd);
+ }
+
+ host_window_ = parent_hwnd;
+
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ if (command_line.HasSwitch(switches::kDomAutomationController))
+ enabled_bindings_ |= BindingsPolicy::DOM_AUTOMATION;
+ if (command_line.HasSwitch(switches::kEnableAccessibility))
+ WebAccessibilityCache::enableAccessibility();
+
+ audio_message_filter_ = new AudioMessageFilter(routing_id_);
+ render_thread_->AddFilter(audio_message_filter_);
+
+ PageClickTracker* page_click_tracker = new PageClickTracker(this);
+ // Note that the order of insertion of the listeners is important.
+ // The password_autocomplete_manager takes the first shot at processing the
+ // notification and can stop the propagation.
+ page_click_tracker->AddListener(password_autocomplete_manager);
+ page_click_tracker->AddListener(autofill_helper);
}
RenderView::~RenderView() {
@@ -624,6 +684,9 @@ RenderView::~RenderView() {
for (ViewMap::iterator it = views->begin(); it != views->end(); ++it)
DCHECK_NE(this, it->second) << "Failed to call Close?";
#endif
+
+ FOR_EACH_OBSERVER(RenderViewObserver, observers_, set_render_view(NULL));
+ FOR_EACH_OBSERVER(RenderViewObserver, observers_, OnDestruct());
}
/*static*/
@@ -654,15 +717,16 @@ RenderView* RenderView::Create(
int64 session_storage_namespace_id,
const string16& frame_name) {
DCHECK(routing_id != MSG_ROUTING_NONE);
- scoped_refptr<RenderView> view(new RenderView(render_thread, webkit_prefs,
- session_storage_namespace_id));
- view->Init(parent_hwnd,
- opener_id,
- renderer_prefs,
- counter,
- routing_id,
- frame_name); // adds reference
- return view;
+ return new RenderView(
+ render_thread,
+ parent_hwnd,
+ opener_id,
+ renderer_prefs,
+ webkit_prefs,
+ counter,
+ routing_id,
+ session_storage_namespace_id,
+ frame_name); // adds reference
}
// static
@@ -674,6 +738,15 @@ void RenderView::SetNextPageID(int32 next_page_id) {
next_page_id_ = next_page_id;
}
+void RenderView::AddObserver(RenderViewObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void RenderView::RemoveObserver(RenderViewObserver* observer) {
+ observer->set_render_view(NULL);
+ observers_.RemoveObserver(observer);
+}
+
bool RenderView::RendererAccessibilityNotification::ShouldIncludeChildren() {
typedef ViewHostMsg_AccessibilityNotification_Params params;
if (type == params::NOTIFICATION_TYPE_CHILDREN_CHANGED ||
@@ -894,86 +967,16 @@ void RenderView::UnregisterBlockedPlugin(BlockedPlugin* blocked_plugin) {
blocked_plugins_.erase(blocked_plugin);
}
-void RenderView::Init(gfx::NativeViewId parent_hwnd,
- int32 opener_id,
- const RendererPreferences& renderer_prefs,
- SharedRenderViewCounter* counter,
- int32 routing_id,
- const string16& frame_name) {
- DCHECK(!webview());
-
- if (opener_id != MSG_ROUTING_NONE)
- opener_id_ = opener_id;
-
- if (counter) {
- shared_popup_counter_ = counter;
- shared_popup_counter_->data++;
- decrement_shared_popup_at_destruction_ = true;
- } else {
- shared_popup_counter_ = new SharedRenderViewCounter(0);
- decrement_shared_popup_at_destruction_ = false;
- }
-
- devtools_agent_.reset(new DevToolsAgent(routing_id, this));
-
- webwidget_ = WebView::create(this, devtools_agent_.get(), this);
- g_view_map.Get().insert(std::make_pair(webview(), this));
- webkit_preferences_.Apply(webview());
- webview()->initializeMainFrame(this);
- if (!frame_name.empty())
- webview()->mainFrame()->setName(frame_name);
-
- OnSetRendererPrefs(renderer_prefs);
-
- routing_id_ = routing_id;
- render_thread_->AddRoute(routing_id_, this);
- // Take a reference on behalf of the RenderThread. This will be balanced
- // when we receive ViewMsg_Close.
- AddRef();
-
- // If this is a popup, we must wait for the CreatingNew_ACK message before
- // completing initialization. Otherwise, we can finish it now.
- if (opener_id == MSG_ROUTING_NONE) {
- did_show_ = true;
- CompleteInit(parent_hwnd);
- }
-
- host_window_ = parent_hwnd;
-
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kDomAutomationController))
- enabled_bindings_ |= BindingsPolicy::DOM_AUTOMATION;
- if (command_line.HasSwitch(switches::kEnableAccessibility))
- WebAccessibilityCache::enableAccessibility();
-
- audio_message_filter_ = new AudioMessageFilter(routing_id_);
- render_thread_->AddFilter(audio_message_filter_);
-}
-
bool RenderView::OnMessageReceived(const IPC::Message& message) {
WebFrame* main_frame = webview() ? webview()->mainFrame() : NULL;
if (main_frame)
child_process_logging::SetActiveURL(main_frame->url());
- // If this is developer tools renderer intercept tools messages first.
- if (devtools_client_.get() && devtools_client_->OnMessageReceived(message))
- return true;
- if (devtools_agent_.get() && devtools_agent_->OnMessageReceived(message))
- return true;
- if (notification_provider_->OnMessageReceived(message))
- return true;
- if (geolocation_dispatcher_.get() &&
- geolocation_dispatcher_->OnMessageReceived(message)) {
- return true;
- }
- if (speech_input_dispatcher_.get() &&
- speech_input_dispatcher_->OnMessageReceived(message)) {
- return true;
- }
- if (device_orientation_dispatcher_.get() &&
- device_orientation_dispatcher_->OnMessageReceived(message)) {
- return true;
- }
+ ObserverListBase<RenderViewObserver>::Iterator it(observers_);
+ RenderViewObserver* observer;
+ while ((observer = it.GetNext()) != NULL)
+ if (observer->OnMessageReceived(message))
+ return true;
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderView, message)
@@ -1019,7 +1022,6 @@ bool RenderView::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewMsg_CSSInsertRequest, OnCSSInsertRequest)
IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)
IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)
- IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)
IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)
IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)
IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)
@@ -1053,10 +1055,6 @@ bool RenderView::OnMessageReceived(const IPC::Message& message) {
OnHandleMessageFromExternalHost)
IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
OnDisassociateFromPopupCount)
- IPC_MESSAGE_HANDLER(ViewMsg_AutoFillSuggestionsReturned,
- OnAutoFillSuggestionsReturned)
- IPC_MESSAGE_HANDLER(ViewMsg_AutoFillFormDataFilled,
- OnAutoFillFormDataFilled)
IPC_MESSAGE_HANDLER(ViewMsg_AllowScriptToClose,
OnAllowScriptToClose)
IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
@@ -1378,12 +1376,6 @@ void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {
history_list_offset_ = params.current_history_list_offset;
history_list_length_ = params.current_history_list_length;
- if (devtools_agent_.get())
- devtools_agent_->OnNavigate();
-
- if (notification_provider_.get())
- notification_provider_->OnNavigate();
-
child_process_logging::SetActiveURL(params.url);
AboutHandler::MaybeHandle(params.url);
@@ -1504,8 +1496,8 @@ void RenderView::OnExecuteEditCommand(const std::string& name,
}
void RenderView::OnSetupDevToolsClient() {
- DCHECK(!devtools_client_.get());
- devtools_client_.reset(new DevToolsClient(this));
+ DCHECK(!devtools_client_);
+ devtools_client_ = new DevToolsClient(this);
}
void RenderView::OnUpdateTargetURLAck() {
@@ -1982,21 +1974,6 @@ void RenderView::AddGURLSearchProvider(
provider_type));
}
-void RenderView::OnAutoFillSuggestionsReturned(
- int query_id,
- const std::vector<string16>& values,
- const std::vector<string16>& labels,
- const std::vector<string16>& icons,
- const std::vector<int>& unique_ids) {
- autofill_helper_->SuggestionsReceived(
- query_id, values, labels, icons, unique_ids);
-}
-
-void RenderView::OnAutoFillFormDataFilled(int query_id,
- const webkit_glue::FormData& form) {
- autofill_helper_->FormDataFilled(query_id, form);
-}
-
void RenderView::OnAllowScriptToClose(bool script_can_close) {
script_can_close_ = script_can_close;
}
@@ -2195,7 +2172,7 @@ void RenderView::printPage(WebFrame* frame) {
}
WebKit::WebNotificationPresenter* RenderView::notificationPresenter() {
- return notification_provider_.get();
+ return notification_provider_;
}
void RenderView::didStartLoading() {
@@ -2300,29 +2277,6 @@ void RenderView::didExecuteCommand(const WebString& command_name) {
UserMetricsRecordAction(name);
}
-void RenderView::textFieldDidEndEditing(
- const WebKit::WebInputElement& element) {
- password_autocomplete_manager_->TextFieldDidEndEditing(element);
-}
-
-void RenderView::textFieldDidChange(const WebKit::WebInputElement& element) {
- // We post a task for doing the AutoFill as the caret position is not set
- // properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976) and
- // it is needed to trigger autofill.
- autofill_method_factory_.RevokeAll();
- MessageLoop::current()->PostTask(
- FROM_HERE,
- autofill_method_factory_.NewRunnableMethod(
- &RenderView::TextFieldDidChangeImpl, element));
-}
-
-void RenderView::TextFieldDidChangeImpl(
- const WebKit::WebInputElement& element) {
- if (password_autocomplete_manager_->TextDidChangeInTextField(element))
- return;
- autofill_helper_->TextDidChangeInTextField(element);
-}
-
void RenderView::SendPendingAccessibilityNotifications() {
if (!accessibility_.get())
return;
@@ -2350,13 +2304,6 @@ void RenderView::SendPendingAccessibilityNotifications() {
accessibility_ack_pending_ = true;
}
-void RenderView::textFieldDidReceiveKeyDown(
- const WebKit::WebInputElement& element,
- const WebKit::WebKeyboardEvent& event) {
- password_autocomplete_manager_->TextFieldHandlingKeyDown(element, event);
- autofill_helper_->KeyDownInTextField(element, event);
-}
-
bool RenderView::handleCurrentKeyboardEvent() {
if (edit_commands_.empty())
return false;
@@ -2649,43 +2596,6 @@ void RenderView::didUpdateInspectorSetting(const WebString& key,
value.utf8()));
}
-void RenderView::didAcceptAutoFillSuggestion(const WebKit::WebNode& node,
- const WebKit::WebString& value,
- const WebKit::WebString& label,
- int unique_id,
- unsigned index) {
- autofill_helper_->DidAcceptAutoFillSuggestion(node, value, unique_id, index);
-}
-
-void RenderView::didSelectAutoFillSuggestion(const WebKit::WebNode& node,
- const WebKit::WebString& value,
- const WebKit::WebString& label,
- int unique_id) {
- autofill_helper_->DidSelectAutoFillSuggestion(node, unique_id);
-}
-
-void RenderView::didClearAutoFillSelection(const WebKit::WebNode& node) {
- autofill_helper_->DidClearAutoFillSelection(node);
-}
-
-void RenderView::didAcceptAutocompleteSuggestion(
- const WebKit::WebInputElement& user_element) {
- bool result = password_autocomplete_manager_->FillPassword(user_element);
- // Since this user name was selected from a suggestion list, we should always
- // have password for it.
- DCHECK(result);
-}
-
-void RenderView::removeAutocompleteSuggestion(const WebKit::WebString& name,
- const WebKit::WebString& value) {
- autofill_helper_->RemoveAutocompleteSuggestion(name, value);
-}
-
-void RenderView::removeAutofillSuggestions(const WebString& name,
- const WebString& value) {
- removeAutocompleteSuggestion(name, value);
-}
-
// WebKit::WebWidgetClient ----------------------------------------------------
void RenderView::didFocus() {
@@ -2941,8 +2851,7 @@ WebCookieJar* RenderView::cookieJar(WebFrame* frame) {
}
void RenderView::frameDetached(WebFrame* frame) {
- autofill_helper_->FrameDetached(frame);
- page_click_tracker_->StopTrackingFrame(frame, true);
+ FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame));
}
void RenderView::willClose(WebFrame* frame) {
@@ -2952,11 +2861,7 @@ void RenderView::willClose(WebFrame* frame) {
page_load_histograms_.Dump(frame);
navigation_state->user_script_idle_scheduler()->Cancel();
- // TODO(jhawkins): Remove once frameDetached is called by WebKit.
- // NOTE: taking this out results in lots of increased memory usage! This is
- // because frameDetached is NOT like wilLClose. The latter happens between
- // navigations, but the former only happens when the RenderView is going away.
- autofill_helper_->FrameWillClose(frame);
+ FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame));
}
bool RenderView::allowImages(WebFrame* frame, bool enabled_per_settings) {
@@ -3550,11 +3455,8 @@ void RenderView::didFinishDocumentLoad(WebFrame* frame) {
Send(new ViewHostMsg_DocumentLoadedInFrame(routing_id_, frame->identifier()));
- page_click_tracker_->StartTrackingFrame(frame);
- // The document has now been fully loaded. Scan for forms to be sent up to
- // the browser.
- autofill_helper_->FrameContentsAvailable(frame);
- password_autocomplete_manager_->SendPasswordForms(frame, false);
+ FOR_EACH_OBSERVER(
+ RenderViewObserver, observers_, DidFinishDocumentLoad(frame));
// Check whether we have new encoding name.
UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
@@ -3605,8 +3507,7 @@ void RenderView::didFinishLoad(WebFrame* frame) {
navigation_state->set_finish_load_time(Time::Now());
navigation_state->user_script_idle_scheduler()->DidFinishLoad();
- // Let the password manager know which password forms are actually visible.
- password_autocomplete_manager_->SendPasswordForms(frame, true);
+ FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidFinishLoad(frame));
Send(new ViewHostMsg_DidFinishLoad(routing_id_, frame->identifier()));
}
@@ -4720,12 +4621,6 @@ void RenderView::OnDragSourceSystemDragEnded() {
webview()->dragSourceSystemDragEnded();
}
-void RenderView::OnFillPasswordForm(
- const webkit_glue::PasswordFormFillData& form_data) {
- password_autocomplete_manager_->ReceivedPasswordFormFillData(webview(),
- form_data);
-}
-
void RenderView::OnDragTargetDragEnter(const WebDropData& drop_data,
const gfx::Point& client_point,
const gfx::Point& screen_point,
@@ -5502,7 +5397,7 @@ void RenderView::DidHandleKeyEvent() {
}
void RenderView::DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {
- page_click_tracker_->DidHandleMouseEvent(event);
+ FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidHandleMouseEvent(event));
}
#if defined(OS_MACOSX)
@@ -5660,27 +5555,26 @@ void RenderView::OnPageTranslated() {
if (!frame)
return;
- // The page is translated, so try to extract the form data again.
- autofill_helper_->FrameContentsAvailable(frame);
+ FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameTranslated(frame));
}
WebKit::WebGeolocationClient* RenderView::geolocationClient() {
- if (!geolocation_dispatcher_.get())
- geolocation_dispatcher_.reset(new GeolocationDispatcher(this));
- return geolocation_dispatcher_.get();
+ if (!geolocation_dispatcher_)
+ geolocation_dispatcher_ = new GeolocationDispatcher(this);
+ return geolocation_dispatcher_;
}
WebKit::WebSpeechInputController* RenderView::speechInputController(
WebKit::WebSpeechInputListener* listener) {
- if (!speech_input_dispatcher_.get())
- speech_input_dispatcher_.reset(new SpeechInputDispatcher(this, listener));
- return speech_input_dispatcher_.get();
+ if (!speech_input_dispatcher_)
+ speech_input_dispatcher_ = new SpeechInputDispatcher(this, listener);
+ return speech_input_dispatcher_;
}
WebKit::WebDeviceOrientationClient* RenderView::deviceOrientationClient() {
- if (!device_orientation_dispatcher_.get())
- device_orientation_dispatcher_.reset(new DeviceOrientationDispatcher(this));
- return device_orientation_dispatcher_.get();
+ if (!device_orientation_dispatcher_)
+ device_orientation_dispatcher_ = new DeviceOrientationDispatcher(this);
+ return device_orientation_dispatcher_;
}
void RenderView::zoomLimitsChanged(double minimum_level, double maximum_level) {
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 414cff8..0d91208 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -17,6 +17,7 @@
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/linked_ptr.h"
+#include "base/observer_list.h"
#include "base/timer.h"
#include "base/weak_ptr.h"
#include "build/build_config.h"
@@ -35,7 +36,6 @@
#include "chrome/renderer/renderer_webcookiejar_impl.h"
#include "chrome/renderer/searchbox.h"
#include "chrome/renderer/translate_helper.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebAutoFillClient.h"
#include "third_party/WebKit/WebKit/chromium/public/WebConsoleMessage.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileSystem.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrameClient.h"
@@ -55,7 +55,6 @@
#endif
class AudioMessageFilter;
-class AutoFillHelper;
class BlockedPlugin;
class CustomMenuListener;
class DictionaryValue;
@@ -73,10 +72,9 @@ class ListValue;
class LoadProgressTracker;
class NavigationState;
class NotificationProvider;
-class PageClickTracker;
-class PasswordAutocompleteManager;
class PepperDeviceTest;
class PrintWebViewHelper;
+class RenderViewObserver;
class RenderViewVisitor;
class SkBitmap;
class SpeechInputDispatcher;
@@ -174,7 +172,6 @@ typedef base::RefCountedData<int> SharedRenderViewCounter;
// communication interface with an embedding application process
//
class RenderView : public RenderWidget,
- public WebKit::WebAutoFillClient,
public WebKit::WebViewClient,
public WebKit::WebFrameClient,
public WebKit::WebPageSerializerClient,
@@ -239,10 +236,6 @@ class RenderView : public RenderWidget,
send_content_state_immediately_ = value;
}
- PageClickTracker* page_click_tracker() const {
- return page_click_tracker_.get();
- }
-
// May be NULL if client-side phishing detection is disabled.
safe_browsing::PhishingClassifierDelegate*
phishing_classifier_delegate() const {
@@ -261,6 +254,10 @@ class RenderView : public RenderWidget,
return search_box_;
}
+ // Functions to add and remove observers for this object.
+ void AddObserver(RenderViewObserver* observer);
+ void RemoveObserver(RenderViewObserver* observer);
+
// Called from JavaScript window.external.AddSearchProvider() to add a
// keyword for a provider described in the given OpenSearch document.
void AddSearchProvider(const std::string& url,
@@ -397,30 +394,6 @@ class RenderView : public RenderWidget,
virtual bool OnMessageReceived(const IPC::Message& msg);
- // WebKit::WebAutoFillClient implementation ----------------------------------
- virtual void didAcceptAutoFillSuggestion(const WebKit::WebNode& node,
- const WebKit::WebString& value,
- const WebKit::WebString& label,
- int unique_id,
- unsigned index);
- virtual void didSelectAutoFillSuggestion(const WebKit::WebNode& node,
- const WebKit::WebString& value,
- const WebKit::WebString& label,
- int unique_id);
- virtual void didClearAutoFillSelection(const WebKit::WebNode& node);
- virtual void didAcceptAutocompleteSuggestion(
- const WebKit::WebInputElement& element);
- virtual void removeAutocompleteSuggestion(const WebKit::WebString& name,
- const WebKit::WebString& value);
- // TODO(jam): remove this function after WebKit roll
- virtual void removeAutofillSuggestions(const WebKit::WebString& name,
- const WebKit::WebString& value);
- virtual void textFieldDidEndEditing(const WebKit::WebInputElement& element);
- virtual void textFieldDidChange(const WebKit::WebInputElement& element);
- virtual void textFieldDidReceiveKeyDown(
- const WebKit::WebInputElement& element,
- const WebKit::WebKeyboardEvent& event);
-
// WebKit::WebWidgetClient implementation ------------------------------------
// Most methods are handled by RenderWidget.
@@ -760,22 +733,18 @@ class RenderView : public RenderWidget,
};
RenderView(RenderThreadBase* render_thread,
- const WebPreferences& webkit_preferences,
- int64 session_storage_namespace_id);
+ gfx::NativeViewId parent_hwnd,
+ int32 opener_id,
+ const RendererPreferences& renderer_prefs,
+ const WebPreferences& webkit_prefs,
+ SharedRenderViewCounter* counter,
+ int32 routing_id,
+ int64 session_storage_namespace_id,
+ const string16& frame_name);
// Do not delete directly. This class is reference counted.
virtual ~RenderView();
- // Initializes this view with the given parent and ID. The |routing_id| can be
- // set to 'MSG_ROUTING_NONE' if the true ID is not yet known. In this case,
- // CompleteInit must be called later with the true ID.
- void Init(gfx::NativeViewId parent,
- int32 opener_id,
- const RendererPreferences& renderer_prefs,
- SharedRenderViewCounter* counter,
- int32 routing_id,
- const string16& frame_name);
-
void UpdateURL(WebKit::WebFrame* frame);
void UpdateTitle(WebKit::WebFrame* frame, const string16& title);
void UpdateSessionHistory(WebKit::WebFrame* frame);
@@ -833,10 +802,6 @@ class RenderView : public RenderWidget,
void AddGURLSearchProvider(const GURL& osd_url,
const ViewHostMsg_PageHasOSDD_Type& provider_type);
- // Called in a posted task by textFieldDidChange() to work-around a WebKit bug
- // http://bugs.webkit.org/show_bug.cgi?id=16976
- void TextFieldDidChangeImpl(const WebKit::WebInputElement& element);
-
// Send queued accessibility notifications from the renderer to the browser.
void SendPendingAccessibilityNotifications();
@@ -856,18 +821,6 @@ class RenderView : public RenderWidget,
void OnAsyncFileOpened(base::PlatformFileError error_code,
IPC::PlatformFileForTransit file_for_transit,
int message_id);
- void OnAutocompleteSuggestionsReturned(
- int query_id,
- const std::vector<string16>& suggestions,
- int default_suggestions_index);
- void OnAutoFillFormDataFilled(int query_id,
- const webkit_glue::FormData& form);
- void OnAutoFillSuggestionsReturned(
- int query_id,
- const std::vector<string16>& values,
- const std::vector<string16>& labels,
- const std::vector<string16>& icons,
- const std::vector<int>& unique_ids);
void OnCancelDownload(int32 download_id);
void OnClearFocusedNode();
void OnClosePage(const ViewMsg_ClosePage_Params& params);
@@ -949,8 +902,6 @@ class RenderView : public RenderWidget,
void OnMoveOrResizeStarted();
void OnNavigate(const ViewMsg_Navigate_Params& params);
void OnNotifyRendererViewType(ViewType::Type view_type);
- void OnFillPasswordForm(
- const webkit_glue::PasswordFormFillData& form_data);
void OnPaste();
#if defined(OS_MACOSX)
void OnPluginImeCompositionConfirmed(const string16& text, int plugin_id);
@@ -1386,36 +1337,35 @@ class RenderView : public RenderWidget,
// Helper objects ------------------------------------------------------------
ScopedRunnableMethodFactory<RenderView> page_info_method_factory_;
- ScopedRunnableMethodFactory<RenderView> autofill_method_factory_;
ScopedRunnableMethodFactory<RenderView> accessibility_method_factory_;
// Responsible for translating the page contents to other languages.
TranslateHelper translate_helper_;
- // Responsible for automatically filling login and password textfields.
- scoped_ptr<PasswordAutocompleteManager> password_autocomplete_manager_;
-
- // Responsible for filling forms (AutoFill) and single text entries
- // (Autocomplete).
- scoped_ptr<AutoFillHelper> autofill_helper_;
-
- // Tracks when text input controls get clicked.
- // IMPORTANT: this should be declared after autofill_helper_ and
- // password_autocomplete_manager_ so the tracker is deleted first (so we won't
- // run the risk of notifying deleted objects).
- scoped_ptr<PageClickTracker> page_click_tracker_;
-
RendererWebCookieJarImpl cookie_jar_;
+ // The next group of objects all implement RenderViewObserver, so are deleted
+ // along with the RenderView automatically. This is why we just store weak
+ // references.
+
// Provides access to this renderer from the remote Inspector UI.
- scoped_ptr<DevToolsAgent> devtools_agent_;
+ DevToolsAgent* devtools_agent_;
// DevToolsClient for renderer hosting developer tools UI. It's NULL for other
// render views.
- scoped_ptr<DevToolsClient> devtools_client_;
+ DevToolsClient* devtools_client_;
// Holds a reference to the service which provides desktop notifications.
- scoped_ptr<NotificationProvider> notification_provider_;
+ NotificationProvider* notification_provider_;
+
+ // The geolocation dispatcher attached to this view, lazily initialized.
+ GeolocationDispatcher* geolocation_dispatcher_;
+
+ // The speech dispatcher attached to this view, lazily initialized.
+ SpeechInputDispatcher* speech_input_dispatcher_;
+
+ // Device orientation dispatcher attached to this view; lazily initialized.
+ DeviceOrientationDispatcher* device_orientation_dispatcher_;
// PrintWebViewHelper handles printing. Note that this object is constructed
// when printing for the first time but only destroyed with the RenderView.
@@ -1423,9 +1373,6 @@ class RenderView : public RenderWidget,
scoped_refptr<AudioMessageFilter> audio_message_filter_;
- // The geolocation dispatcher attached to this view, lazily initialized.
- scoped_ptr<GeolocationDispatcher> geolocation_dispatcher_;
-
// Handles accessibility requests into the renderer side, as well as
// maintains the cache and other features of the accessibility tree.
scoped_ptr<WebKit::WebAccessibilityCache> accessibility_;
@@ -1438,12 +1385,6 @@ class RenderView : public RenderWidget,
// Set if we are waiting for a accessibility notification ack.
bool accessibility_ack_pending_;
- // The speech dispatcher attached to this view, lazily initialized.
- scoped_ptr<SpeechInputDispatcher> speech_input_dispatcher_;
-
- // Device orientation dispatcher attached to this view; lazily initialized.
- scoped_ptr<DeviceOrientationDispatcher> device_orientation_dispatcher_;
-
// Responsible for sending page load related histograms.
PageLoadHistograms page_load_histograms_;
@@ -1529,11 +1470,17 @@ class RenderView : public RenderWidget,
// Reports load progress to the browser.
scoped_ptr<LoadProgressTracker> load_progress_tracker_;
+ // All the registered observers. We expect this list to be small, so vector
+ // is fine.
+ ObserverList<RenderViewObserver> observers_;
+
// ---------------------------------------------------------------------------
// ADDING NEW DATA? Please see if it fits appropriately in one of the above
// sections rather than throwing it randomly at the end. If you're adding a
// bunch of stuff, you should probably create a helper class and put your
- // data and methods on that to avoid bloating RenderView more.
+ // data and methods on that to avoid bloating RenderView more. You can use
+ // the Observer interface to filter IPC messages and receive frame change
+ // notifications.
// ---------------------------------------------------------------------------
DISALLOW_COPY_AND_ASSIGN(RenderView);
diff --git a/chrome/renderer/render_view_browsertest.cc b/chrome/renderer/render_view_browsertest.cc
index 379407d..01298b8 100644
--- a/chrome/renderer/render_view_browsertest.cc
+++ b/chrome/renderer/render_view_browsertest.cc
@@ -12,6 +12,7 @@
#include "chrome/common/native_web_keyboard_event.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
+#include "chrome/renderer/autofill_helper.h"
#include "chrome/renderer/print_web_view_helper.h"
#include "chrome/test/render_view_test.h"
#include "gfx/codec/jpeg_codec.h"
@@ -1025,7 +1026,7 @@ TEST_F(RenderViewTest, SendForms) {
// Verify that "FormsSeen" sends the expected number of fields.
ProcessPendingMessages();
- const IPC::Message* message = render_thread_.sink().GetUniqueMessageMatching(
+ const IPC::Message* message = render_thread_.sink().GetFirstMessageMatching(
ViewHostMsg_FormsSeen::ID);
ASSERT_NE(static_cast<IPC::Message*>(NULL), message);
ViewHostMsg_FormsSeen::Param params;
@@ -1065,11 +1066,12 @@ TEST_F(RenderViewTest, SendForms) {
// Accept suggestion that contains a label. Labeled items indicate AutoFill
// as opposed to Autocomplete. We're testing this distinction below with
// the |ViewHostMsg_FillAutoFillFormData::ID| message.
- view_->didAcceptAutoFillSuggestion(firstname,
- WebKit::WebString::fromUTF8("Johnny"),
- WebKit::WebString::fromUTF8("Home"),
- 1,
- -1);
+ autofill_helper_->didAcceptAutoFillSuggestion(
+ firstname,
+ WebKit::WebString::fromUTF8("Johnny"),
+ WebKit::WebString::fromUTF8("Home"),
+ 1,
+ -1);
ProcessPendingMessages();
const IPC::Message* message2 = render_thread_.sink().GetUniqueMessageMatching(
@@ -1115,7 +1117,7 @@ TEST_F(RenderViewTest, FillFormElement) {
// Verify that "FormsSeen" sends the expected number of fields.
ProcessPendingMessages();
- const IPC::Message* message = render_thread_.sink().GetUniqueMessageMatching(
+ const IPC::Message* message = render_thread_.sink().GetFirstMessageMatching(
ViewHostMsg_FormsSeen::ID);
ASSERT_NE(static_cast<IPC::Message*>(NULL), message);
ViewHostMsg_FormsSeen::Param params;
@@ -1150,11 +1152,12 @@ TEST_F(RenderViewTest, FillFormElement) {
// Accept a suggestion in a form that has been auto-filled. This triggers
// the direct filling of the firstname element with value parameter.
- view_->didAcceptAutoFillSuggestion(firstname,
- WebKit::WebString::fromUTF8("David"),
- WebKit::WebString(),
- 0,
- 0);
+ autofill_helper_->didAcceptAutoFillSuggestion(
+ firstname,
+ WebKit::WebString::fromUTF8("David"),
+ WebKit::WebString(),
+ 0,
+ 0);
ProcessPendingMessages();
const IPC::Message* message2 = render_thread_.sink().GetUniqueMessageMatching(
diff --git a/chrome/renderer/render_view_observer.cc b/chrome/renderer/render_view_observer.cc
new file mode 100644
index 0000000..7e771e3
--- /dev/null
+++ b/chrome/renderer/render_view_observer.cc
@@ -0,0 +1,33 @@
+// Copyright (c) 2011 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/render_view_observer.h"
+
+#include "chrome/renderer/render_view.h"
+
+RenderViewObserver::RenderViewObserver(RenderView* render_view)
+ : render_view_(render_view), routing_id_(render_view->routing_id()) {
+ render_view_->AddObserver(this);
+}
+
+RenderViewObserver::~RenderViewObserver() {
+ if (render_view_)
+ render_view_->RemoveObserver(this);
+}
+
+void RenderViewObserver::OnDestruct() {
+ delete this;
+}
+
+bool RenderViewObserver::OnMessageReceived(const IPC::Message& message) {
+ return false;
+}
+
+bool RenderViewObserver::Send(IPC::Message* message) {
+ if (render_view_)
+ return render_view_->Send(message);
+
+ delete message;
+ return false;
+}
diff --git a/chrome/renderer/render_view_observer.h b/chrome/renderer/render_view_observer.h
new file mode 100644
index 0000000..be0d85f
--- /dev/null
+++ b/chrome/renderer/render_view_observer.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2011 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_RENDER_VIEW_OBSERVER_H_
+#define CHROME_RENDERER_RENDER_VIEW_OBSERVER_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "ipc/ipc_channel.h"
+
+class RenderView;
+
+namespace WebKit {
+class WebFrame;
+class WebMouseEvent;
+}
+
+// Base class for objects that want to filter incoming IPCs, and also get
+// notified of changes to the frame.
+class RenderViewObserver : public IPC::Channel::Listener,
+ public IPC::Message::Sender {
+ public:
+ // By default, observers will be deleted when the RenderView goes away. If
+ // they want to outlive it, they can override this function.
+ virtual void OnDestruct();
+
+ // These match the WebKit API notifications.
+ virtual void DidFinishDocumentLoad(WebKit::WebFrame* frame) {}
+ virtual void DidFinishLoad(WebKit::WebFrame* frame) {}
+ virtual void FrameDetached(WebKit::WebFrame* frame) {}
+ virtual void FrameWillClose(WebKit::WebFrame* frame) {}
+
+ // These match the RenderView methods below.
+ virtual void FrameTranslated(WebKit::WebFrame* frame) {}
+ virtual void DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {}
+
+ protected:
+ RenderViewObserver(RenderView* render_view);
+ virtual ~RenderViewObserver();
+
+ // IPC::Channel::Listener implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message);
+
+ // IPC::Message::Sender implementation.
+ virtual bool Send(IPC::Message* message);
+
+ RenderView* render_view() { return render_view_; }
+ int routing_id() { return routing_id_; }
+
+ private:
+ friend class RenderView;
+
+ void set_render_view(RenderView* rv) { render_view_ = rv; }
+
+ RenderView* render_view_;
+ // The routing ID of the associated RenderView.
+ int routing_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderViewObserver);
+};
+
+#endif // CHROME_RENDERER_RENDER_VIEW_OBSERVER_H_
diff --git a/chrome/renderer/speech_input_dispatcher.cc b/chrome/renderer/speech_input_dispatcher.cc
index d119621..6ce90b3 100644
--- a/chrome/renderer/speech_input_dispatcher.cc
+++ b/chrome/renderer/speech_input_dispatcher.cc
@@ -15,8 +15,9 @@
using WebKit::WebFrame;
SpeechInputDispatcher::SpeechInputDispatcher(
- RenderView* render_view, WebKit::WebSpeechInputListener* listener)
- : render_view_(render_view),
+ RenderView* render_view,
+ WebKit::WebSpeechInputListener* listener)
+ : RenderViewObserver(render_view),
listener_(listener) {
}
@@ -40,11 +41,11 @@ bool SpeechInputDispatcher::startRecognition(
const WebKit::WebString& language,
const WebKit::WebString& grammar) {
VLOG(1) << "SpeechInputDispatcher::startRecognition enter";
- gfx::Size scroll = render_view_->webview()->mainFrame()->scrollOffset();
+ gfx::Size scroll = render_view()->webview()->mainFrame()->scrollOffset();
gfx::Rect rect = element_rect;
rect.Offset(-scroll.width(), -scroll.height());
- render_view_->Send(new ViewHostMsg_SpeechInput_StartRecognition(
- render_view_->routing_id(), request_id, rect,
+ Send(new ViewHostMsg_SpeechInput_StartRecognition(
+ routing_id(), request_id, rect,
UTF16ToUTF8(language), UTF16ToUTF8(grammar)));
VLOG(1) << "SpeechInputDispatcher::startRecognition exit";
return true;
@@ -52,15 +53,13 @@ bool SpeechInputDispatcher::startRecognition(
void SpeechInputDispatcher::cancelRecognition(int request_id) {
VLOG(1) << "SpeechInputDispatcher::cancelRecognition enter";
- render_view_->Send(new ViewHostMsg_SpeechInput_CancelRecognition(
- render_view_->routing_id(), request_id));
+ Send(new ViewHostMsg_SpeechInput_CancelRecognition(routing_id(), request_id));
VLOG(1) << "SpeechInputDispatcher::cancelRecognition exit";
}
void SpeechInputDispatcher::stopRecording(int request_id) {
VLOG(1) << "SpeechInputDispatcher::stopRecording enter";
- render_view_->Send(new ViewHostMsg_SpeechInput_StopRecording(
- render_view_->routing_id(), request_id));
+ Send(new ViewHostMsg_SpeechInput_StopRecording(routing_id(), request_id));
VLOG(1) << "SpeechInputDispatcher::stopRecording exit";
}
diff --git a/chrome/renderer/speech_input_dispatcher.h b/chrome/renderer/speech_input_dispatcher.h
index e993226..d5a3ce4 100644
--- a/chrome/renderer/speech_input_dispatcher.h
+++ b/chrome/renderer/speech_input_dispatcher.h
@@ -7,28 +7,26 @@
#include "base/basictypes.h"
#include "chrome/common/speech_input_result.h"
-#include "ipc/ipc_channel.h"
+#include "chrome/renderer/render_view_observer.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSpeechInputController.h"
class GURL;
-class RenderView;
namespace WebKit {
class WebSpeechInputListener;
-class WebString;
-struct WebRect;
}
// SpeechInputDispatcher is a delegate for speech input messages used by WebKit.
// It's the complement of SpeechInputDispatcherHost (owned by RenderViewHost).
-class SpeechInputDispatcher : public WebKit::WebSpeechInputController,
- public IPC::Channel::Listener {
+class SpeechInputDispatcher : public RenderViewObserver,
+ public WebKit::WebSpeechInputController {
public:
SpeechInputDispatcher(RenderView* render_view,
WebKit::WebSpeechInputListener* listener);
- // IPC::Channel::Listener implementation.
- bool OnMessageReceived(const IPC::Message& msg);
+ private:
+ // RenderView::Observer implementation.
+ bool OnMessageReceived(const IPC::Message& message);
// WebKit::WebSpeechInputController.
virtual bool startRecognition(int request_id,
@@ -39,13 +37,11 @@ class SpeechInputDispatcher : public WebKit::WebSpeechInputController,
virtual void cancelRecognition(int request_id);
virtual void stopRecording(int request_id);
- private:
void OnSpeechRecognitionResult(
int request_id, const speech_input::SpeechInputResultArray& result);
void OnSpeechRecordingComplete(int request_id);
void OnSpeechRecognitionComplete(int request_id);
- RenderView* render_view_;
WebKit::WebSpeechInputListener* listener_;
DISALLOW_COPY_AND_ASSIGN(SpeechInputDispatcher);
diff --git a/chrome/test/render_view_test.cc b/chrome/test/render_view_test.cc
index 47a7c53..bfacc61 100644
--- a/chrome/test/render_view_test.cc
+++ b/chrome/test/render_view_test.cc
@@ -11,11 +11,13 @@
#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
#include "chrome/common/renderer_preferences.h"
+#include "chrome/renderer/autofill_helper.h"
#include "chrome/renderer/extensions/event_bindings.h"
#include "chrome/renderer/extensions/extension_process_bindings.h"
#include "chrome/renderer/extensions/js_only_v8_extensions.h"
#include "chrome/renderer/extensions/renderer_extension_bindings.h"
#include "chrome/renderer/mock_render_process.h"
+#include "chrome/renderer/password_autocomplete_manager.h"
#include "chrome/renderer/renderer_main_platform_delegate.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
@@ -135,6 +137,12 @@ void RenderViewTest::SetUp() {
// Attach a pseudo keyboard device to this object.
mock_keyboard_.reset(new MockKeyboard());
+
+ // RenderView doesn't expose it's PasswordAutocompleteManager or
+ // AutoFillHelper objects, because it has no need to store them directly
+ // (they're stored as RenderViewObserver*). So just create another set.
+ password_autocomplete_ = new PasswordAutocompleteManager(view_);
+ autofill_helper_ = new AutoFillHelper(view_, password_autocomplete_);
}
void RenderViewTest::TearDown() {
@@ -245,7 +253,7 @@ void RenderViewTest::SendNativeKeyEvent(
scoped_ptr<IPC::Message> input_message(new ViewMsg_HandleInputEvent(0));
input_message->WriteData(reinterpret_cast<const char*>(&key_event),
sizeof(WebKit::WebKeyboardEvent));
- view_->OnHandleInputEvent(*input_message);
+ view_->OnMessageReceived(*input_message);
}
void RenderViewTest::VerifyPageCount(int count) {
@@ -338,8 +346,9 @@ bool RenderViewTest::SimulateElementClick(const std::string& element_id) {
mouse_event.y = bounds.CenterPoint().y();
mouse_event.clickCount = 1;
ViewMsg_HandleInputEvent input_event(0);
- input_event.WriteData(reinterpret_cast<const char*>(&mouse_event),
- sizeof(WebMouseEvent));
- view_->OnHandleInputEvent(input_event);
+ scoped_ptr<IPC::Message> input_message(new ViewMsg_HandleInputEvent(0));
+ input_message->WriteData(reinterpret_cast<const char*>(&mouse_event),
+ sizeof(WebMouseEvent));
+ view_->OnMessageReceived(*input_message);
return true;
}
diff --git a/chrome/test/render_view_test.h b/chrome/test/render_view_test.h
index bb3e498..3528d40 100644
--- a/chrome/test/render_view_test.h
+++ b/chrome/test/render_view_test.h
@@ -21,7 +21,9 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
+class AutoFillHelper;
class MockRenderProcess;
+class PasswordAutocompleteManager;
class RenderViewTest : public testing::Test {
public:
@@ -99,6 +101,9 @@ class RenderViewTest : public testing::Test {
scoped_ptr<MainFunctionParams> params_;
scoped_ptr<CommandLine> command_line_;
scoped_ptr<SandboxInitWrapper> sandbox_init_wrapper_;
+
+ PasswordAutocompleteManager* password_autocomplete_;
+ AutoFillHelper* autofill_helper_;
};
#endif // CHROME_TEST_RENDER_VIEW_TEST_H_