Index: chrome/renderer/render_view.cc |
=================================================================== |
--- chrome/renderer/render_view.cc (revision 71253) |
+++ chrome/renderer/render_view.cc (working copy) |
@@ -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 @@ |
}; |
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 @@ |
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 @@ |
// 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 @@ |
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 @@ |
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 @@ |
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 @@ |
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,91 +967,16 @@ |
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)); |
- |
- // TODO(jam): remove this once WebKit is rolled |
-#if defined(WEBKIT_HAS_WEB_AUTO_FILL_CLIENT) |
- webwidget_ = WebView::create(this, devtools_agent_.get(), this); |
-#else |
- webwidget_ = WebView::create(this, devtools_agent_.get()); |
-#endif |
- 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) |
@@ -1024,7 +1022,6 @@ |
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) |
@@ -1058,10 +1055,6 @@ |
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) |
@@ -1383,12 +1376,6 @@ |
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); |
@@ -1509,8 +1496,8 @@ |
} |
void RenderView::OnSetupDevToolsClient() { |
- DCHECK(!devtools_client_.get()); |
- devtools_client_.reset(new DevToolsClient(this)); |
+ DCHECK(!devtools_client_); |
+ devtools_client_ = new DevToolsClient(this); |
} |
void RenderView::OnUpdateTargetURLAck() { |
@@ -1987,21 +1974,6 @@ |
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; |
} |
@@ -2191,7 +2163,7 @@ |
} |
WebKit::WebNotificationPresenter* RenderView::notificationPresenter() { |
- return notification_provider_.get(); |
+ return notification_provider_; |
} |
void RenderView::didStartLoading() { |
@@ -2296,29 +2268,6 @@ |
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; |
@@ -2346,13 +2295,6 @@ |
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; |
@@ -2645,43 +2587,6 @@ |
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() { |
@@ -2937,8 +2842,7 @@ |
} |
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) { |
@@ -2948,11 +2852,7 @@ |
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) { |
@@ -3546,11 +3446,8 @@ |
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()); |
@@ -3601,8 +3498,7 @@ |
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())); |
} |
@@ -4716,12 +4612,6 @@ |
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, |
@@ -5494,7 +5384,7 @@ |
} |
void RenderView::DidHandleMouseEvent(const WebKit::WebMouseEvent& event) { |
- page_click_tracker_->DidHandleMouseEvent(event); |
+ FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidHandleMouseEvent(event)); |
} |
#if defined(OS_MACOSX) |
@@ -5652,27 +5542,26 @@ |
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) { |