blob: 113ca88cfec98b8f1841b6129b83d781f10fcb5a [file] [log] [blame]
[email protected]05d478752009-04-08 23:38:161// Copyright (c) 2009 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/renderer/render_view.h"
6
7#include <algorithm>
8#include <string>
9#include <vector>
10
[email protected]91e81ae2009-05-08 22:14:3811#include "app/gfx/color_utils.h"
[email protected]37126212009-05-06 02:23:3112#include "app/gfx/favicon_size.h"
[email protected]a92b8642009-05-05 23:38:5613#include "app/l10n_util.h"
[email protected]37126212009-05-06 02:23:3114#include "app/message_box_flags.h"
[email protected]9929da92009-05-05 02:05:1115#include "app/resource_bundle.h"
initial.commit09911bf2008-07-26 23:55:2916#include "base/command_line.h"
[email protected]bb063b72009-03-27 23:18:5017#include "base/compiler_specific.h"
[email protected]4646f292009-05-20 03:49:0518#include "base/field_trial.h"
initial.commit09911bf2008-07-26 23:55:2919#include "base/gfx/png_encoder.h"
[email protected]18bcc3c2009-01-27 21:39:1520#include "base/gfx/native_widget_types.h"
initial.commit09911bf2008-07-26 23:55:2921#include "base/string_piece.h"
22#include "base/string_util.h"
[email protected]6c8afae52009-01-22 02:24:5723#include "build/build_config.h"
[email protected]81e63782009-02-27 19:35:0924#include "chrome/common/bindings_policy.h"
initial.commit09911bf2008-07-26 23:55:2925#include "chrome/common/chrome_switches.h"
[email protected]f0af6a72009-05-30 05:25:1726#include "chrome/common/chrome_constants.h"
initial.commit09911bf2008-07-26 23:55:2927#include "chrome/common/jstemplate_builder.h"
[email protected]630e26b2008-10-14 22:55:1728#include "chrome/common/page_zoom.h"
[email protected]e09ba552009-02-05 03:26:2929#include "chrome/common/render_messages.h"
[email protected]9b6f40e2009-06-11 15:54:2630#include "chrome/common/renderer_preferences.h"
initial.commit09911bf2008-07-26 23:55:2931#include "chrome/common/thumbnail_score.h"
[email protected]6de74452009-02-25 18:04:5932#include "chrome/common/url_constants.h"
initial.commit09911bf2008-07-26 23:55:2933#include "chrome/renderer/about_handler.h"
[email protected]5fb88962009-04-16 19:03:2534#include "chrome/renderer/audio_message_filter.h"
initial.commit09911bf2008-07-26 23:55:2935#include "chrome/renderer/debug_message_handler.h"
[email protected]e4ac5df2009-03-17 15:33:1136#include "chrome/renderer/devtools_agent.h"
37#include "chrome/renderer/devtools_client.h"
[email protected]309d7a282009-03-24 09:18:2738#include "chrome/renderer/extensions/extension_process_bindings.h"
initial.commit09911bf2008-07-26 23:55:2939#include "chrome/renderer/localized_error.h"
[email protected]6f56d482009-02-20 05:02:5640#include "chrome/renderer/media/audio_renderer_impl.h"
[email protected]add51772009-06-11 18:25:1741#include "chrome/renderer/media/buffered_data_source.h"
[email protected]d81c1e52009-06-03 22:09:5042#include "chrome/renderer/print_web_view_helper.h"
[email protected]39008c02009-02-11 23:59:2543#include "chrome/renderer/render_process.h"
[email protected]fcf19542009-03-30 21:24:0744#include "chrome/renderer/renderer_logging.h"
[email protected]0938d3c2009-01-09 20:37:3545#include "chrome/renderer/user_script_slave.h"
initial.commit09911bf2008-07-26 23:55:2946#include "chrome/renderer/visitedlink_slave.h"
[email protected]ba4b17f2009-02-11 21:32:2947#include "chrome/renderer/webplugin_delegate_proxy.h"
[email protected]eb47a132009-03-04 00:39:5648#include "chrome/renderer/webworker_proxy.h"
[email protected]34ac8f32009-02-22 23:03:2749#include "grit/generated_resources.h"
50#include "grit/renderer_resources.h"
[email protected]f11ca0732009-04-11 00:09:3451#include "net/base/data_url.h"
initial.commit09911bf2008-07-26 23:55:2952#include "net/base/escape.h"
53#include "net/base/net_errors.h"
[email protected]c399a8a2008-11-22 19:38:0054#include "skia/ext/bitmap_platform_device.h"
[email protected]83c9e6552008-12-03 16:22:1055#include "skia/ext/image_operations.h"
[email protected]afdcf5c2009-05-10 20:30:4156#include "webkit/api/public/WebDragData.h"
57#include "webkit/api/public/WebPoint.h"
58#include "webkit/api/public/WebRect.h"
59#include "webkit/api/public/WebScriptSource.h"
60#include "webkit/api/public/WebSize.h"
[email protected]ba4b17f2009-02-11 21:32:2961#include "webkit/default_plugin/default_plugin_shared.h"
initial.commit09911bf2008-07-26 23:55:2962#include "webkit/glue/dom_operations.h"
63#include "webkit/glue/dom_serializer.h"
[email protected]f11ca0732009-04-11 00:09:3464#include "webkit/glue/image_decoder.h"
initial.commit09911bf2008-07-26 23:55:2965#include "webkit/glue/password_form.h"
[email protected]ba4b17f2009-02-11 21:32:2966#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:2967#include "webkit/glue/searchable_form_data.h"
[email protected]6a983b42009-03-20 20:12:2568#include "webkit/glue/webaccessibilitymanager_impl.h"
initial.commit09911bf2008-07-26 23:55:2969#include "webkit/glue/webdatasource.h"
[email protected]611cad42009-03-16 18:51:3470#include "webkit/glue/webdevtoolsagent_delegate.h"
initial.commit09911bf2008-07-26 23:55:2971#include "webkit/glue/webdropdata.h"
72#include "webkit/glue/weberror.h"
73#include "webkit/glue/webframe.h"
initial.commit09911bf2008-07-26 23:55:2974#include "webkit/glue/webkit_glue.h"
[email protected]add51772009-06-11 18:25:1775#include "webkit/glue/webmediaplayer_impl.h"
initial.commit09911bf2008-07-26 23:55:2976#include "webkit/glue/webpreferences.h"
[email protected]b94d3322009-02-12 19:49:0477#include "webkit/glue/webplugin_delegate.h"
initial.commit09911bf2008-07-26 23:55:2978#include "webkit/glue/webresponse.h"
[email protected]00d7e622009-04-21 23:06:0579#include "webkit/glue/webtextinput.h"
initial.commit09911bf2008-07-26 23:55:2980#include "webkit/glue/weburlrequest.h"
81#include "webkit/glue/webview.h"
initial.commit09911bf2008-07-26 23:55:2982
[email protected]6c8afae52009-01-22 02:24:5783#if defined(OS_WIN)
84// TODO(port): these files are currently Windows only because they concern:
[email protected]6c8afae52009-01-22 02:24:5785// * theming
[email protected]6c8afae52009-01-22 02:24:5786#include "base/gfx/native_theme.h"
[email protected]6c8afae52009-01-22 02:24:5787#endif
88
[email protected]c20210e62009-04-03 21:39:2689using base::Time;
[email protected]e1acf6f2008-10-27 20:43:3390using base::TimeDelta;
[email protected]0dea3ea2009-03-31 23:30:5991using WebKit::WebConsoleMessage;
[email protected]e80c73b2009-04-07 23:24:5892using WebKit::WebDragData;
[email protected]b3f2b912009-04-09 16:18:5293using WebKit::WebRect;
[email protected]4f999132009-03-31 18:08:4094using WebKit::WebScriptSource;
[email protected]27ba8532009-04-24 20:22:4395using WebKit::WebWorker;
96using WebKit::WebWorkerClient;
[email protected]e1acf6f2008-10-27 20:43:3397
initial.commit09911bf2008-07-26 23:55:2998//-----------------------------------------------------------------------------
99
100// define to write the time necessary for thumbnail/DOM text retrieval,
101// respectively, into the system debug log
102// #define TIME_BITMAP_RETRIEVAL
103// #define TIME_TEXT_RETRIEVAL
104
105// maximum number of characters in the document to index, any text beyond this
106// point will be clipped
[email protected]6c8afae52009-01-22 02:24:57107static const size_t kMaxIndexChars = 65535;
initial.commit09911bf2008-07-26 23:55:29108
109// Size of the thumbnails that we'll generate
110static const int kThumbnailWidth = 196;
111static const int kThumbnailHeight = 136;
112
113// Delay in milliseconds that we'll wait before capturing the page contents
114// and thumbnail.
115static const int kDelayForCaptureMs = 500;
116
117// Typically, we capture the page data once the page is loaded.
118// Sometimes, the page never finishes to load, preventing the page capture
119// To workaround this problem, we always perform a capture after the following
120// delay.
121static const int kDelayForForcedCaptureMs = 6000;
122
[email protected]81a34412009-01-05 19:17:24123// The default value for RenderView.delay_seconds_for_form_state_sync_, see
124// that variable for more.
125const int kDefaultDelaySecondsForFormStateSync = 5;
initial.commit09911bf2008-07-26 23:55:29126
127// The next available page ID to use. This ensures that the page IDs are
128// globally unique in the renderer.
129static int32 next_page_id_ = 1;
130
[email protected]0aa55312008-10-17 21:53:08131// The maximum number of popups that can be spawned from one page.
132static const int kMaximumNumberOfUnacknowledgedPopups = 25;
133
initial.commit09911bf2008-07-26 23:55:29134static const char* const kUnreachableWebDataURL =
[email protected]60e448982009-05-06 04:21:16135 "chrome://chromewebdata/";
initial.commit09911bf2008-07-26 23:55:29136
[email protected]50b691c2008-10-31 19:08:35137static const char* const kBackForwardNavigationScheme = "history";
138
initial.commit09911bf2008-07-26 23:55:29139// Associated with browser-initiated navigations to hold tracking data.
[email protected]77f17a82009-05-21 04:42:54140class RenderView::NavigationState : public WebDataSource::ExtraData {
initial.commit09911bf2008-07-26 23:55:29141 public:
[email protected]77f17a82009-05-21 04:42:54142 NavigationState(int32 pending_page_id,
143 PageTransition::Type transition,
144 Time request_time)
[email protected]6c8afae52009-01-22 02:24:57145 : transition_type(transition),
[email protected]c20210e62009-04-03 21:39:26146 request_time(request_time),
[email protected]6c8afae52009-01-22 02:24:57147 request_committed(false),
148 pending_page_id_(pending_page_id) {
initial.commit09911bf2008-07-26 23:55:29149 }
150
151 // Contains the page_id for this navigation or -1 if there is none yet.
152 int32 pending_page_id() const { return pending_page_id_; }
153
154 // Is this a new navigation?
155 bool is_new_navigation() const { return pending_page_id_ == -1; }
156
157 // Contains the transition type that the browser specified when it
158 // initiated the load.
159 PageTransition::Type transition_type;
[email protected]77f17a82009-05-21 04:42:54160
161 // The time that this navigation was requested.
[email protected]c20210e62009-04-03 21:39:26162 Time request_time;
initial.commit09911bf2008-07-26 23:55:29163
164 // True if we have already processed the "DidCommitLoad" event for this
165 // request. Used by session history.
166 bool request_committed;
167
168 private:
169 int32 pending_page_id_;
170
[email protected]77f17a82009-05-21 04:42:54171 DISALLOW_COPY_AND_ASSIGN(NavigationState);
initial.commit09911bf2008-07-26 23:55:29172};
173
initial.commit09911bf2008-07-26 23:55:29174///////////////////////////////////////////////////////////////////////////////
175
[email protected]81a34412009-01-05 19:17:24176RenderView::RenderView(RenderThreadBase* render_thread)
177 : RenderWidget(render_thread, true),
[email protected]81e63782009-02-27 19:35:09178 enabled_bindings_(0),
[email protected]e75cb49e2009-01-05 23:13:21179 target_url_status_(TARGET_NONE),
[email protected]81a34412009-01-05 19:17:24180 is_loading_(false),
[email protected]e75cb49e2009-01-05 23:13:21181 navigation_gesture_(NavigationGestureUnknown),
[email protected]81a34412009-01-05 19:17:24182 page_id_(-1),
183 last_page_id_sent_to_browser_(-1),
184 last_indexed_page_id_(-1),
[email protected]81a34412009-01-05 19:17:24185 opened_by_user_gesture_(true),
[email protected]bb063b72009-03-27 23:18:50186 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
[email protected]81a34412009-01-05 19:17:24187 first_default_plugin_(NULL),
[email protected]e4ac5df2009-03-17 15:33:11188 devtools_agent_(NULL),
189 devtools_client_(NULL),
[email protected]81a34412009-01-05 19:17:24190 history_back_list_count_(0),
191 history_forward_list_count_(0),
[email protected]81a34412009-01-05 19:17:24192 has_unload_listener_(false),
193 decrement_shared_popup_at_destruction_(false),
[email protected]81a34412009-01-05 19:17:24194 form_field_autofill_request_id_(0),
195 popup_notification_visible_(false),
[email protected]0666aef2009-05-13 19:48:08196 delay_seconds_for_form_state_sync_(kDefaultDelaySecondsForFormStateSync),
197 preferred_width_(0),
[email protected]9b6f40e2009-06-11 15:54:26198 send_preferred_width_changes_(false) {
initial.commit09911bf2008-07-26 23:55:29199}
200
201RenderView::~RenderView() {
[email protected]0aa55312008-10-17 21:53:08202 if (decrement_shared_popup_at_destruction_)
203 shared_popup_counter_->data--;
204
initial.commit09911bf2008-07-26 23:55:29205 // Clear any back-pointers that might still be held by plugins.
206 PluginDelegateList::iterator it = plugin_delegates_.begin();
207 while (it != plugin_delegates_.end()) {
208 (*it)->DropRenderView();
209 it = plugin_delegates_.erase(it);
210 }
211
[email protected]81a34412009-01-05 19:17:24212 render_thread_->RemoveFilter(debug_message_handler_);
[email protected]5fb88962009-04-16 19:03:25213 render_thread_->RemoveFilter(audio_message_filter_);
initial.commit09911bf2008-07-26 23:55:29214}
215
216/*static*/
[email protected]0aa55312008-10-17 21:53:08217RenderView* RenderView::Create(
[email protected]81a34412009-01-05 19:17:24218 RenderThreadBase* render_thread,
[email protected]18bcc3c2009-01-27 21:39:15219 gfx::NativeViewId parent_hwnd,
[email protected]1c4947f2009-01-15 22:25:11220 base::WaitableEvent* modal_dialog_event,
[email protected]0aa55312008-10-17 21:53:08221 int32 opener_id,
[email protected]80d96fa2009-06-10 22:34:51222 const RendererPreferences& renderer_prefs,
[email protected]0aa55312008-10-17 21:53:08223 const WebPreferences& webkit_prefs,
224 SharedRenderViewCounter* counter,
225 int32 routing_id) {
initial.commit09911bf2008-07-26 23:55:29226 DCHECK(routing_id != MSG_ROUTING_NONE);
[email protected]81a34412009-01-05 19:17:24227 scoped_refptr<RenderView> view = new RenderView(render_thread);
initial.commit09911bf2008-07-26 23:55:29228 view->Init(parent_hwnd,
229 modal_dialog_event,
230 opener_id,
[email protected]80d96fa2009-06-10 22:34:51231 renderer_prefs,
initial.commit09911bf2008-07-26 23:55:29232 webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08233 counter,
initial.commit09911bf2008-07-26 23:55:29234 routing_id); // adds reference
235 return view;
236}
237
238/*static*/
239void RenderView::SetNextPageID(int32 next_page_id) {
240 // This method should only be called during process startup, and the given
241 // page id had better not exceed our current next page id!
[email protected]4646f292009-05-20 03:49:05242 DCHECK_EQ(next_page_id_, 1);
initial.commit09911bf2008-07-26 23:55:29243 DCHECK(next_page_id >= next_page_id_);
244 next_page_id_ = next_page_id;
245}
246
247void RenderView::PluginDestroyed(WebPluginDelegateProxy* proxy) {
248 PluginDelegateList::iterator it =
249 std::find(plugin_delegates_.begin(), plugin_delegates_.end(), proxy);
250 DCHECK(it != plugin_delegates_.end());
251 plugin_delegates_.erase(it);
252 // If the plugin is deleted, we need to clear our reference in case user
253 // clicks the info bar to install. Unfortunately we are getting
254 // PluginDestroyed in single process mode. However, that is not a huge
255 // concern.
256 if (proxy == first_default_plugin_)
257 first_default_plugin_ = NULL;
258}
259
[email protected]690a99c2009-01-06 16:48:45260void RenderView::PluginCrashed(const FilePath& plugin_path) {
initial.commit09911bf2008-07-26 23:55:29261 Send(new ViewHostMsg_CrashedPlugin(routing_id_, plugin_path));
262}
263
264
265void RenderView::JSOutOfMemory() {
266 Send(new ViewHostMsg_JSOutOfMemory(routing_id_));
267}
268
[email protected]18bcc3c2009-01-27 21:39:15269void RenderView::Init(gfx::NativeViewId parent_hwnd,
[email protected]1c4947f2009-01-15 22:25:11270 base::WaitableEvent* modal_dialog_event,
initial.commit09911bf2008-07-26 23:55:29271 int32 opener_id,
[email protected]80d96fa2009-06-10 22:34:51272 const RendererPreferences& renderer_prefs,
initial.commit09911bf2008-07-26 23:55:29273 const WebPreferences& webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08274 SharedRenderViewCounter* counter,
initial.commit09911bf2008-07-26 23:55:29275 int32 routing_id) {
276 DCHECK(!webview());
277
278 if (opener_id != MSG_ROUTING_NONE)
279 opener_id_ = opener_id;
280
[email protected]0aa55312008-10-17 21:53:08281 if (counter) {
282 shared_popup_counter_ = counter;
283 shared_popup_counter_->data++;
284 decrement_shared_popup_at_destruction_ = true;
285 } else {
286 shared_popup_counter_ = new SharedRenderViewCounter(0);
287 decrement_shared_popup_at_destruction_ = false;
288 }
289
[email protected]80d96fa2009-06-10 22:34:51290 OnSetRendererPrefs(renderer_prefs);
291
[email protected]90ca3692009-04-09 16:09:43292 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
293
[email protected]2ef9c452009-05-13 13:03:14294 bool dev_tools_enabled = !command_line.HasSwitch(
295 switches::kDisableOutOfProcessDevTools);
[email protected]90ca3692009-04-09 16:09:43296 if (dev_tools_enabled)
297 devtools_agent_.reset(new DevToolsAgent(routing_id, this));
[email protected]9b9d7282009-04-08 14:13:04298
[email protected]c5b3b5e2009-02-13 06:41:11299 webwidget_ = WebView::Create(this, webkit_prefs);
initial.commit09911bf2008-07-26 23:55:29300
[email protected]2e417c82009-04-02 22:30:26301#if defined(OS_LINUX)
302 // We have to enable ourselves as the editor delegate on linux so we can copy
303 // text selections to the X clipboard.
304 webview()->SetUseEditorDelegate(true);
305#endif
306
initial.commit09911bf2008-07-26 23:55:29307 // Don't let WebCore keep a B/F list - we have our own.
308 // We let it keep 1 entry because FrameLoader::goToItem expects an item in the
309 // backForwardList, which is used only in ASSERTs.
310 webview()->SetBackForwardListSize(1);
311
312 routing_id_ = routing_id;
[email protected]81a34412009-01-05 19:17:24313 render_thread_->AddRoute(routing_id_, this);
initial.commit09911bf2008-07-26 23:55:29314 // Take a reference on behalf of the RenderThread. This will be balanced
315 // when we receive ViewMsg_Close.
316 AddRef();
317
318 // If this is a popup, we must wait for the CreatingNew_ACK message before
319 // completing initialization. Otherwise, we can finish it now.
320 if (opener_id == MSG_ROUTING_NONE) {
321 did_show_ = true;
322 CompleteInit(parent_hwnd);
323 }
324
325 host_window_ = parent_hwnd;
[email protected]1c4947f2009-01-15 22:25:11326 modal_dialog_event_.reset(modal_dialog_event);
initial.commit09911bf2008-07-26 23:55:29327
[email protected]81e63782009-02-27 19:35:09328 if (command_line.HasSwitch(switches::kDomAutomationController))
329 enabled_bindings_ |= BindingsPolicy::DOM_AUTOMATION;
initial.commit09911bf2008-07-26 23:55:29330
331 debug_message_handler_ = new DebugMessageHandler(this);
[email protected]81a34412009-01-05 19:17:24332 render_thread_->AddFilter(debug_message_handler_);
[email protected]5fb88962009-04-16 19:03:25333
334 audio_message_filter_ = new AudioMessageFilter(routing_id_);
335 render_thread_->AddFilter(audio_message_filter_);
initial.commit09911bf2008-07-26 23:55:29336}
337
338void RenderView::OnMessageReceived(const IPC::Message& message) {
[email protected]f8b6b6f2009-03-10 16:48:26339 WebFrame* main_frame = webview() ? webview()->GetMainFrame() : NULL;
340 renderer_logging::ScopedActiveRenderingURLSetter url_setter(
341 main_frame ? main_frame->GetURL() : GURL());
[email protected]f8b6b6f2009-03-10 16:48:26342
[email protected]b2abac72009-02-26 12:39:28343 // If this is developer tools renderer intercept tools messages first.
[email protected]e4ac5df2009-03-17 15:33:11344 if (devtools_client_.get() && devtools_client_->OnMessageReceived(message))
[email protected]b2abac72009-02-26 12:39:28345 return;
[email protected]b4b967e2009-04-22 11:33:05346 if (devtools_agent_.get() && devtools_agent_->OnMessageReceived(message))
347 return;
[email protected]b2abac72009-02-26 12:39:28348
initial.commit09911bf2008-07-26 23:55:29349 IPC_BEGIN_MESSAGE_MAP(RenderView, message)
initial.commit09911bf2008-07-26 23:55:29350 IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)
initial.commit09911bf2008-07-26 23:55:29351 IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)
352 IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
353 IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
354 IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText)
355 IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
356 IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)
357 IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)
358 IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)
359 IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)
360 IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)
361 IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)
[email protected]bbbd545c2008-12-15 20:18:04362 IPC_MESSAGE_HANDLER(ViewMsg_ToggleSpellCheck, OnToggleSpellCheck)
initial.commit09911bf2008-07-26 23:55:29363 IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)
364 IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)
365 IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
366 IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
[email protected]630e26b2008-10-14 22:55:17367 IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
[email protected]ea8c7452009-04-02 20:47:06368 IPC_MESSAGE_HANDLER(ViewMsg_InsertText, OnInsertText)
initial.commit09911bf2008-07-26 23:55:29369 IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
370 IPC_MESSAGE_HANDLER(ViewMsg_InspectElement, OnInspectElement)
371 IPC_MESSAGE_HANDLER(ViewMsg_ShowJavaScriptConsole, OnShowJavaScriptConsole)
[email protected]b2abac72009-02-26 12:39:28372 IPC_MESSAGE_HANDLER(ViewMsg_SetupDevToolsClient, OnSetupDevToolsClient)
initial.commit09911bf2008-07-26 23:55:29373 IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)
374 IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
[email protected]1810e132009-03-24 23:35:48375 IPC_MESSAGE_HANDLER(ViewMsg_CSSInsertRequest, OnCSSInsertRequest)
initial.commit09911bf2008-07-26 23:55:29376 IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)
377 IPC_MESSAGE_HANDLER(ViewMsg_DebugAttach, OnDebugAttach)
[email protected]88010e082008-08-29 11:07:40378 IPC_MESSAGE_HANDLER(ViewMsg_DebugDetach, OnDebugDetach)
initial.commit09911bf2008-07-26 23:55:29379 IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)
380 IPC_MESSAGE_HANDLER(ViewMsg_UploadFile, OnUploadFileRequest)
381 IPC_MESSAGE_HANDLER(ViewMsg_FormFill, OnFormFill)
382 IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)
383 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)
384 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)
385 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)
386 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)
[email protected]18cb2572008-08-21 20:34:45387 IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)
initial.commit09911bf2008-07-26 23:55:29388 IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)
[email protected]266eb6f2008-09-30 23:56:50389 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved,
390 OnDragSourceEndedOrMoved)
initial.commit09911bf2008-07-26 23:55:29391 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,
392 OnDragSourceSystemDragEnded)
393 IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)
394 IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)
395 IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)
396 IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
397 IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)
398 IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)
399 IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
400 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)
401 IPC_MESSAGE_HANDLER(ViewMsg_UpdateBackForwardListCount,
402 OnUpdateBackForwardListCount)
403 IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,
404 OnGetAllSavableResourceLinksForCurrentPage)
[email protected]f09c7182009-03-10 12:54:04405 IPC_MESSAGE_HANDLER(
406 ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,
407 OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)
initial.commit09911bf2008-07-26 23:55:29408 IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)
[email protected]266eb6f2008-09-30 23:56:50409 IPC_MESSAGE_HANDLER(ViewMsg_GetAccessibilityInfo, OnGetAccessibilityInfo)
410 IPC_MESSAGE_HANDLER(ViewMsg_ClearAccessibilityInfo,
411 OnClearAccessibilityInfo)
initial.commit09911bf2008-07-26 23:55:29412 IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose)
413 IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
414 IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)
[email protected]18cb2572008-08-21 20:34:45415 IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,
416 OnMessageFromExternalHost)
[email protected]0aa55312008-10-17 21:53:08417 IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
418 OnDisassociateFromPopupCount)
[email protected]0ebf3872008-11-07 21:35:03419 IPC_MESSAGE_HANDLER(ViewMsg_AutofillSuggestions,
420 OnReceivedAutofillSuggestions)
[email protected]2c4410d2009-05-06 23:46:22421 IPC_MESSAGE_HANDLER(ViewMsg_PopupNotificationVisibilityChanged,
422 OnPopupNotificationVisibilityChanged)
[email protected]30f75e62009-02-25 22:01:00423 IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
[email protected]309d7a282009-03-24 09:18:27424 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionResponse, OnExtensionResponse)
[email protected]05d478752009-04-08 23:38:16425 IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
[email protected]699ab0d2009-04-23 23:19:14426 IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
[email protected]0666aef2009-05-13 19:48:08427 IPC_MESSAGE_HANDLER(ViewMsg_EnableIntrinsicWidthChangedMode,
428 OnEnableIntrinsicWidthChangedMode)
[email protected]80d96fa2009-06-10 22:34:51429 IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
[email protected]634a6f92008-12-01 21:39:31430
initial.commit09911bf2008-07-26 23:55:29431 // Have the super handle all other messages.
432 IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))
433 IPC_END_MESSAGE_MAP()
434}
435
initial.commit09911bf2008-07-26 23:55:29436void RenderView::SendThumbnail() {
437 WebFrame* main_frame = webview()->GetMainFrame();
438 if (!main_frame)
439 return;
440
441 // get the URL for this page
442 GURL url(main_frame->GetURL());
443 if (url.is_empty())
444 return;
445
446 if (size_.IsEmpty())
447 return; // Don't create an empty thumbnail!
448
449 ThumbnailScore score;
450 SkBitmap thumbnail;
[email protected]b6e4bec2008-11-12 01:17:15451 if (!CaptureThumbnail(main_frame, kThumbnailWidth, kThumbnailHeight,
452 &thumbnail, &score))
453 return;
454
initial.commit09911bf2008-07-26 23:55:29455 // send the thumbnail message to the browser process
[email protected]674741932009-02-04 23:44:46456 Send(new ViewHostMsg_Thumbnail(routing_id_, url, score, thumbnail));
initial.commit09911bf2008-07-26 23:55:29457}
458
[email protected]068637222009-01-29 16:58:07459void RenderView::OnPrintPages() {
initial.commit09911bf2008-07-26 23:55:29460 DCHECK(webview());
[email protected]068637222009-01-29 16:58:07461 if (webview()) {
462 // The renderer own the control flow as if it was a window.print() call.
463 ScriptedPrint(webview()->GetMainFrame());
initial.commit09911bf2008-07-26 23:55:29464 }
initial.commit09911bf2008-07-26 23:55:29465}
466
initial.commit09911bf2008-07-26 23:55:29467void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) {
468 if (load_id != page_id_)
469 return; // this capture call is no longer relevant due to navigation
470 if (load_id == last_indexed_page_id_)
471 return; // we already indexed this page
472
473 if (!webview())
474 return;
475
476 WebFrame* main_frame = webview()->GetMainFrame();
477 if (!main_frame)
478 return;
479
480 // Don't index/capture pages that are in view source mode.
481 if (main_frame->GetInViewSourceMode())
482 return;
483
484 // Don't index/capture pages that failed to load. This only checks the top
485 // level frame so the thumbnail may contain a frame that failed to load.
486 WebDataSource* ds = main_frame->GetDataSource();
487 if (ds && ds->HasUnreachableURL())
488 return;
489
490 if (!preliminary_capture)
491 last_indexed_page_id_ = load_id;
492
493 // get the URL for this page
494 GURL url(main_frame->GetURL());
495 if (url.is_empty())
496 return;
497
498 // full text
499 std::wstring contents;
500 CaptureText(main_frame, &contents);
501 if (contents.size()) {
502 // Send the text to the browser for indexing.
503 Send(new ViewHostMsg_PageContents(url, load_id, contents));
504 }
505
506 // thumbnail
507 SendThumbnail();
508}
509
510void RenderView::CaptureText(WebFrame* frame, std::wstring* contents) {
511 contents->clear();
512 if (!frame)
513 return;
514
[email protected]0faf0bd92008-09-09 20:53:27515 // Don't index any https pages. People generally don't want their bank
516 // accounts, etc. indexed on their computer, especially since some of these
517 // things are not marked cachable.
518 // TODO(brettw) we may want to consider more elaborate heuristics such as
519 // the cachability of the page. We may also want to consider subframes (this
520 // test will still index subframes if the subframe is SSL).
521 if (frame->GetURL().SchemeIsSecure())
522 return;
523
initial.commit09911bf2008-07-26 23:55:29524#ifdef TIME_TEXT_RETRIEVAL
525 double begin = time_util::GetHighResolutionTimeNow();
526#endif
527
528 // get the contents of the frame
529 frame->GetContentAsPlainText(kMaxIndexChars, contents);
530
531#ifdef TIME_TEXT_RETRIEVAL
532 double end = time_util::GetHighResolutionTimeNow();
533 char buf[128];
534 sprintf_s(buf, "%d chars retrieved for indexing in %gms\n",
535 contents.size(), (end - begin)*1000);
536 OutputDebugStringA(buf);
537#endif
538
539 // When the contents are clipped to the maximum, we don't want to have a
540 // partial word indexed at the end that might have been clipped. Therefore,
541 // terminate the string at the last space to ensure no words are clipped.
542 if (contents->size() == kMaxIndexChars) {
543 size_t last_space_index = contents->find_last_of(kWhitespaceWide);
544 if (last_space_index == std::wstring::npos)
545 return; // don't index if we got a huge block of text with no spaces
546 contents->resize(last_space_index);
547 }
548}
549
[email protected]b6e4bec2008-11-12 01:17:15550bool RenderView::CaptureThumbnail(WebFrame* frame,
initial.commit09911bf2008-07-26 23:55:29551 int w,
552 int h,
553 SkBitmap* thumbnail,
554 ThumbnailScore* score) {
555#ifdef TIME_BITMAP_RETRIEVAL
556 double begin = time_util::GetHighResolutionTimeNow();
557#endif
558
[email protected]21f527e2008-12-17 23:29:40559 scoped_ptr<skia::BitmapPlatformDevice> device;
[email protected]b6e4bec2008-11-12 01:17:15560 if (!frame->CaptureImage(&device, true))
561 return false;
562
563 const SkBitmap& src_bmp = device->accessBitmap(false);
initial.commit09911bf2008-07-26 23:55:29564
565 SkRect dest_rect;
566 dest_rect.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
567 float dest_aspect = dest_rect.width() / dest_rect.height();
568
569 // Get the src rect so that we can preserve the aspect ratio while filling
570 // the destination.
571 SkIRect src_rect;
572 if (src_bmp.width() < dest_rect.width() ||
573 src_bmp.height() < dest_rect.height()) {
574 // Source image is smaller: we clip the part of source image within the
575 // dest rect, and then stretch it to fill the dest rect. We don't respect
576 // the aspect ratio in this case.
577 src_rect.set(0, 0, static_cast<S16CPU>(dest_rect.width()),
578 static_cast<S16CPU>(dest_rect.height()));
579 score->good_clipping = false;
580 } else {
581 float src_aspect = static_cast<float>(src_bmp.width()) / src_bmp.height();
582 if (src_aspect > dest_aspect) {
583 // Wider than tall, clip horizontally: we center the smaller thumbnail in
584 // the wider screen.
585 S16CPU new_width = static_cast<S16CPU>(src_bmp.height() * dest_aspect);
586 S16CPU x_offset = (src_bmp.width() - new_width) / 2;
587 src_rect.set(x_offset, 0, new_width + x_offset, src_bmp.height());
588 score->good_clipping = false;
589 } else {
590 src_rect.set(0, 0, src_bmp.width(),
591 static_cast<S16CPU>(src_bmp.width() / dest_aspect));
592 score->good_clipping = true;
593 }
594 }
595
[email protected]b3f2b912009-04-09 16:18:52596 score->at_top = (frame->ScrollOffset().height == 0);
initial.commit09911bf2008-07-26 23:55:29597
598 SkBitmap subset;
[email protected]b6e4bec2008-11-12 01:17:15599 device->accessBitmap(false).extractSubset(&subset, src_rect);
initial.commit09911bf2008-07-26 23:55:29600
601 // Resample the subset that we want to get it the right size.
[email protected]465b34b72008-12-12 20:19:14602 *thumbnail = skia::ImageOperations::Resize(
603 subset, skia::ImageOperations::RESIZE_LANCZOS3, w, h);
initial.commit09911bf2008-07-26 23:55:29604
605 score->boring_score = CalculateBoringScore(thumbnail);
606
607#ifdef TIME_BITMAP_RETRIEVAL
608 double end = time_util::GetHighResolutionTimeNow();
609 char buf[128];
610 sprintf_s(buf, "thumbnail in %gms\n", (end - begin) * 1000);
611 OutputDebugStringA(buf);
612#endif
[email protected]b6e4bec2008-11-12 01:17:15613 return true;
initial.commit09911bf2008-07-26 23:55:29614}
615
616double RenderView::CalculateBoringScore(SkBitmap* bitmap) {
617 int histogram[256] = {0};
618 color_utils::BuildLumaHistogram(bitmap, histogram);
619
620 int color_count = *std::max_element(histogram, histogram + 256);
621 int pixel_count = bitmap->width() * bitmap->height();
622 return static_cast<double>(color_count) / pixel_count;
623}
624
625void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {
626 if (!webview())
627 return;
628
[email protected]f8b6b6f2009-03-10 16:48:26629 renderer_logging::ScopedActiveRenderingURLSetter url_setter(params.url);
[email protected]f8b6b6f2009-03-10 16:48:26630
initial.commit09911bf2008-07-26 23:55:29631 AboutHandler::MaybeHandle(params.url);
632
633 bool is_reload = params.reload;
634
635 WebFrame* main_frame = webview()->GetMainFrame();
[email protected]606843fa2008-12-02 19:08:56636 if (is_reload && !main_frame->HasCurrentHistoryState()) {
initial.commit09911bf2008-07-26 23:55:29637 // We cannot reload if we do not have any history state. This happens, for
638 // example, when recovering from a crash. Our workaround here is a bit of
639 // a hack since it means that reload after a crashed tab does not cause an
640 // end-to-end cache validation.
641 is_reload = false;
642 }
643
[email protected]77f17a82009-05-21 04:42:54644 // A navigation resulting from loading a javascript URL should not be treated
645 // as a browser initiated event. Instead, we want it to look as if the page
646 // initiated any load resulting from JS execution.
647 if (!params.url.SchemeIs(chrome::kJavaScriptScheme)) {
648 pending_navigation_state_.reset(new NavigationState(
649 params.page_id, params.transition, params.request_time));
650 }
initial.commit09911bf2008-07-26 23:55:29651
[email protected]04d3c6e2009-05-22 17:00:13652 // If we are reloading, then WebKit will use the history state of the current
653 // page, so we should just ignore any given history state. Otherwise, if we
654 // have history state, then we need to navigate to it, which corresponds to a
655 // back/forward navigation event.
656 if (!is_reload && !params.state.empty()) {
657 // We must know the page ID of the page we are navigating back to.
[email protected]f929f2f22009-06-12 16:56:58658 DCHECK_NE(params.page_id, -1);
[email protected]04d3c6e2009-05-22 17:00:13659 main_frame->LoadHistoryState(params.state);
660 } else {
661 // Navigate to the given URL.
662 scoped_ptr<WebRequest> request(WebRequest::Create(params.url));
initial.commit09911bf2008-07-26 23:55:29663
[email protected]04d3c6e2009-05-22 17:00:13664 // TODO(darin): WebFrame should just have a Reload method.
665
666 WebRequestCachePolicy cache_policy;
667 if (is_reload) {
668 cache_policy = WebRequestReloadIgnoringCacheData;
669 } else {
670 // A session history navigation should have been accompanied by state.
[email protected]f929f2f22009-06-12 16:56:58671 DCHECK_EQ(params.page_id, -1);
[email protected]04d3c6e2009-05-22 17:00:13672 if (main_frame->GetInViewSourceMode()) {
673 cache_policy = WebRequestReturnCacheDataElseLoad;
674 } else {
675 cache_policy = WebRequestUseProtocolCachePolicy;
676 }
677 }
678 request->SetCachePolicy(cache_policy);
679
680 if (params.referrer.is_valid())
681 request->SetHttpHeaderValue("Referer", params.referrer.spec());
682
683 main_frame->LoadRequest(request.get());
[email protected]c0588052008-10-27 23:01:50684 }
685
[email protected]77f17a82009-05-21 04:42:54686 // In case LoadRequest failed before DidCreateDataSource was called.
687 pending_navigation_state_.reset();
initial.commit09911bf2008-07-26 23:55:29688}
689
690// Stop loading the current page
691void RenderView::OnStop() {
692 if (webview())
693 webview()->StopLoading();
694}
695
696void RenderView::OnLoadAlternateHTMLText(const std::string& html_contents,
697 bool new_navigation,
698 const GURL& display_url,
699 const std::string& security_info) {
700 if (!webview())
701 return;
702
703 scoped_ptr<WebRequest> request(WebRequest::Create(
704 GURL(kUnreachableWebDataURL)));
705 request->SetSecurityInfo(security_info);
706
707 webview()->GetMainFrame()->LoadAlternateHTMLString(request.get(),
708 html_contents,
709 display_url,
710 !new_navigation);
711}
712
713void RenderView::OnCopyImageAt(int x, int y) {
714 webview()->CopyImageAt(x, y);
715}
716
717void RenderView::OnInspectElement(int x, int y) {
718 webview()->InspectElement(x, y);
719}
720
721void RenderView::OnShowJavaScriptConsole() {
722 webview()->ShowJavaScriptConsole();
723}
724
[email protected]b2abac72009-02-26 12:39:28725void RenderView::OnSetupDevToolsClient() {
[email protected]e4ac5df2009-03-17 15:33:11726 DCHECK(!devtools_client_.get());
727 devtools_client_.reset(new DevToolsClient(this));
[email protected]b2abac72009-02-26 12:39:28728}
729
initial.commit09911bf2008-07-26 23:55:29730void RenderView::OnStopFinding(bool clear_selection) {
731 WebView* view = webview();
732 if (!view)
733 return;
734
735 if (clear_selection)
736 view->GetFocusedFrame()->ClearSelection();
737
738 WebFrame* frame = view->GetMainFrame();
739 while (frame) {
[email protected]65134c432008-09-26 21:47:20740 frame->StopFinding(clear_selection);
initial.commit09911bf2008-07-26 23:55:29741 frame = view->GetNextFrameAfter(frame, false);
742 }
743}
744
745void RenderView::OnFindReplyAck() {
746 // Check if there is any queued up request waiting to be sent.
747 if (queued_find_reply_message_.get()) {
748 // Send the search result over to the browser process.
749 Send(queued_find_reply_message_.get());
750 queued_find_reply_message_.release();
751 }
752}
753
754void RenderView::OnUpdateTargetURLAck() {
755 // Check if there is a targeturl waiting to be sent.
756 if (target_url_status_ == TARGET_PENDING) {
757 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_,
758 pending_target_url_));
759 }
760
761 target_url_status_ = TARGET_NONE;
762}
763
764void RenderView::OnUndo() {
765 if (!webview())
766 return;
767
768 webview()->GetFocusedFrame()->Undo();
769}
770
771void RenderView::OnRedo() {
772 if (!webview())
773 return;
774
775 webview()->GetFocusedFrame()->Redo();
776}
777
778void RenderView::OnCut() {
779 if (!webview())
780 return;
781
782 webview()->GetFocusedFrame()->Cut();
783}
784
785void RenderView::OnCopy() {
786 if (!webview())
787 return;
788
789 webview()->GetFocusedFrame()->Copy();
790}
791
792void RenderView::OnPaste() {
793 if (!webview())
794 return;
795
796 webview()->GetFocusedFrame()->Paste();
797}
798
799void RenderView::OnReplace(const std::wstring& text) {
800 if (!webview())
801 return;
802
803 webview()->GetFocusedFrame()->Replace(text);
804}
805
[email protected]bbbd545c2008-12-15 20:18:04806void RenderView::OnToggleSpellCheck() {
807 if (!webview())
808 return;
809
810 webview()->GetFocusedFrame()->ToggleSpellCheck();
811}
812
initial.commit09911bf2008-07-26 23:55:29813void RenderView::OnDelete() {
814 if (!webview())
815 return;
816
817 webview()->GetFocusedFrame()->Delete();
818}
819
820void RenderView::OnSelectAll() {
821 if (!webview())
822 return;
823
824 webview()->GetFocusedFrame()->SelectAll();
825}
826
827void RenderView::OnSetInitialFocus(bool reverse) {
828 if (!webview())
829 return;
830 webview()->SetInitialFocus(reverse);
831}
832
833///////////////////////////////////////////////////////////////////////////////
834
835// Tell the embedding application that the URL of the active page has changed
836void RenderView::UpdateURL(WebFrame* frame) {
837 WebDataSource* ds = frame->GetDataSource();
838 DCHECK(ds);
839
840 const WebRequest& request = ds->GetRequest();
841 const WebRequest& initial_request = ds->GetInitialRequest();
842 const WebResponse& response = ds->GetResponse();
843
[email protected]77f17a82009-05-21 04:42:54844 // This will be null if we did not initiate the navigation.
845 NavigationState* navigation_state =
846 static_cast<NavigationState*>(ds->GetExtraData());
initial.commit09911bf2008-07-26 23:55:29847
848 ViewHostMsg_FrameNavigate_Params params;
[email protected]2e39d2e2009-02-19 18:41:31849 params.http_status_code = response.GetHttpStatusCode();
initial.commit09911bf2008-07-26 23:55:29850 params.is_post = false;
851 params.page_id = page_id_;
[email protected]8a3422c92008-09-24 17:42:42852 params.is_content_filtered = response.IsContentFiltered();
initial.commit09911bf2008-07-26 23:55:29853 if (!request.GetSecurityInfo().empty()) {
854 // SSL state specified in the request takes precedence over the one in the
855 // response.
856 // So far this is only intended for error pages that are not expected to be
857 // over ssl, so we should not get any clash.
858 DCHECK(response.GetSecurityInfo().empty());
859 params.security_info = request.GetSecurityInfo();
860 } else {
861 params.security_info = response.GetSecurityInfo();
862 }
863
864 // Set the URL to be displayed in the browser UI to the user.
865 if (ds->HasUnreachableURL()) {
866 params.url = ds->GetUnreachableURL();
867 } else {
868 params.url = request.GetURL();
869 }
870
871 params.redirects = ds->GetRedirectChain();
872 params.should_update_history = !ds->HasUnreachableURL();
873
874 const SearchableFormData* searchable_form_data =
875 frame->GetDataSource()->GetSearchableFormData();
876 if (searchable_form_data) {
877 params.searchable_form_url = searchable_form_data->url();
878 params.searchable_form_element_name = searchable_form_data->element_name();
879 params.searchable_form_encoding = searchable_form_data->encoding();
880 }
881
882 const PasswordForm* password_form_data =
883 frame->GetDataSource()->GetPasswordFormData();
884 if (password_form_data)
885 params.password_form = *password_form_data;
886
887 params.gesture = navigation_gesture_;
888 navigation_gesture_ = NavigationGestureUnknown;
889
[email protected]77f17a82009-05-21 04:42:54890 if (!frame->GetParent()) {
initial.commit09911bf2008-07-26 23:55:29891 // Top-level navigation.
892
893 // Update contents MIME type for main frame.
[email protected]9d806f52009-03-12 22:50:54894 params.contents_mime_type = ds->GetResponse().GetMimeType();
initial.commit09911bf2008-07-26 23:55:29895
896 // We assume top level navigations initiated by the renderer are link
897 // clicks.
[email protected]77f17a82009-05-21 04:42:54898 params.transition = navigation_state ?
899 navigation_state->transition_type : PageTransition::LINK;
initial.commit09911bf2008-07-26 23:55:29900 if (!PageTransition::IsMainFrame(params.transition)) {
901 // If the main frame does a load, it should not be reported as a subframe
902 // navigation. This can occur in the following case:
903 // 1. You're on a site with frames.
904 // 2. You do a subframe navigation. This is stored with transition type
905 // MANUAL_SUBFRAME.
906 // 3. You navigate to some non-frame site, say, google.com.
907 // 4. You navigate back to the page from step 2. Since it was initially
908 // MANUAL_SUBFRAME, it will be that same transition type here.
909 // We don't want that, because any navigation that changes the toplevel
910 // frame should be tracked as a toplevel navigation (this allows us to
911 // update the URL bar, etc).
912 params.transition = PageTransition::LINK;
913 }
914
915 if (params.transition == PageTransition::LINK &&
916 frame->GetDataSource()->IsFormSubmit()) {
917 params.transition = PageTransition::FORM_SUBMIT;
918 }
919
920 // If we have a valid consumed client redirect source,
921 // the page contained a client redirect (meta refresh, document.loc...),
922 // so we set the referrer and transition to match.
923 if (completed_client_redirect_src_.is_valid()) {
[email protected]77e09a92008-08-01 18:11:04924 DCHECK(completed_client_redirect_src_ == params.redirects[0]);
initial.commit09911bf2008-07-26 23:55:29925 params.referrer = completed_client_redirect_src_;
926 params.transition = static_cast<PageTransition::Type>(
927 params.transition | PageTransition::CLIENT_REDIRECT);
928 } else {
929 // Bug 654101: the referrer will be empty on https->http transitions. It
930 // would be nice if we could get the real referrer from somewhere.
931 params.referrer = GURL(initial_request.GetHttpReferrer());
932 }
933
[email protected]8e3c1a72008-11-25 01:13:32934 std::string method = request.GetHttpMethod();
935 if (method == "POST")
initial.commit09911bf2008-07-26 23:55:29936 params.is_post = true;
937
938 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
939 } else {
940 // Subframe navigation: the type depends on whether this navigation
941 // generated a new session history entry. When they do generate a session
942 // history entry, it means the user initiated the navigation and we should
943 // mark it as such. This test checks if this is the first time UpdateURL
944 // has been called since WillNavigateToURL was called to initiate the load.
945 if (page_id_ > last_page_id_sent_to_browser_)
946 params.transition = PageTransition::MANUAL_SUBFRAME;
947 else
948 params.transition = PageTransition::AUTO_SUBFRAME;
949
initial.commit09911bf2008-07-26 23:55:29950 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
951 }
952
953 last_page_id_sent_to_browser_ =
954 std::max(last_page_id_sent_to_browser_, page_id_);
955
956 // If we end up reusing this WebRequest (for example, due to a #ref click),
957 // we don't want the transition type to persist.
[email protected]77f17a82009-05-21 04:42:54958 if (navigation_state)
959 navigation_state->transition_type = PageTransition::LINK; // Just clear it.
[email protected]266eb6f2008-09-30 23:56:50960
[email protected]6c8afae52009-01-22 02:24:57961#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:25962 if (web_accessibility_manager_.get()) {
[email protected]be645db2009-02-06 20:36:33963 // Clear accessibility info cache.
[email protected]6a983b42009-03-20 20:12:25964 web_accessibility_manager_->ClearAccObjMap(-1, true);
[email protected]266eb6f2008-09-30 23:56:50965 }
[email protected]6c8afae52009-01-22 02:24:57966#else
[email protected]7d926f92009-03-03 14:26:54967 // TODO(port): accessibility not yet implemented. See http://crbug.com/8288.
[email protected]6c8afae52009-01-22 02:24:57968#endif
initial.commit09911bf2008-07-26 23:55:29969}
970
971// Tell the embedding application that the title of the active page has changed
972void RenderView::UpdateTitle(WebFrame* frame, const std::wstring& title) {
973 // Ignore all but top level navigations...
[email protected]f0af6a72009-05-30 05:25:17974 if (webview()->GetMainFrame() == frame) {
975 Send(new ViewHostMsg_UpdateTitle(
976 routing_id_,
977 page_id_,
978 title.length() > chrome::kMaxTitleChars ?
979 title.substr(0, chrome::kMaxTitleChars) : title));
980 }
initial.commit09911bf2008-07-26 23:55:29981}
982
983void RenderView::UpdateEncoding(WebFrame* frame,
[email protected]e38f40152008-09-12 23:08:30984 const std::wstring& encoding_name) {
initial.commit09911bf2008-07-26 23:55:29985 // Only update main frame's encoding_name.
986 if (webview()->GetMainFrame() == frame &&
987 last_encoding_name_ != encoding_name) {
[email protected]e38f40152008-09-12 23:08:30988 // Save the encoding name for later comparing.
initial.commit09911bf2008-07-26 23:55:29989 last_encoding_name_ = encoding_name;
990
[email protected]e38f40152008-09-12 23:08:30991 Send(new ViewHostMsg_UpdateEncoding(routing_id_, last_encoding_name_));
initial.commit09911bf2008-07-26 23:55:29992 }
993}
994
[email protected]f4d34b52008-11-24 23:05:01995// Sends the previous session history state to the browser so it will be saved
996// before we navigate to a new page. This must be called *before* the page ID
997// has been updated so we know what it was.
initial.commit09911bf2008-07-26 23:55:29998void RenderView::UpdateSessionHistory(WebFrame* frame) {
999 // If we have a valid page ID at this point, then it corresponds to the page
1000 // we are navigating away from. Otherwise, this is the first navigation, so
1001 // there is no past session history to record.
1002 if (page_id_ == -1)
1003 return;
1004
initial.commit09911bf2008-07-26 23:55:291005 std::string state;
[email protected]606843fa2008-12-02 19:08:561006 if (!webview()->GetMainFrame()->GetPreviousHistoryState(&state))
initial.commit09911bf2008-07-26 23:55:291007 return;
[email protected]606843fa2008-12-02 19:08:561008 Send(new ViewHostMsg_UpdateState(routing_id_, page_id_, state));
initial.commit09911bf2008-07-26 23:55:291009}
1010
1011///////////////////////////////////////////////////////////////////////////////
1012// WebViewDelegate
1013
[email protected]80d96fa2009-06-10 22:34:511014bool RenderView::CanAcceptLoadDrops() const {
1015 return renderer_preferences_.can_accept_load_drops;
1016}
1017
initial.commit09911bf2008-07-26 23:55:291018void RenderView::DidStartLoading(WebView* webview) {
1019 if (is_loading_) {
1020 DLOG(WARNING) << "DidStartLoading called while loading";
1021 return;
1022 }
1023
1024 is_loading_ = true;
1025 // Clear the pointer so that we can assign it only when there is an unknown
1026 // plugin on a page.
1027 first_default_plugin_ = NULL;
1028
[email protected]329581b2009-04-28 06:52:351029 Send(new ViewHostMsg_DidStartLoading(routing_id_));
initial.commit09911bf2008-07-26 23:55:291030}
1031
1032void RenderView::DidStopLoading(WebView* webview) {
1033 if (!is_loading_) {
1034 DLOG(WARNING) << "DidStopLoading called while not loading";
1035 return;
1036 }
1037
1038 is_loading_ = false;
1039
1040 // NOTE: For now we're doing the safest thing, and sending out notification
1041 // when done loading. This currently isn't an issue as the favicon is only
1042 // displayed when done loading. Ideally we would send notification when
1043 // finished parsing the head, but webkit doesn't support that yet.
1044 // The feed discovery code would also benefit from access to the head.
1045 GURL favicon_url(webview->GetMainFrame()->GetFavIconURL());
1046 if (!favicon_url.is_empty())
1047 Send(new ViewHostMsg_UpdateFavIconURL(routing_id_, page_id_, favicon_url));
1048
1049 AddGURLSearchProvider(webview->GetMainFrame()->GetOSDDURL(),
1050 true); // autodetected
1051
[email protected]329581b2009-04-28 06:52:351052 Send(new ViewHostMsg_DidStopLoading(routing_id_));
initial.commit09911bf2008-07-26 23:55:291053
1054 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1055 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo, page_id_,
1056 false),
1057 kDelayForCaptureMs);
1058
1059 // The page is loaded. Try to process the file we need to upload if any.
1060 ProcessPendingUpload();
1061
1062 // Since the page is done loading, we are sure we don't need to try
1063 // again.
1064 ResetPendingUpload();
1065}
1066
[email protected]77f17a82009-05-21 04:42:541067void RenderView::DidCreateDataSource(WebFrame* frame, WebDataSource* ds) {
1068 ds->SetExtraData(pending_navigation_state_.release());
1069}
1070
initial.commit09911bf2008-07-26 23:55:291071void RenderView::DidStartProvisionalLoadForFrame(
1072 WebView* webview,
1073 WebFrame* frame,
1074 NavigationGesture gesture) {
[email protected]77e09a92008-08-01 18:11:041075 if (webview->GetMainFrame() == frame) {
initial.commit09911bf2008-07-26 23:55:291076 navigation_gesture_ = gesture;
[email protected]266eb6f2008-09-30 23:56:501077
[email protected]77e09a92008-08-01 18:11:041078 // Make sure redirect tracking state is clear for the new load.
1079 completed_client_redirect_src_ = GURL();
1080 }
initial.commit09911bf2008-07-26 23:55:291081
[email protected]c20210e62009-04-03 21:39:261082 WebDataSource* ds = frame->GetProvisionalDataSource();
1083 if (ds) {
[email protected]77f17a82009-05-21 04:42:541084 NavigationState* navigation_state =
1085 static_cast<NavigationState*>(ds->GetExtraData());
1086 if (navigation_state)
1087 ds->SetRequestTime(navigation_state->request_time);
[email protected]c20210e62009-04-03 21:39:261088 }
initial.commit09911bf2008-07-26 23:55:291089 Send(new ViewHostMsg_DidStartProvisionalLoadForFrame(
1090 routing_id_, webview->GetMainFrame() == frame,
1091 frame->GetProvisionalDataSource()->GetRequest().GetURL()));
1092}
1093
1094bool RenderView::DidLoadResourceFromMemoryCache(WebView* webview,
1095 const WebRequest& request,
1096 const WebResponse& response,
1097 WebFrame* frame) {
1098 // Let the browser know we loaded a resource from the memory cache. This
1099 // message is needed to display the correct SSL indicators.
1100 Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(routing_id_,
[email protected]ffc45862009-03-17 06:11:081101 request.GetURL(), frame->GetSecurityOrigin(),
1102 frame->GetTop()->GetSecurityOrigin(),
1103 response.GetSecurityInfo()));
initial.commit09911bf2008-07-26 23:55:291104
1105 return false;
1106}
1107
1108void RenderView::DidReceiveProvisionalLoadServerRedirect(WebView* webview,
1109 WebFrame* frame) {
1110 if (frame == webview->GetMainFrame()) {
1111 // Received a redirect on the main frame.
1112 WebDataSource* data_source =
1113 webview->GetMainFrame()->GetProvisionalDataSource();
1114 if (!data_source) {
1115 // Should only be invoked when we have a data source.
1116 NOTREACHED();
1117 return;
1118 }
1119 const std::vector<GURL>& redirects = data_source->GetRedirectChain();
1120 if (redirects.size() >= 2) {
1121 Send(new ViewHostMsg_DidRedirectProvisionalLoad(
1122 routing_id_, page_id_, redirects[redirects.size() - 2],
1123 redirects[redirects.size() - 1]));
1124 }
1125 }
1126}
1127
1128void RenderView::DidFailProvisionalLoadWithError(WebView* webview,
1129 const WebError& error,
1130 WebFrame* frame) {
1131 // Notify the browser that we failed a provisional load with an error.
1132 //
1133 // Note: It is important this notification occur before DidStopLoading so the
1134 // SSL manager can react to the provisional load failure before being
1135 // notified the load stopped.
1136 //
1137 WebDataSource* ds = frame->GetProvisionalDataSource();
1138 DCHECK(ds);
1139
1140 const WebRequest& failed_request = ds->GetRequest();
1141
1142 bool show_repost_interstitial =
1143 (error.GetErrorCode() == net::ERR_CACHE_MISS &&
1144 LowerCaseEqualsASCII(failed_request.GetHttpMethod(), "post"));
1145 Send(new ViewHostMsg_DidFailProvisionalLoadWithError(
1146 routing_id_, frame == webview->GetMainFrame(),
1147 error.GetErrorCode(), error.GetFailedURL(),
1148 show_repost_interstitial));
1149
initial.commit09911bf2008-07-26 23:55:291150 // Don't display an error page if this is simply a cancelled load. Aside
1151 // from being dumb, WebCore doesn't expect it and it will cause a crash.
1152 if (error.GetErrorCode() == net::ERR_ABORTED)
1153 return;
1154
1155 // If this is a failed back/forward/reload navigation, then we need to do a
1156 // 'replace' load. This is necessary to avoid messing up session history.
1157 // Otherwise, we do a normal load, which simulates a 'go' navigation as far
1158 // as session history is concerned.
[email protected]77f17a82009-05-21 04:42:541159 NavigationState* navigation_state =
1160 static_cast<NavigationState*>(ds->GetExtraData());
1161 bool replace = navigation_state && !navigation_state->is_new_navigation();
initial.commit09911bf2008-07-26 23:55:291162
[email protected]5df266ac2008-10-15 19:50:131163 // Use the alternate error page service if this is a DNS failure or
1164 // connection failure. ERR_CONNECTION_FAILED can be dropped once we no longer
1165 // use winhttp.
1166 int ec = error.GetErrorCode();
1167 if (ec == net::ERR_NAME_NOT_RESOLVED ||
1168 ec == net::ERR_CONNECTION_FAILED ||
1169 ec == net::ERR_CONNECTION_REFUSED ||
1170 ec == net::ERR_ADDRESS_UNREACHABLE ||
1171 ec == net::ERR_TIMED_OUT) {
1172 const GURL& failed_url = error.GetFailedURL();
1173 const GURL& error_page_url = GetAlternateErrorPageURL(failed_url,
1174 ec == net::ERR_NAME_NOT_RESOLVED ? WebViewDelegate::DNS_ERROR
1175 : WebViewDelegate::CONNECTION_ERROR);
1176 if (error_page_url.is_valid()) {
1177 // Ask the WebFrame to fetch the alternate error page for us.
1178 frame->LoadAlternateHTMLErrorPage(&failed_request, error, error_page_url,
1179 replace, GURL(kUnreachableWebDataURL));
1180 return;
1181 }
initial.commit09911bf2008-07-26 23:55:291182 }
[email protected]5df266ac2008-10-15 19:50:131183
[email protected]be645db2009-02-06 20:36:331184 // Fallback to a local error page.
[email protected]5df266ac2008-10-15 19:50:131185 LoadNavigationErrorPage(frame, &failed_request, error, std::string(),
1186 replace);
initial.commit09911bf2008-07-26 23:55:291187}
1188
1189void RenderView::LoadNavigationErrorPage(WebFrame* frame,
1190 const WebRequest* failed_request,
1191 const WebError& error,
1192 const std::string& html,
1193 bool replace) {
1194 const GURL& failed_url = error.GetFailedURL();
1195
1196 std::string alt_html;
1197 if (html.empty()) {
1198 // Use a local error page.
1199 int resource_id;
1200 DictionaryValue error_strings;
1201 if (error.GetErrorCode() == net::ERR_CACHE_MISS &&
1202 LowerCaseEqualsASCII(failed_request->GetHttpMethod(), "post")) {
1203 GetFormRepostErrorValues(failed_url, &error_strings);
1204 resource_id = IDR_ERROR_NO_DETAILS_HTML;
1205 } else {
1206 GetLocalizedErrorValues(error, &error_strings);
1207 resource_id = IDR_NET_ERROR_HTML;
1208 }
[email protected]8e50b602009-03-03 22:59:431209 error_strings.SetString(L"textdirection",
1210 (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) ?
1211 L"rtl" : L"ltr");
initial.commit09911bf2008-07-26 23:55:291212
1213 alt_html = GetAltHTMLForTemplate(error_strings, resource_id);
1214 } else {
1215 alt_html = html;
1216 }
1217
1218 // Use a data: URL as the site URL to prevent against XSS attacks.
1219 scoped_ptr<WebRequest> request(failed_request->Clone());
1220 request->SetURL(GURL(kUnreachableWebDataURL));
1221
1222 frame->LoadAlternateHTMLString(request.get(), alt_html, failed_url,
1223 replace);
1224}
1225
1226void RenderView::DidCommitLoadForFrame(WebView *webview, WebFrame* frame,
1227 bool is_new_navigation) {
[email protected]77f17a82009-05-21 04:42:541228 NavigationState* navigation_state = static_cast<NavigationState*>(
1229 frame->GetDataSource()->GetExtraData());
initial.commit09911bf2008-07-26 23:55:291230
1231 if (is_new_navigation) {
1232 // When we perform a new navigation, we need to update the previous session
1233 // history entry with state for the page we are leaving.
1234 UpdateSessionHistory(frame);
1235
1236 // We bump our Page ID to correspond with the new session history entry.
1237 page_id_ = next_page_id_++;
1238
1239 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1240 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo,
1241 page_id_, true),
1242 kDelayForForcedCaptureMs);
1243 } else {
[email protected]77f17a82009-05-21 04:42:541244 // Inspect the navigation_state on the main frame (set in our Navigate
1245 // method) to see if the navigation corresponds to a session history
1246 // navigation... Note: |frame| may or may not be the toplevel frame, but
1247 // for the case of capturing session history, the first committed frame
1248 // suffices. We keep track of whether we've seen this commit before so
1249 // that only capture session history once per navigation.
[email protected]f4d34b52008-11-24 23:05:011250 //
1251 // Note that we need to check if the page ID changed. In the case of a
1252 // reload, the page ID doesn't change, and UpdateSessionHistory gets the
1253 // previous URL and the current page ID, which would be wrong.
[email protected]77f17a82009-05-21 04:42:541254 if (navigation_state && !navigation_state->is_new_navigation() &&
1255 !navigation_state->request_committed &&
1256 page_id_ != navigation_state->pending_page_id()) {
initial.commit09911bf2008-07-26 23:55:291257 // This is a successful session history navigation!
1258 UpdateSessionHistory(frame);
[email protected]77f17a82009-05-21 04:42:541259 page_id_ = navigation_state->pending_page_id();
initial.commit09911bf2008-07-26 23:55:291260 }
1261 }
1262
1263 // Remember that we've already processed this request, so we don't update
1264 // the session history again. We do this regardless of whether this is
1265 // a session history navigation, because if we attempted a session history
1266 // navigation without valid HistoryItem state, WebCore will think it is a
1267 // new navigation.
[email protected]77f17a82009-05-21 04:42:541268 if (navigation_state)
1269 navigation_state->request_committed = true;
initial.commit09911bf2008-07-26 23:55:291270
1271 UpdateURL(frame);
1272
1273 // If this committed load was initiated by a client redirect, we're
1274 // at the last stop now, so clear it.
1275 completed_client_redirect_src_ = GURL();
1276
1277 // Check whether we have new encoding name.
1278 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
1279}
1280
1281void RenderView::DidReceiveTitle(WebView* webview,
1282 const std::wstring& title,
1283 WebFrame* frame) {
1284 UpdateTitle(frame, title);
1285
1286 // Also check whether we have new encoding name.
1287 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
1288}
1289
1290void RenderView::DidFinishLoadForFrame(WebView* webview, WebFrame* frame) {
[email protected]c20210e62009-04-03 21:39:261291 if (webview->GetMainFrame() == frame) {
1292 const GURL& url = frame->GetURL();
1293 if (url.SchemeIs("http") || url.SchemeIs("https"))
1294 DumpLoadHistograms();
1295 }
initial.commit09911bf2008-07-26 23:55:291296}
1297
1298void RenderView::DidFailLoadWithError(WebView* webview,
1299 const WebError& error,
1300 WebFrame* frame) {
1301}
1302
1303void RenderView::DidFinishDocumentLoadForFrame(WebView* webview,
1304 WebFrame* frame) {
1305 // Check whether we have new encoding name.
1306 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
[email protected]1e0f70402008-10-16 23:57:471307
[email protected]8930d472009-02-21 08:05:281308 if (RenderThread::current()) // Will be NULL during unit tests.
1309 RenderThread::current()->user_script_slave()->InjectScripts(
[email protected]0afe8272009-02-14 04:15:161310 frame, UserScript::DOCUMENT_END);
initial.commit09911bf2008-07-26 23:55:291311}
1312
1313void RenderView::DidHandleOnloadEventsForFrame(WebView* webview,
1314 WebFrame* frame) {
1315}
1316
1317void RenderView::DidChangeLocationWithinPageForFrame(WebView* webview,
1318 WebFrame* frame,
1319 bool is_new_navigation) {
[email protected]77f17a82009-05-21 04:42:541320 // If this was a reference fragment navigation that we initiated, then we
1321 // could end up having a non-null pending navigation state. We just need to
1322 // update the ExtraData on the datasource so that others who read the
1323 // ExtraData will get the new NavigationState. Similarly, if we did not
1324 // initiate this navigation, then we need to take care to clear any pre-
1325 // existing navigation state.
1326 frame->GetDataSource()->SetExtraData(pending_navigation_state_.release());
1327
initial.commit09911bf2008-07-26 23:55:291328 DidCommitLoadForFrame(webview, frame, is_new_navigation);
[email protected]77f17a82009-05-21 04:42:541329
[email protected]9d806f52009-03-12 22:50:541330 const string16& title =
[email protected]de56f3782008-10-01 22:31:351331 webview->GetMainFrame()->GetDataSource()->GetPageTitle();
[email protected]9d806f52009-03-12 22:50:541332 UpdateTitle(frame, UTF16ToWideHack(title));
initial.commit09911bf2008-07-26 23:55:291333}
1334
1335void RenderView::DidReceiveIconForFrame(WebView* webview,
1336 WebFrame* frame) {
1337}
1338
1339void RenderView::WillPerformClientRedirect(WebView* webview,
1340 WebFrame* frame,
1341 const GURL& src_url,
1342 const GURL& dest_url,
1343 unsigned int delay_seconds,
1344 unsigned int fire_date) {
1345}
1346
1347void RenderView::DidCancelClientRedirect(WebView* webview,
1348 WebFrame* frame) {
1349}
1350
[email protected]309d7a282009-03-24 09:18:271351void RenderView::WillCloseFrame(WebView* view, WebFrame* frame) {
[email protected]309d7a282009-03-24 09:18:271352}
1353
initial.commit09911bf2008-07-26 23:55:291354void RenderView::DidCompleteClientRedirect(WebView* webview,
1355 WebFrame* frame,
1356 const GURL& source) {
1357 if (webview->GetMainFrame() == frame)
1358 completed_client_redirect_src_ = source;
1359}
1360
[email protected]5b35a6b2009-03-16 19:58:081361void RenderView::WillSendRequest(WebView* webview,
1362 uint32 identifier,
1363 WebRequest* request) {
1364 request->SetRequestorID(routing_id_);
1365}
1366
initial.commit09911bf2008-07-26 23:55:291367void RenderView::BindDOMAutomationController(WebFrame* webframe) {
1368 dom_automation_controller_.set_message_sender(this);
1369 dom_automation_controller_.set_routing_id(routing_id_);
1370 dom_automation_controller_.BindToJavascript(webframe,
1371 L"domAutomationController");
1372}
1373
1374void RenderView::WindowObjectCleared(WebFrame* webframe) {
[email protected]81e63782009-02-27 19:35:091375 if (BindingsPolicy::is_dom_automation_enabled(enabled_bindings_))
initial.commit09911bf2008-07-26 23:55:291376 BindDOMAutomationController(webframe);
[email protected]81e63782009-02-27 19:35:091377 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_)) {
initial.commit09911bf2008-07-26 23:55:291378 dom_ui_bindings_.set_message_sender(this);
1379 dom_ui_bindings_.set_routing_id(routing_id_);
1380 dom_ui_bindings_.BindToJavascript(webframe, L"chrome");
1381 }
[email protected]81e63782009-02-27 19:35:091382 if (BindingsPolicy::is_external_host_enabled(enabled_bindings_)) {
[email protected]18cb2572008-08-21 20:34:451383 external_host_bindings_.set_message_sender(this);
1384 external_host_bindings_.set_routing_id(routing_id_);
1385 external_host_bindings_.BindToJavascript(webframe, L"externalHost");
1386 }
initial.commit09911bf2008-07-26 23:55:291387}
1388
[email protected]0afe8272009-02-14 04:15:161389void RenderView::DocumentElementAvailable(WebFrame* frame) {
[email protected]4b8323b2009-04-17 18:45:441390 // TODO(mpcomplete): remove this before Chrome extensions ship.
1391 // HACK. This is a temporary workaround to allow cross-origin XHR for Chrome
1392 // extensions. It grants full access to every origin, when we really want
1393 // to be able to restrict them more specifically.
[email protected]d959ce22009-04-15 21:03:421394 if (frame->GetURL().SchemeIs(chrome::kExtensionScheme))
[email protected]4b8323b2009-04-17 18:45:441395 frame->GrantUniversalAccess();
[email protected]d959ce22009-04-15 21:03:421396
[email protected]85b99842009-05-16 02:01:251397 // Tell extensions to self-register their js contexts.
[email protected]4646f292009-05-20 03:49:051398 // TODO(rafaelw): This is kind of gross. We need a way to call through
[email protected]85b99842009-05-16 02:01:251399 // the glue layer to retrieve the current v8::Context.
1400 if (frame->GetURL().SchemeIs(chrome::kExtensionScheme))
1401 ExtensionProcessBindings::RegisterExtensionContext(frame);
1402
[email protected]8930d472009-02-21 08:05:281403 if (RenderThread::current()) // Will be NULL during unit tests.
1404 RenderThread::current()->user_script_slave()->InjectScripts(
[email protected]0afe8272009-02-14 04:15:161405 frame, UserScript::DOCUMENT_START);
1406}
1407
initial.commit09911bf2008-07-26 23:55:291408WindowOpenDisposition RenderView::DispositionForNavigationAction(
1409 WebView* webview,
1410 WebFrame* frame,
1411 const WebRequest* request,
1412 WebNavigationType type,
1413 WindowOpenDisposition disposition,
1414 bool is_redirect) {
[email protected]77f17a82009-05-21 04:42:541415 // GetExtraData is NULL when we did not issue the request ourselves (see
1416 // OnNavigate), and so such a request may correspond to a link-click,
1417 // script, or drag-n-drop initiated navigation.
1418 bool is_content_initiated =
1419 !frame->GetProvisionalDataSource()->GetExtraData();
1420
initial.commit09911bf2008-07-26 23:55:291421 // Webkit is asking whether to navigate to a new URL.
1422 // This is fine normally, except if we're showing UI from one security
1423 // context and they're trying to navigate to a different context.
1424 const GURL& url = request->GetURL();
[email protected]77f17a82009-05-21 04:42:541425
initial.commit09911bf2008-07-26 23:55:291426 // We only care about navigations that are within the current tab (as opposed
1427 // to, for example, opening a new window).
1428 // But we sometimes navigate to about:blank to clear a tab, and we want to
1429 // still allow that.
[email protected]77f17a82009-05-21 04:42:541430 if (disposition == CURRENT_TAB && is_content_initiated &&
1431 frame->GetParent() == NULL && !url.SchemeIs(chrome::kAboutScheme)) {
1432 // When we received such unsolicited navigations, we sometimes want to
1433 // punt them up to the browser to handle.
1434 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_) ||
1435 frame->GetInViewSourceMode() ||
1436 url.SchemeIs(chrome::kViewSourceScheme)) {
1437 OpenURL(webview, url, GURL(), disposition);
1438 return IGNORE_ACTION; // Suppress the load here.
initial.commit09911bf2008-07-26 23:55:291439 }
1440 }
1441
1442 // Detect when a page is "forking" a new tab that can be safely rendered in
1443 // its own process. This is done by sites like Gmail that try to open links
1444 // in new windows without script connections back to the original page. We
1445 // treat such cases as browser navigations (in which we will create a new
1446 // renderer for a cross-site navigation), rather than WebKit navigations.
1447 //
1448 // We use the following heuristic to decide whether to fork a new page in its
1449 // own process:
1450 // The parent page must open a new tab to about:blank, set the new tab's
1451 // window.opener to null, and then redirect the tab to a cross-site URL using
1452 // JavaScript.
1453 bool is_fork =
1454 // Must start from a tab showing about:blank, which is later redirected.
[email protected]6aad4bd2009-02-26 22:55:171455 frame->GetURL() == GURL("about:blank") &&
initial.commit09911bf2008-07-26 23:55:291456 // Must be the first real navigation of the tab.
1457 GetHistoryBackListCount() < 1 &&
1458 GetHistoryForwardListCount() < 1 &&
1459 // The parent page must have set the child's window.opener to null before
1460 // redirecting to the desired URL.
1461 frame->GetOpener() == NULL &&
1462 // Must be a top-level frame.
1463 frame->GetParent() == NULL &&
[email protected]77f17a82009-05-21 04:42:541464 // Must not have issued the request from this page.
1465 is_content_initiated &&
initial.commit09911bf2008-07-26 23:55:291466 // Must be targeted at the current tab.
1467 disposition == CURRENT_TAB &&
1468 // Must be a JavaScript navigation, which appears as "other".
1469 type == WebNavigationTypeOther;
1470 if (is_fork) {
1471 // Open the URL via the browser, not via WebKit.
[email protected]c0588052008-10-27 23:01:501472 OpenURL(webview, url, GURL(), disposition);
initial.commit09911bf2008-07-26 23:55:291473 return IGNORE_ACTION;
1474 }
1475
1476 return disposition;
1477}
1478
[email protected]a455d3812009-03-05 20:18:071479void RenderView::RunJavaScriptAlert(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291480 const std::wstring& message) {
[email protected]478ff2ed2009-04-21 23:49:181481 RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptAlert,
initial.commit09911bf2008-07-26 23:55:291482 message,
1483 std::wstring(),
[email protected]a455d3812009-03-05 20:18:071484 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291485 NULL);
1486}
1487
[email protected]a455d3812009-03-05 20:18:071488bool RenderView::RunJavaScriptConfirm(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291489 const std::wstring& message) {
[email protected]478ff2ed2009-04-21 23:49:181490 return RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptConfirm,
initial.commit09911bf2008-07-26 23:55:291491 message,
1492 std::wstring(),
[email protected]a455d3812009-03-05 20:18:071493 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291494 NULL);
1495}
1496
[email protected]a455d3812009-03-05 20:18:071497bool RenderView::RunJavaScriptPrompt(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291498 const std::wstring& message,
1499 const std::wstring& default_value,
1500 std::wstring* result) {
[email protected]478ff2ed2009-04-21 23:49:181501 return RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptPrompt,
initial.commit09911bf2008-07-26 23:55:291502 message,
1503 default_value,
[email protected]a455d3812009-03-05 20:18:071504 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291505 result);
1506}
1507
1508bool RenderView::RunJavaScriptMessage(int type,
1509 const std::wstring& message,
1510 const std::wstring& default_value,
[email protected]a455d3812009-03-05 20:18:071511 const GURL& frame_url,
initial.commit09911bf2008-07-26 23:55:291512 std::wstring* result) {
1513 bool success = false;
1514 std::wstring result_temp;
1515 if (!result)
1516 result = &result_temp;
1517 IPC::SyncMessage* msg = new ViewHostMsg_RunJavaScriptMessage(
[email protected]a455d3812009-03-05 20:18:071518 routing_id_, message, default_value, frame_url, type, &success, result);
initial.commit09911bf2008-07-26 23:55:291519
[email protected]1c4947f2009-01-15 22:25:111520 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291521 Send(msg);
1522
1523 return success;
1524}
1525
1526void RenderView::AddGURLSearchProvider(const GURL& osd_url, bool autodetected) {
1527 if (!osd_url.is_empty())
1528 Send(new ViewHostMsg_PageHasOSDD(routing_id_, page_id_, osd_url,
1529 autodetected));
1530}
1531
[email protected]a455d3812009-03-05 20:18:071532bool RenderView::RunBeforeUnloadConfirm(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291533 const std::wstring& message) {
1534 bool success = false;
1535 // This is an ignored return value, but is included so we can accept the same
1536 // response as RunJavaScriptMessage.
1537 std::wstring ignored_result;
1538 IPC::SyncMessage* msg = new ViewHostMsg_RunBeforeUnloadConfirm(
[email protected]a455d3812009-03-05 20:18:071539 routing_id_, webframe->GetURL(), message, &success, &ignored_result);
initial.commit09911bf2008-07-26 23:55:291540
[email protected]1c4947f2009-01-15 22:25:111541 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291542 Send(msg);
1543
1544 return success;
1545}
1546
[email protected]0ebf3872008-11-07 21:35:031547void RenderView::QueryFormFieldAutofill(const std::wstring& field_name,
1548 const std::wstring& text,
1549 int64 node_id) {
1550 static int message_id_counter = 0;
1551 form_field_autofill_request_id_ = message_id_counter++;
1552 Send(new ViewHostMsg_QueryFormFieldAutofill(routing_id_,
1553 field_name, text,
1554 node_id,
1555 form_field_autofill_request_id_));
1556}
1557
[email protected]4d2b6fb2009-03-20 22:28:171558void RenderView::RemoveStoredAutofillEntry(const std::wstring& name,
1559 const std::wstring& value) {
1560 Send(new ViewHostMsg_RemoveAutofillEntry(routing_id_, name, value));
1561}
1562
[email protected]0ebf3872008-11-07 21:35:031563void RenderView::OnReceivedAutofillSuggestions(
1564 int64 node_id,
1565 int request_id,
[email protected]8d0f15c2008-11-11 01:01:091566 const std::vector<std::wstring>& suggestions,
[email protected]0ebf3872008-11-07 21:35:031567 int default_suggestion_index) {
1568 if (!webview() || request_id != form_field_autofill_request_id_)
1569 return;
1570
1571 webview()->AutofillSuggestionsForNode(node_id, suggestions,
1572 default_suggestion_index);
1573}
1574
[email protected]2c4410d2009-05-06 23:46:221575void RenderView::OnPopupNotificationVisibilityChanged(bool visible) {
[email protected]634a6f92008-12-01 21:39:311576 popup_notification_visible_ = visible;
1577}
1578
initial.commit09911bf2008-07-26 23:55:291579void RenderView::ShowModalHTMLDialog(const GURL& url, int width, int height,
1580 const std::string& json_arguments,
1581 std::string* json_retval) {
1582 IPC::SyncMessage* msg = new ViewHostMsg_ShowModalHTMLDialog(
1583 routing_id_, url, width, height, json_arguments, json_retval);
1584
[email protected]1c4947f2009-01-15 22:25:111585 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291586 Send(msg);
1587}
1588
1589uint32 RenderView::GetCPBrowsingContext() {
1590 uint32 context = 0;
1591 Send(new ViewHostMsg_GetCPBrowsingContext(&context));
1592 return context;
1593}
1594
1595// Tell the browser to display a destination link.
1596void RenderView::UpdateTargetURL(WebView* webview, const GURL& url) {
1597 if (url != target_url_) {
1598 if (target_url_status_ == TARGET_INFLIGHT ||
1599 target_url_status_ == TARGET_PENDING) {
1600 // If we have a request in-flight, save the URL to be sent when we
1601 // receive an ACK to the in-flight request. We can happily overwrite
1602 // any existing pending sends.
1603 pending_target_url_ = url;
1604 target_url_status_ = TARGET_PENDING;
1605 } else {
1606 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_, url));
1607 target_url_ = url;
1608 target_url_status_ = TARGET_INFLIGHT;
1609 }
1610 }
1611}
1612
[email protected]b62d1a8c2009-01-13 23:54:571613void RenderView::RunFileChooser(bool multi_select,
[email protected]b949f1112009-04-12 20:03:081614 const string16& title,
1615 const FilePath& default_filename,
initial.commit09911bf2008-07-26 23:55:291616 WebFileChooserCallback* file_chooser) {
1617 if (file_chooser_.get()) {
1618 // TODO(brettw): bug 1235154: This should be a synchronous message to deal
1619 // with the fact that web pages can programatically trigger this. With the
1620 // asnychronous messages, we can get an additional call when one is pending,
1621 // which this test is for. For now, we just ignore the additional file
1622 // chooser request. WebKit doesn't do anything to expect the callback, so
1623 // we can just ignore calling it.
1624 delete file_chooser;
1625 return;
1626 }
1627 file_chooser_.reset(file_chooser);
[email protected]b62d1a8c2009-01-13 23:54:571628 Send(new ViewHostMsg_RunFileChooser(routing_id_, multi_select, title,
[email protected]b949f1112009-04-12 20:03:081629 default_filename));
initial.commit09911bf2008-07-26 23:55:291630}
1631
1632void RenderView::AddMessageToConsole(WebView* webview,
1633 const std::wstring& message,
1634 unsigned int line_no,
1635 const std::wstring& source_id) {
1636 Send(new ViewHostMsg_AddMessageToConsole(routing_id_, message,
1637 static_cast<int32>(line_no),
1638 source_id));
1639}
1640
1641void RenderView::AddSearchProvider(const std::string& url) {
1642 AddGURLSearchProvider(GURL(url),
1643 false); // not autodetected
1644}
1645
1646void RenderView::DebuggerOutput(const std::wstring& out) {
1647 Send(new ViewHostMsg_DebuggerOutput(routing_id_, out));
1648}
1649
[email protected]c88a70fe2009-05-05 20:00:221650WebView* RenderView::CreateWebView(WebView* webview,
1651 bool user_gesture,
1652 const GURL& creator_url) {
[email protected]0aa55312008-10-17 21:53:081653 // Check to make sure we aren't overloading on popups.
1654 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups)
1655 return NULL;
1656
[email protected]634a6f92008-12-01 21:39:311657 // This window can't be closed from a window.close() call until we receive a
1658 // message from the Browser process explicitly allowing it.
1659 popup_notification_visible_ = true;
1660
initial.commit09911bf2008-07-26 23:55:291661 int32 routing_id = MSG_ROUTING_NONE;
[email protected]6c8afae52009-01-22 02:24:571662
[email protected]18bcc3c2009-01-27 21:39:151663 ModalDialogEvent modal_dialog_event;
[email protected]6c8afae52009-01-22 02:24:571664 render_thread_->Send(
[email protected]15787f8f2008-10-17 15:29:031665 new ViewHostMsg_CreateWindow(routing_id_, user_gesture, &routing_id,
1666 &modal_dialog_event));
initial.commit09911bf2008-07-26 23:55:291667 if (routing_id == MSG_ROUTING_NONE) {
initial.commit09911bf2008-07-26 23:55:291668 return NULL;
1669 }
1670
1671 // The WebView holds a reference to this new RenderView
[email protected]80d96fa2009-06-10 22:34:511672 const WebPreferences& web_prefs = webview->GetPreferences();
[email protected]6c8afae52009-01-22 02:24:571673 base::WaitableEvent* waitable_event = new base::WaitableEvent
1674#if defined(OS_WIN)
[email protected]18bcc3c2009-01-27 21:39:151675 (modal_dialog_event.event);
[email protected]6c8afae52009-01-22 02:24:571676#else
1677 (true, false);
1678#endif
[email protected]81a34412009-01-05 19:17:241679 RenderView* view = RenderView::Create(render_thread_,
[email protected]1c4947f2009-01-15 22:25:111680 NULL, waitable_event, routing_id_,
[email protected]80d96fa2009-06-10 22:34:511681 renderer_preferences_, web_prefs,
1682 shared_popup_counter_, routing_id);
[email protected]ed4bf2d2009-05-05 00:10:061683 view->opened_by_user_gesture_ = user_gesture;
[email protected]c88a70fe2009-05-05 20:00:221684 view->creator_url_ = creator_url;
initial.commit09911bf2008-07-26 23:55:291685
1686 // Copy over the alternate error page URL so we can have alt error pages in
1687 // the new render view (we don't need the browser to send the URL back down).
1688 view->alternate_error_page_url_ = alternate_error_page_url_;
1689
1690 return view->webview();
1691}
1692
[email protected]0ebf3872008-11-07 21:35:031693WebWidget* RenderView::CreatePopupWidget(WebView* webview,
[email protected]cfd727f2009-01-09 20:21:111694 bool activatable) {
[email protected]8085dbc82008-09-26 22:53:441695 RenderWidget* widget = RenderWidget::Create(routing_id_,
[email protected]81a34412009-01-05 19:17:241696 render_thread_,
[email protected]cfd727f2009-01-09 20:21:111697 activatable);
initial.commit09911bf2008-07-26 23:55:291698 return widget->webwidget();
1699}
1700
1701WebPluginDelegate* RenderView::CreatePluginDelegate(
1702 WebView* webview,
1703 const GURL& url,
1704 const std::string& mime_type,
1705 const std::string& clsid,
1706 std::string* actual_mime_type) {
[email protected]ffeba6d2009-04-27 20:43:261707#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]6273e2e72009-04-17 00:13:551708 if (!PluginChannelHost::IsListening())
1709 return NULL;
1710
[email protected]9dd9e8382009-06-05 18:23:211711 GURL policy_url;
1712 if (webview->GetMainFrame())
1713 policy_url = webview->GetMainFrame()->GetURL();
1714
[email protected]f5cdaff2009-05-19 21:01:471715 FilePath path;
1716 render_thread_->Send(
[email protected]9dd9e8382009-06-05 18:23:211717 new ViewHostMsg_GetPluginPath(url, policy_url, mime_type, clsid, &path,
[email protected]f5cdaff2009-05-19 21:01:471718 actual_mime_type));
1719 if (path.value().empty())
1720 return NULL;
1721
1722 std::string mime_type_to_use;
1723 if (!actual_mime_type->empty())
1724 mime_type_to_use = *actual_mime_type;
1725 else
1726 mime_type_to_use = mime_type;
1727
[email protected]ffeba6d2009-04-27 20:43:261728#if !defined(OS_LINUX) // In-proc plugins aren't supported on Linux.
[email protected]88a1fb47a2009-03-13 00:18:061729 if (RenderProcess::current()->in_process_plugins()) {
[email protected]b94d3322009-02-12 19:49:041730 return WebPluginDelegate::Create(path,
1731 mime_type_to_use,
1732 gfx::NativeViewFromId(host_window_));
initial.commit09911bf2008-07-26 23:55:291733 }
[email protected]ffeba6d2009-04-27 20:43:261734#endif
initial.commit09911bf2008-07-26 23:55:291735
1736 WebPluginDelegateProxy* proxy =
[email protected]f5cdaff2009-05-19 21:01:471737 WebPluginDelegateProxy::Create(url, mime_type_to_use, clsid, this);
initial.commit09911bf2008-07-26 23:55:291738 if (!proxy)
1739 return NULL;
1740
1741 // We hold onto the proxy so we can poke it when we are painting. See our
1742 // DidPaint implementation below.
1743 plugin_delegates_.push_back(proxy);
1744
1745 return proxy;
[email protected]6c8afae52009-01-22 02:24:571746#else
[email protected]157e5d22009-04-23 18:43:351747 // TODO(port): Plugins currently not supported
1748 NOTIMPLEMENTED();
1749 return NULL;
[email protected]6c8afae52009-01-22 02:24:571750#endif
initial.commit09911bf2008-07-26 23:55:291751}
1752
[email protected]4e6be3f2009-05-07 02:24:441753WebKit::WebMediaPlayer* RenderView::CreateWebMediaPlayer(
1754 WebKit::WebMediaPlayerClient* client) {
[email protected]add51772009-06-11 18:25:171755 scoped_refptr<media::FilterFactoryCollection> factory =
1756 new media::FilterFactoryCollection();
1757 // Add in any custom filter factories first.
1758 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
1759 if (!cmd_line->HasSwitch(switches::kDisableAudio)) {
1760 // Add the chrome specific audio renderer.
1761 factory->AddFactory(
1762 AudioRendererImpl::CreateFactory(audio_message_filter()));
1763 }
1764 if (!cmd_line->HasSwitch(switches::kSimpleDataSource)) {
1765 // Add the chrome specific media data source.
1766 factory->AddFactory(BufferedDataSource::CreateFactory(routing_id()));
1767 }
1768 return new webkit_glue::WebMediaPlayerImpl(client, factory);
[email protected]ec9212f2008-12-18 21:40:361769}
1770
initial.commit09911bf2008-07-26 23:55:291771void RenderView::OnMissingPluginStatus(WebPluginDelegate* delegate,
1772 int status) {
[email protected]6c8afae52009-01-22 02:24:571773#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291774 if (first_default_plugin_ == NULL) {
1775 // Show the InfoBar for the first available plugin.
1776 if (status == default_plugin::MISSING_PLUGIN_AVAILABLE) {
1777 first_default_plugin_ = delegate;
1778 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1779 }
1780 } else {
1781 // Closes the InfoBar if user clicks on the plugin (instead of the InfoBar)
1782 // to start the download/install.
1783 if (status == default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD) {
1784 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1785 }
1786 }
[email protected]6c8afae52009-01-22 02:24:571787#else
1788 // TODO(port): plugins current not supported
1789 NOTIMPLEMENTED();
1790#endif
initial.commit09911bf2008-07-26 23:55:291791}
1792
[email protected]eb47a132009-03-04 00:39:561793WebWorker* RenderView::CreateWebWorker(WebWorkerClient* client) {
1794#if defined(OS_WIN)
[email protected]ec775ef2009-05-01 21:20:471795 return new WebWorkerProxy(client, RenderThread::current(), routing_id_);
[email protected]eb47a132009-03-04 00:39:561796#else
1797 // TODO(port): out of process workers
1798 NOTIMPLEMENTED();
1799 return NULL;
1800#endif
1801}
1802
initial.commit09911bf2008-07-26 23:55:291803void RenderView::OpenURL(WebView* webview, const GURL& url,
[email protected]c0588052008-10-27 23:01:501804 const GURL& referrer,
initial.commit09911bf2008-07-26 23:55:291805 WindowOpenDisposition disposition) {
[email protected]c0588052008-10-27 23:01:501806 Send(new ViewHostMsg_OpenURL(routing_id_, url, referrer, disposition));
initial.commit09911bf2008-07-26 23:55:291807}
1808
[email protected]1d522202009-04-04 01:56:421809void RenderView::DidContentsSizeChange(WebWidget* webwidget,
1810 int new_width,
1811 int new_height) {
[email protected]0666aef2009-05-13 19:48:081812 // We don't always want to send the change messages over IPC, only if we've
1813 // be put in that mode by getting a |ViewMsg_EnableIntrinsicWidthChangedMode|
1814 // message.
1815 // TODO(rafaelw): Figure out where the best place to set this for extensions
1816 // is. It isn't clean to test for ExtensionView by examining the
1817 // enabled_bindings. This needs to be generalized as it becomes clear what
1818 // extension toolbars need.
1819 if (BindingsPolicy::is_extension_enabled(enabled_bindings_) ||
1820 send_preferred_width_changes_) {
1821 // WebCore likes to tell us things have changed even when they haven't, so
1822 // cache the width and only send the IPC message when we're sure the
1823 // width is different.
[email protected]1d522202009-04-04 01:56:421824 int width = webview()->GetMainFrame()->GetContentsPreferredWidth();
[email protected]0666aef2009-05-13 19:48:081825 if (width != preferred_width_) {
1826 Send(new ViewHostMsg_DidContentsPreferredWidthChange(routing_id_, width));
1827 preferred_width_ = width;
1828 }
[email protected]1d522202009-04-04 01:56:421829 }
1830}
1831
initial.commit09911bf2008-07-26 23:55:291832// We are supposed to get a single call to Show for a newly created RenderView
1833// that was created via RenderView::CreateWebView. So, we wait until this
1834// point to dispatch the ShowView message.
1835//
1836// This method provides us with the information about how to display the newly
1837// created RenderView (i.e., as a constrained popup or as a new tab).
1838//
1839void RenderView::Show(WebWidget* webwidget, WindowOpenDisposition disposition) {
1840 DCHECK(!did_show_) << "received extraneous Show call";
1841 DCHECK(opener_id_ != MSG_ROUTING_NONE);
1842
1843 if (did_show_)
1844 return;
1845 did_show_ = true;
1846
1847 // NOTE: initial_pos_ may still have its default values at this point, but
1848 // that's okay. It'll be ignored if disposition is not NEW_POPUP, or the
1849 // browser process will impose a default position otherwise.
[email protected]35f7d212009-04-29 21:19:271850 Send(new ViewHostMsg_ShowView(opener_id_, routing_id_, disposition,
[email protected]c88a70fe2009-05-05 20:00:221851 initial_pos_, opened_by_user_gesture_, creator_url_));
[email protected]2533ce12009-05-09 00:02:241852 SetPendingWindowRect(initial_pos_);
initial.commit09911bf2008-07-26 23:55:291853}
1854
[email protected]634a6f92008-12-01 21:39:311855void RenderView::CloseWidgetSoon(WebWidget* webwidget) {
[email protected]2c4410d2009-05-06 23:46:221856 if (!popup_notification_visible_)
[email protected]634a6f92008-12-01 21:39:311857 RenderWidget::CloseWidgetSoon(webwidget);
1858}
1859
initial.commit09911bf2008-07-26 23:55:291860void RenderView::RunModal(WebWidget* webwidget) {
1861 DCHECK(did_show_) << "should already have shown the view";
1862
1863 IPC::SyncMessage* msg = new ViewHostMsg_RunModal(routing_id_);
1864
[email protected]1c4947f2009-01-15 22:25:111865 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291866 Send(msg);
1867}
1868
1869void RenderView::SyncNavigationState() {
1870 if (!webview())
1871 return;
1872
initial.commit09911bf2008-07-26 23:55:291873 std::string state;
[email protected]606843fa2008-12-02 19:08:561874 if (!webview()->GetMainFrame()->GetCurrentHistoryState(&state))
initial.commit09911bf2008-07-26 23:55:291875 return;
[email protected]606843fa2008-12-02 19:08:561876 Send(new ViewHostMsg_UpdateState(routing_id_, page_id_, state));
initial.commit09911bf2008-07-26 23:55:291877}
1878
1879void RenderView::ShowContextMenu(WebView* webview,
[email protected]124646932009-01-28 18:39:021880 ContextNode node,
initial.commit09911bf2008-07-26 23:55:291881 int x,
1882 int y,
1883 const GURL& link_url,
1884 const GURL& image_url,
1885 const GURL& page_url,
1886 const GURL& frame_url,
1887 const std::wstring& selection_text,
1888 const std::wstring& misspelled_word,
[email protected]6aa376b2008-09-23 18:49:521889 int edit_flags,
[email protected]c9825a42009-05-01 22:51:501890 const std::string& security_info,
1891 const std::string& frame_charset) {
[email protected]e09ba552009-02-05 03:26:291892 ContextMenuParams params;
[email protected]124646932009-01-28 18:39:021893 params.node = node;
initial.commit09911bf2008-07-26 23:55:291894 params.x = x;
1895 params.y = y;
1896 params.image_url = image_url;
1897 params.link_url = link_url;
[email protected]e6c79812009-04-22 22:31:421898 params.unfiltered_link_url = link_url;
initial.commit09911bf2008-07-26 23:55:291899 params.page_url = page_url;
1900 params.frame_url = frame_url;
1901 params.selection_text = selection_text;
1902 params.misspelled_word = misspelled_word;
[email protected]be645db2009-02-06 20:36:331903 params.spellcheck_enabled =
[email protected]bbbd545c2008-12-15 20:18:041904 webview->GetFocusedFrame()->SpellCheckEnabled();
initial.commit09911bf2008-07-26 23:55:291905 params.edit_flags = edit_flags;
[email protected]6aa376b2008-09-23 18:49:521906 params.security_info = security_info;
[email protected]c9825a42009-05-01 22:51:501907 params.frame_charset = frame_charset;
initial.commit09911bf2008-07-26 23:55:291908 Send(new ViewHostMsg_ContextMenu(routing_id_, params));
1909}
1910
[email protected]e80c73b2009-04-07 23:24:581911void RenderView::StartDragging(WebView* webview,
1912 const WebDragData& drag_data) {
1913 Send(new ViewHostMsg_StartDragging(routing_id_, WebDropData(drag_data)));
initial.commit09911bf2008-07-26 23:55:291914}
1915
1916void RenderView::TakeFocus(WebView* webview, bool reverse) {
1917 Send(new ViewHostMsg_TakeFocus(routing_id_, reverse));
1918}
1919
1920void RenderView::DidDownloadImage(int id,
1921 const GURL& image_url,
1922 bool errored,
1923 const SkBitmap& image) {
1924 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, errored,
1925 image));
1926}
1927
1928
1929void RenderView::OnDownloadImage(int id,
1930 const GURL& image_url,
1931 int image_size) {
[email protected]f11ca0732009-04-11 00:09:341932 bool data_image_failed = false;
1933 if (image_url.SchemeIs("data")) {
1934 SkBitmap data_image = ImageFromDataUrl(image_url);
1935 data_image_failed = data_image.empty();
1936 if (!data_image_failed) {
1937 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, false,
1938 data_image));
1939 }
1940 }
1941
1942 if (data_image_failed || !webview()->DownloadImage(id, image_url, image_size))
initial.commit09911bf2008-07-26 23:55:291943 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, true,
1944 SkBitmap()));
1945}
1946
[email protected]f11ca0732009-04-11 00:09:341947SkBitmap RenderView::ImageFromDataUrl(const GURL& url) const {
1948 std::string mime_type, char_set, data;
1949 if (net::DataURL::Parse(url, &mime_type, &char_set, &data) && !data.empty()) {
1950 // Decode the favicon using WebKit's image decoder.
1951 webkit_glue::ImageDecoder decoder(gfx::Size(kFavIconSize, kFavIconSize));
1952 const unsigned char* src_data =
1953 reinterpret_cast<const unsigned char*>(&data[0]);
1954
1955 return decoder.Decode(src_data, data.size());
1956 }
1957 return SkBitmap();
1958}
1959
initial.commit09911bf2008-07-26 23:55:291960void RenderView::OnGetApplicationInfo(int page_id) {
1961 webkit_glue::WebApplicationInfo app_info;
1962 if (page_id == page_id_)
1963 webkit_glue::GetApplicationInfo(webview(), &app_info);
1964
1965 // Prune out any data URLs in the set of icons. The browser process expects
1966 // any icon with a data URL to have originated from a favicon. We don't want
1967 // to decode arbitrary data URLs in the browser process. See
1968 // http://b/issue?id=1162972
1969 for (size_t i = 0; i < app_info.icons.size(); ++i) {
[email protected]6de74452009-02-25 18:04:591970 if (app_info.icons[i].url.SchemeIs(chrome::kDataScheme)) {
initial.commit09911bf2008-07-26 23:55:291971 app_info.icons.erase(app_info.icons.begin() + i);
1972 --i;
1973 }
1974 }
1975
1976 Send(new ViewHostMsg_DidGetApplicationInfo(routing_id_, page_id, app_info));
1977}
1978
1979GURL RenderView::GetAlternateErrorPageURL(const GURL& failedURL,
1980 ErrorPageType error_type) {
1981 if (failedURL.SchemeIsSecure()) {
1982 // If the URL that failed was secure, then the embedding web page was not
1983 // expecting a network attacker to be able to manipulate its contents. As
1984 // we fetch alternate error pages over HTTP, we would be allowing a network
1985 // attacker to manipulate the contents of the response if we tried to use
1986 // the link doctor here.
1987 return GURL::EmptyGURL();
1988 }
1989
1990 // Grab the base URL from the browser process.
1991 if (!alternate_error_page_url_.is_valid())
1992 return GURL::EmptyGURL();
1993
1994 // Strip query params from the failed URL.
1995 GURL::Replacements remove_params;
1996 remove_params.ClearUsername();
1997 remove_params.ClearPassword();
1998 remove_params.ClearQuery();
1999 remove_params.ClearRef();
2000 const GURL url_to_send = failedURL.ReplaceComponents(remove_params);
2001
2002 // Construct the query params to send to link doctor.
2003 std::string params(alternate_error_page_url_.query());
2004 params.append("&url=");
2005 params.append(EscapeQueryParamValue(url_to_send.spec()));
2006 params.append("&sourceid=chrome");
2007 params.append("&error=");
2008 switch (error_type) {
2009 case DNS_ERROR:
2010 params.append("dnserror");
2011 break;
2012
2013 case HTTP_404:
2014 params.append("http404");
2015 break;
2016
[email protected]5df266ac2008-10-15 19:50:132017 case CONNECTION_ERROR:
[email protected]e1f934b2009-01-26 20:41:332018 params.append("connectionfailure");
[email protected]5df266ac2008-10-15 19:50:132019 break;
2020
initial.commit09911bf2008-07-26 23:55:292021 default:
2022 NOTREACHED() << "unknown ErrorPageType";
2023 }
2024
2025 // OK, build the final url to return.
2026 GURL::Replacements link_doctor_params;
2027 link_doctor_params.SetQueryStr(params);
2028 GURL url = alternate_error_page_url_.ReplaceComponents(link_doctor_params);
2029 return url;
2030}
2031
[email protected]7ea066a2009-04-06 20:21:592032void RenderView::OnFind(int request_id,
2033 const string16& search_text,
2034 const WebKit::WebFindOptions& options) {
initial.commit09911bf2008-07-26 23:55:292035 WebFrame* main_frame = webview()->GetMainFrame();
2036 WebFrame* frame_after_main = webview()->GetNextFrameAfter(main_frame, true);
2037 WebFrame* focused_frame = webview()->GetFocusedFrame();
2038 WebFrame* search_frame = focused_frame; // start searching focused frame.
2039
2040 bool multi_frame = (frame_after_main != main_frame);
2041
2042 // If we have multiple frames, we don't want to wrap the search within the
2043 // frame, so we check here if we only have main_frame in the chain.
2044 bool wrap_within_frame = !multi_frame;
2045
[email protected]b3f2b912009-04-09 16:18:522046 WebRect selection_rect;
initial.commit09911bf2008-07-26 23:55:292047 bool result = false;
2048
2049 do {
[email protected]7ea066a2009-04-06 20:21:592050 result = search_frame->Find(
2051 request_id, search_text, options, wrap_within_frame, &selection_rect);
initial.commit09911bf2008-07-26 23:55:292052
2053 if (!result) {
2054 // don't leave text selected as you move to the next frame.
2055 search_frame->ClearSelection();
2056
2057 // Find the next frame, but skip the invisible ones.
2058 do {
2059 // What is the next frame to search? (we might be going backwards). Note
2060 // that we specify wrap=true so that search_frame never becomes NULL.
[email protected]7ea066a2009-04-06 20:21:592061 search_frame = options.forward ?
initial.commit09911bf2008-07-26 23:55:292062 webview()->GetNextFrameAfter(search_frame, true) :
2063 webview()->GetPreviousFrameBefore(search_frame, true);
2064 } while (!search_frame->Visible() && search_frame != focused_frame);
2065
[email protected]884db412008-11-24 23:46:502066 // Make sure selection doesn't affect the search operation in new frame.
initial.commit09911bf2008-07-26 23:55:292067 search_frame->ClearSelection();
2068
2069 // If we have multiple frames and we have wrapped back around to the
2070 // focused frame, we need to search it once more allowing wrap within
2071 // the frame, otherwise it will report 'no match' if the focused frame has
2072 // reported matches, but no frames after the focused_frame contain a
2073 // match for the search word(s).
2074 if (multi_frame && search_frame == focused_frame) {
[email protected]7ea066a2009-04-06 20:21:592075 result = search_frame->Find(
2076 request_id, search_text, options, true, // Force wrapping.
2077 &selection_rect);
initial.commit09911bf2008-07-26 23:55:292078 }
2079 }
2080
2081 // TODO(jcampan): http://b/issue?id=1157486 Remove StoreForFocus call once
2082 // we have the fix for 792423.
2083 search_frame->GetView()->StoreFocusForFrame(search_frame);
2084 webview()->SetFocusedFrame(search_frame);
2085 } while (!result && search_frame != focused_frame);
2086
2087 // Make sure we don't leave any frame focused or the focus won't be restored
2088 // properly in WebViewImpl::SetFocus(). Note that we are talking here about
2089 // focused on the SelectionController, not FocusController.
2090 // webview()->GetFocusedFrame() will still return the last focused frame (as
2091 // it queries the FocusController).
2092 // TODO(jcampan): http://b/issue?id=1157486 Remove next line once we have the
2093 // fix for 792423.
2094 webview()->SetFocusedFrame(NULL);
2095
[email protected]7ea066a2009-04-06 20:21:592096 if (options.findNext) {
[email protected]4f3dc372009-02-24 00:10:292097 // Force the main_frame to report the actual count.
[email protected]7ea066a2009-04-06 20:21:592098 main_frame->IncreaseMatchCount(0, request_id);
[email protected]4f3dc372009-02-24 00:10:292099 } else {
2100 // If nothing is found, set result to "0 of 0", otherwise, set it to
2101 // "-1 of 1" to indicate that we found at least one item, but we don't know
2102 // yet what is active.
2103 int ordinal = result ? -1 : 0; // -1 here means, we might know more later.
2104 int match_count = result ? 1 : 0; // 1 here means possibly more coming.
initial.commit09911bf2008-07-26 23:55:292105
[email protected]4f3dc372009-02-24 00:10:292106 // If we find no matches then this will be our last status update.
2107 // Otherwise the scoping effort will send more results.
2108 bool final_status_update = !result;
initial.commit09911bf2008-07-26 23:55:292109
[email protected]4f3dc372009-02-24 00:10:292110 // Send the search result over to the browser process.
[email protected]4f999132009-03-31 18:08:402111 Send(new ViewHostMsg_Find_Reply(routing_id_,
[email protected]7ea066a2009-04-06 20:21:592112 request_id,
[email protected]4f3dc372009-02-24 00:10:292113 match_count,
2114 selection_rect,
2115 ordinal,
2116 final_status_update));
initial.commit09911bf2008-07-26 23:55:292117
initial.commit09911bf2008-07-26 23:55:292118 // Scoping effort begins, starting with the mainframe.
2119 search_frame = main_frame;
2120
2121 main_frame->ResetMatchCount();
2122
2123 do {
2124 // Cancel all old scoping requests before starting a new one.
2125 search_frame->CancelPendingScopingEffort();
2126
2127 // We don't start another scoping effort unless at least one match has
2128 // been found.
2129 if (result) {
2130 // Start new scoping request. If the scoping function determines that it
2131 // needs to scope, it will defer until later.
[email protected]7ea066a2009-04-06 20:21:592132 search_frame->ScopeStringMatches(request_id,
2133 search_text,
2134 options,
initial.commit09911bf2008-07-26 23:55:292135 true); // reset the tickmarks
2136 }
2137
2138 // Iterate to the next frame. The frame will not necessarily scope, for
2139 // example if it is not visible.
2140 search_frame = webview()->GetNextFrameAfter(search_frame, true);
2141 } while (search_frame != main_frame);
2142 }
2143}
2144
2145void RenderView::ReportFindInPageMatchCount(int count, int request_id,
2146 bool final_update) {
2147 // If we have a message that has been queued up, then we should just replace
2148 // it. The ACK from the browser will make sure it gets sent when the browser
2149 // wants it.
2150 if (queued_find_reply_message_.get()) {
2151 IPC::Message* msg = new ViewHostMsg_Find_Reply(
2152 routing_id_,
2153 request_id,
2154 count,
[email protected]b3f2b912009-04-09 16:18:522155 gfx::Rect(),
initial.commit09911bf2008-07-26 23:55:292156 -1, // Don't update active match ordinal.
2157 final_update);
2158 queued_find_reply_message_.reset(msg);
2159 } else {
2160 // Send the search result over to the browser process.
2161 Send(new ViewHostMsg_Find_Reply(
2162 routing_id_,
2163 request_id,
2164 count,
[email protected]b3f2b912009-04-09 16:18:522165 gfx::Rect(),
initial.commit09911bf2008-07-26 23:55:292166 -1, // // Don't update active match ordinal.
2167 final_update));
2168 }
2169}
2170
2171void RenderView::ReportFindInPageSelection(int request_id,
2172 int active_match_ordinal,
[email protected]b3f2b912009-04-09 16:18:522173 const WebRect& selection_rect) {
initial.commit09911bf2008-07-26 23:55:292174 // Send the search result over to the browser process.
2175 Send(new ViewHostMsg_Find_Reply(routing_id_,
2176 request_id,
2177 -1,
2178 selection_rect,
2179 active_match_ordinal,
2180 false));
2181}
2182
[email protected]ed4bf2d2009-05-05 00:10:062183bool RenderView::WasOpenedByUserGesture() const {
initial.commit09911bf2008-07-26 23:55:292184 return opened_by_user_gesture_;
2185}
2186
[email protected]7f40fc5b2009-06-12 19:23:082187void RenderView::SpellCheck(const std::wstring& word, int* misspell_location,
2188 int* misspell_length) {
2189 Send(new ViewHostMsg_SpellCheck(routing_id_, word, misspell_location,
2190 misspell_length));
initial.commit09911bf2008-07-26 23:55:292191}
2192
[email protected]26ea6c42009-06-10 22:32:212193std::wstring RenderView::GetAutoCorrectWord(
2194 const std::wstring& misspelled_word) {
2195 std::wstring autocorrect_word;
[email protected]eda2b5a2009-05-12 19:30:212196 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2197 if (command_line.HasSwitch(switches::kAutoSpellCorrect)) {
2198 Send(new ViewHostMsg_GetAutoCorrectWord(routing_id_, misspelled_word,
2199 &autocorrect_word));
2200 }
[email protected]26ea6c42009-06-10 22:32:212201
2202 return autocorrect_word;
[email protected]eda2b5a2009-05-12 19:30:212203}
2204
initial.commit09911bf2008-07-26 23:55:292205void RenderView::SetInputMethodState(bool enabled) {
2206 // Save the updated IME status and mark the input focus has been updated.
2207 // The IME status is to be sent to a browser process next time when
2208 // the input caret is rendered.
[email protected]9f23f592008-11-17 08:36:342209 if (!ime_control_busy_) {
2210 ime_control_updated_ = true;
2211 ime_control_new_state_ = enabled;
2212 }
initial.commit09911bf2008-07-26 23:55:292213}
2214
2215void RenderView::ScriptedPrint(WebFrame* frame) {
[email protected]d81c1e52009-06-03 22:09:502216 print_render_view_.reset(new PrintWebViewHelper(this));
2217 print_render_view_->SyncPrint(frame);
2218 print_render_view_.reset();
initial.commit09911bf2008-07-26 23:55:292219}
2220
2221void RenderView::WebInspectorOpened(int num_resources) {
2222 Send(new ViewHostMsg_InspectElement_Reply(routing_id_, num_resources));
2223}
2224
2225void RenderView::UserMetricsRecordAction(const std::wstring& action) {
2226 Send(new ViewHostMsg_UserMetricsRecordAction(routing_id_, action));
2227}
2228
2229void RenderView::DnsPrefetch(const std::vector<std::string>& host_names) {
2230 Send(new ViewHostMsg_DnsPrefetch(host_names));
2231}
2232
[email protected]630e26b2008-10-14 22:55:172233void RenderView::OnZoom(int function) {
2234 static const bool kZoomIsTextOnly = false;
2235 switch (function) {
2236 case PageZoom::SMALLER:
2237 webview()->ZoomOut(kZoomIsTextOnly);
initial.commit09911bf2008-07-26 23:55:292238 break;
[email protected]630e26b2008-10-14 22:55:172239 case PageZoom::STANDARD:
2240 webview()->ResetZoom();
initial.commit09911bf2008-07-26 23:55:292241 break;
[email protected]630e26b2008-10-14 22:55:172242 case PageZoom::LARGER:
2243 webview()->ZoomIn(kZoomIsTextOnly);
initial.commit09911bf2008-07-26 23:55:292244 break;
2245 default:
2246 NOTREACHED();
2247 }
2248}
2249
[email protected]ea8c7452009-04-02 20:47:062250void RenderView::OnInsertText(const string16& text) {
[email protected]5f9e0b82009-05-08 22:13:392251 WebFrame* frame = webview()->GetFocusedFrame();
2252 if (!frame)
2253 return;
2254 WebTextInput* text_input = frame->GetTextInput();
[email protected]00d7e622009-04-21 23:06:052255 if (text_input)
[email protected]7be0e172009-05-14 01:05:272256 text_input->InsertText(text);
[email protected]ea8c7452009-04-02 20:47:062257}
2258
[email protected]e38f40152008-09-12 23:08:302259void RenderView::OnSetPageEncoding(const std::wstring& encoding_name) {
initial.commit09911bf2008-07-26 23:55:292260 webview()->SetPageEncoding(encoding_name);
2261}
2262
2263void RenderView::OnPasswordFormsSeen(WebView* webview,
2264 const std::vector<PasswordForm>& forms) {
2265 Send(new ViewHostMsg_PasswordFormsSeen(routing_id_, forms));
2266}
2267
[email protected]8d0f15c2008-11-11 01:01:092268void RenderView::OnAutofillFormSubmitted(WebView* webview,
2269 const AutofillForm& form) {
2270 Send(new ViewHostMsg_AutofillFormSubmitted(routing_id_, form));
2271}
2272
[email protected]f6e59a62009-05-13 21:12:032273void RenderView::NavigateBackForwardSoon(int offset) {
[email protected]f46aff62008-10-16 07:58:052274 history_back_list_count_ += offset;
2275 history_forward_list_count_ -= offset;
2276
initial.commit09911bf2008-07-26 23:55:292277 Send(new ViewHostMsg_GoToEntryAtOffset(routing_id_, offset));
2278}
2279
2280int RenderView::GetHistoryBackListCount() {
2281 return history_back_list_count_;
2282}
2283
2284int RenderView::GetHistoryForwardListCount() {
2285 return history_forward_list_count_;
2286}
2287
2288void RenderView::OnNavStateChanged(WebView* webview) {
[email protected]81a34412009-01-05 19:17:242289 if (!nav_state_sync_timer_.IsRunning()) {
2290 nav_state_sync_timer_.Start(
2291 TimeDelta::FromSeconds(delay_seconds_for_form_state_sync_), this,
2292 &RenderView::SyncNavigationState);
2293 }
initial.commit09911bf2008-07-26 23:55:292294}
2295
2296void RenderView::SetTooltipText(WebView* webview,
2297 const std::wstring& tooltip_text) {
2298 Send(new ViewHostMsg_SetTooltipText(routing_id_, tooltip_text));
2299}
2300
[email protected]2e417c82009-04-02 22:30:262301void RenderView::DidChangeSelection(bool is_empty_selection) {
2302#if defined(OS_LINUX)
[email protected]d5d7b8002009-05-18 21:20:542303 // TODO(estade): investigate incremental updates to the selection so that we
2304 // don't send the entire selection over IPC every time.
[email protected]2e417c82009-04-02 22:30:262305 if (!is_empty_selection) {
[email protected]d5d7b8002009-05-18 21:20:542306 // Sometimes we get repeated DidChangeSelection calls from webkit when
2307 // the selection hasn't actually changed. We don't want to report these
2308 // because it will cause us to continually claim the X clipboard.
2309 const std::string& this_selection =
2310 webview()->GetFocusedFrame()->GetSelection(false);
2311 if (this_selection == last_selection_)
2312 return;
2313
[email protected]dbadbcc2009-04-09 00:57:102314 Send(new ViewHostMsg_SelectionChanged(routing_id_,
[email protected]d5d7b8002009-05-18 21:20:542315 this_selection));
2316 last_selection_ = this_selection;
[email protected]2e417c82009-04-02 22:30:262317 }
2318#endif
2319}
2320
initial.commit09911bf2008-07-26 23:55:292321void RenderView::DownloadUrl(const GURL& url, const GURL& referrer) {
2322 Send(new ViewHostMsg_DownloadUrl(routing_id_, url, referrer));
2323}
2324
[email protected]0df30122009-06-03 12:13:082325void RenderView::UpdateInspectorSettings(const std::wstring& raw_settings) {
2326 Send(new ViewHostMsg_UpdateInspectorSettings(routing_id_, raw_settings));
2327}
2328
[email protected]611cad42009-03-16 18:51:342329WebDevToolsAgentDelegate* RenderView::GetWebDevToolsAgentDelegate() {
[email protected]b75b7d072009-04-06 13:47:002330 return devtools_agent_.get();
[email protected]611cad42009-03-16 18:51:342331}
2332
[email protected]ea8c7452009-04-02 20:47:062333void RenderView::PasteFromSelectionClipboard() {
2334 Send(new ViewHostMsg_PasteFromSelectionClipboard(routing_id_));
2335}
2336
initial.commit09911bf2008-07-26 23:55:292337WebFrame* RenderView::GetChildFrame(const std::wstring& frame_xpath) const {
2338 WebFrame* web_frame;
2339 if (frame_xpath.empty()) {
2340 web_frame = webview()->GetMainFrame();
2341 } else {
2342 web_frame = webview()->GetMainFrame()->GetChildFrame(frame_xpath);
2343 }
2344
2345 return web_frame;
2346}
2347
[email protected]f29acf52008-11-03 20:08:332348void RenderView::EvaluateScript(const std::wstring& frame_xpath,
2349 const std::wstring& script) {
initial.commit09911bf2008-07-26 23:55:292350 WebFrame* web_frame = GetChildFrame(frame_xpath);
2351 if (!web_frame)
2352 return;
2353
[email protected]4f999132009-03-31 18:08:402354 web_frame->ExecuteScript(WebScriptSource(WideToUTF16Hack(script)));
initial.commit09911bf2008-07-26 23:55:292355}
2356
[email protected]1810e132009-03-24 23:35:482357void RenderView::InsertCSS(const std::wstring& frame_xpath,
2358 const std::string& css) {
2359 WebFrame* web_frame = GetChildFrame(frame_xpath);
2360 if (!web_frame)
2361 return;
2362
2363 web_frame->InsertCSSStyles(css);
2364}
2365
initial.commit09911bf2008-07-26 23:55:292366void RenderView::OnScriptEvalRequest(const std::wstring& frame_xpath,
2367 const std::wstring& jscript) {
[email protected]f29acf52008-11-03 20:08:332368 EvaluateScript(frame_xpath, jscript);
initial.commit09911bf2008-07-26 23:55:292369}
2370
[email protected]1810e132009-03-24 23:35:482371void RenderView::OnCSSInsertRequest(const std::wstring& frame_xpath,
2372 const std::string& css) {
2373 InsertCSS(frame_xpath, css);
2374}
2375
[email protected]7ea066a2009-04-06 20:21:592376void RenderView::OnAddMessageToConsole(
2377 const string16& frame_xpath,
2378 const string16& message,
2379 const WebConsoleMessage::Level& level) {
2380 WebFrame* web_frame = GetChildFrame(UTF16ToWideHack(frame_xpath));
[email protected]0dea3ea2009-03-31 23:30:592381 if (web_frame)
[email protected]7ea066a2009-04-06 20:21:592382 web_frame->AddMessageToConsole(WebConsoleMessage(level, message));
initial.commit09911bf2008-07-26 23:55:292383}
2384
[email protected]6c8afae52009-01-22 02:24:572385#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292386void RenderView::OnDebugAttach() {
initial.commit09911bf2008-07-26 23:55:292387 Send(new ViewHostMsg_DidDebugAttach(routing_id_));
2388 // Tell the plugin host to stop accepting messages in order to avoid
2389 // hangs while the renderer is paused.
2390 // TODO(1243929): It might be an improvement to add more plumbing to do this
2391 // when the renderer is actually paused vs. just the debugger being attached.
2392 PluginChannelHost::SetListening(false);
2393}
2394
2395void RenderView::OnDebugDetach() {
2396 // Tell the plugin host to start accepting plugin messages again.
2397 PluginChannelHost::SetListening(true);
2398}
[email protected]6c8afae52009-01-22 02:24:572399#else // defined(OS_WIN)
2400// TODO(port): plugins not yet supported
2401void RenderView::OnDebugAttach() { NOTIMPLEMENTED(); }
2402void RenderView::OnDebugDetach() { NOTIMPLEMENTED(); }
2403#endif
initial.commit09911bf2008-07-26 23:55:292404
[email protected]81e63782009-02-27 19:35:092405void RenderView::OnAllowBindings(int enabled_bindings_flags) {
2406 enabled_bindings_ |= enabled_bindings_flags;
initial.commit09911bf2008-07-26 23:55:292407}
2408
2409void RenderView::OnSetDOMUIProperty(const std::string& name,
2410 const std::string& value) {
[email protected]81e63782009-02-27 19:35:092411 DCHECK(BindingsPolicy::is_dom_ui_enabled(enabled_bindings_));
initial.commit09911bf2008-07-26 23:55:292412 dom_ui_bindings_.SetProperty(name, value);
2413}
2414
2415void RenderView::OnReservePageIDRange(int size_of_range) {
2416 next_page_id_ += size_of_range + 1;
2417}
2418
[email protected]e80c73b2009-04-07 23:24:582419void RenderView::OnDragSourceEndedOrMoved(const gfx::Point& client_point,
2420 const gfx::Point& screen_point,
initial.commit09911bf2008-07-26 23:55:292421 bool ended) {
2422 if (ended)
[email protected]e80c73b2009-04-07 23:24:582423 webview()->DragSourceEndedAt(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292424 else
[email protected]e80c73b2009-04-07 23:24:582425 webview()->DragSourceMovedTo(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292426}
2427
2428void RenderView::OnDragSourceSystemDragEnded() {
2429 webview()->DragSourceSystemDragEnded();
2430}
2431
2432void RenderView::OnUploadFileRequest(const ViewMsg_UploadFile_Params& p) {
2433 webkit_glue::FileUploadData* f = new webkit_glue::FileUploadData;
2434 f->file_path = p.file_path;
2435 f->form_name = p.form;
2436 f->file_name = p.file;
2437 f->submit_name = p.submit;
2438
2439 // Build the other form values map.
2440 if (!p.other_values.empty()) {
2441 std::vector<std::wstring> e;
2442 std::vector<std::wstring> kvp;
2443 std::vector<std::wstring>::iterator i;
2444
2445 SplitString(p.other_values, L'\n', &e);
2446 for (i = e.begin(); i != e.end(); ++i) {
2447 SplitString(*i, L'=', &kvp);
2448 if (kvp.size() == 2)
2449 f->other_form_values[kvp[0]] = kvp[1];
2450 kvp.clear();
2451 }
2452 }
2453
2454 pending_upload_data_.reset(f);
2455 ProcessPendingUpload();
2456}
2457
2458void RenderView::ProcessPendingUpload() {
2459 webkit_glue::FileUploadData* f = pending_upload_data_.get();
2460 if (f && webview() && webkit_glue::FillFormToUploadFile(webview(), *f))
2461 ResetPendingUpload();
2462}
2463
2464void RenderView::ResetPendingUpload() {
2465 pending_upload_data_.reset();
2466}
2467
2468void RenderView::OnFormFill(const FormData& form) {
2469 webkit_glue::FillForm(this->webview(), form);
2470}
2471
2472void RenderView::OnFillPasswordForm(
2473 const PasswordFormDomManager::FillData& form_data) {
2474 webkit_glue::FillPasswordForm(this->webview(), form_data);
2475}
2476
2477void RenderView::OnDragTargetDragEnter(const WebDropData& drop_data,
[email protected]e80c73b2009-04-07 23:24:582478 const gfx::Point& client_point,
2479 const gfx::Point& screen_point) {
2480 bool is_drop_target = webview()->DragTargetDragEnter(
2481 drop_data.ToDragData(),
2482 drop_data.identity,
2483 client_point,
2484 screen_point);
initial.commit09911bf2008-07-26 23:55:292485
2486 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target));
2487}
2488
[email protected]e80c73b2009-04-07 23:24:582489void RenderView::OnDragTargetDragOver(const gfx::Point& client_point,
2490 const gfx::Point& screen_point) {
2491 bool is_drop_target =
2492 webview()->DragTargetDragOver(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292493
2494 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target));
2495}
2496
2497void RenderView::OnDragTargetDragLeave() {
2498 webview()->DragTargetDragLeave();
2499}
2500
[email protected]e80c73b2009-04-07 23:24:582501void RenderView::OnDragTargetDrop(const gfx::Point& client_point,
2502 const gfx::Point& screen_point) {
2503 webview()->DragTargetDrop(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292504}
2505
2506void RenderView::OnUpdateWebPreferences(const WebPreferences& prefs) {
2507 webview()->SetPreferences(prefs);
2508}
2509
2510void RenderView::OnSetAltErrorPageURL(const GURL& url) {
2511 alternate_error_page_url_ = url;
2512}
2513
initial.commit09911bf2008-07-26 23:55:292514void RenderView::OnInstallMissingPlugin() {
2515 // This could happen when the first default plugin is deleted.
2516 if (first_default_plugin_ == NULL)
2517 return;
2518 first_default_plugin_->InstallMissingPlugin();
2519}
2520
[email protected]b62d1a8c2009-01-13 23:54:572521void RenderView::OnFileChooserResponse(
[email protected]561abe62009-04-06 18:08:342522 const std::vector<FilePath>& file_names) {
[email protected]8029f5672009-03-20 22:33:362523 // This could happen if we navigated to a different page before the user
2524 // closed the chooser.
2525 if (!file_chooser_.get())
2526 return;
2527
[email protected]b62d1a8c2009-01-13 23:54:572528 file_chooser_->OnFileChoose(file_names);
initial.commit09911bf2008-07-26 23:55:292529 file_chooser_.reset();
2530}
2531
2532void RenderView::OnEnableViewSourceMode() {
2533 if (!webview())
2534 return;
2535 WebFrame* main_frame = webview()->GetMainFrame();
2536 if (!main_frame)
2537 return;
2538
2539 main_frame->SetInViewSourceMode(true);
2540}
2541
[email protected]0666aef2009-05-13 19:48:082542void RenderView::OnEnableIntrinsicWidthChangedMode() {
2543 send_preferred_width_changes_ = true;
2544}
2545
[email protected]80d96fa2009-06-10 22:34:512546void RenderView::OnSetRendererPrefs(const RendererPreferences& renderer_prefs) {
2547 renderer_preferences_ = renderer_prefs;
2548}
2549
initial.commit09911bf2008-07-26 23:55:292550void RenderView::OnUpdateBackForwardListCount(int back_list_count,
2551 int forward_list_count) {
2552 history_back_list_count_ = back_list_count;
2553 history_forward_list_count_ = forward_list_count;
2554}
2555
[email protected]266eb6f2008-09-30 23:56:502556void RenderView::OnGetAccessibilityInfo(
[email protected]6a983b42009-03-20 20:12:252557 const webkit_glue::WebAccessibility::InParams& in_params,
2558 webkit_glue::WebAccessibility::OutParams* out_params) {
[email protected]6c8afae52009-01-22 02:24:572559#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:252560 if (!web_accessibility_manager_.get()) {
2561 web_accessibility_manager_.reset(
2562 webkit_glue::WebAccessibilityManager::Create());
2563 }
[email protected]266eb6f2008-09-30 23:56:502564
[email protected]6a983b42009-03-20 20:12:252565 if (!web_accessibility_manager_->GetAccObjInfo(webview(), in_params,
2566 out_params)) {
[email protected]266eb6f2008-09-30 23:56:502567 return;
2568 }
[email protected]6c8afae52009-01-22 02:24:572569#else // defined(OS_WIN)
2570 // TODO(port): accessibility not yet implemented
2571 NOTIMPLEMENTED();
2572#endif
[email protected]266eb6f2008-09-30 23:56:502573}
2574
[email protected]6a983b42009-03-20 20:12:252575void RenderView::OnClearAccessibilityInfo(int acc_obj_id, bool clear_all) {
[email protected]6c8afae52009-01-22 02:24:572576#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:252577 if (!web_accessibility_manager_.get()) {
[email protected]266eb6f2008-09-30 23:56:502578 // If accessibility is not activated, ignore clearing message.
2579 return;
2580 }
[email protected]e846d0d2009-05-20 00:53:062581
[email protected]6a983b42009-03-20 20:12:252582 if (!web_accessibility_manager_->ClearAccObjMap(acc_obj_id, clear_all))
[email protected]266eb6f2008-09-30 23:56:502583 return;
[email protected]e846d0d2009-05-20 00:53:062584
[email protected]6c8afae52009-01-22 02:24:572585#else // defined(OS_WIN)
2586 // TODO(port): accessibility not yet implemented
2587 NOTIMPLEMENTED();
2588#endif
[email protected]266eb6f2008-09-30 23:56:502589}
2590
initial.commit09911bf2008-07-26 23:55:292591void RenderView::OnGetAllSavableResourceLinksForCurrentPage(
2592 const GURL& page_url) {
2593 // Prepare list to storage all savable resource links.
2594 std::vector<GURL> resources_list;
2595 std::vector<GURL> referrers_list;
2596 std::vector<GURL> frames_list;
2597 webkit_glue::SavableResourcesResult result(&resources_list,
2598 &referrers_list,
2599 &frames_list);
2600
2601 if (!webkit_glue::GetAllSavableResourceLinksForCurrentPage(webview(),
2602 page_url,
2603 &result)) {
2604 // If something is wrong when collecting all savable resource links,
2605 // send empty list to embedder(browser) to tell it failed.
2606 referrers_list.clear();
2607 resources_list.clear();
2608 frames_list.clear();
2609 }
2610
2611 // Send result of all savable resource links to embedder.
2612 Send(new ViewHostMsg_SendCurrentPageAllSavableResourceLinks(routing_id_,
2613 resources_list,
2614 referrers_list,
2615 frames_list));
2616}
2617
2618void RenderView::OnGetSerializedHtmlDataForCurrentPageWithLocalLinks(
[email protected]f6b48532009-02-12 01:56:322619 const std::vector<GURL>& links,
[email protected]fde6714d12009-02-18 22:39:312620 const std::vector<FilePath>& local_paths,
2621 const FilePath& local_directory_name) {
initial.commit09911bf2008-07-26 23:55:292622 webkit_glue::DomSerializer dom_serializer(webview()->GetMainFrame(),
2623 true,
2624 this,
2625 links,
2626 local_paths,
2627 local_directory_name);
2628 dom_serializer.SerializeDom();
2629}
2630
2631void RenderView::DidSerializeDataForFrame(const GURL& frame_url,
2632 const std::string& data, PageSavingSerializationStatus status) {
2633 Send(new ViewHostMsg_SendSerializedHtmlData(routing_id_,
2634 frame_url, data, static_cast<int32>(status)));
2635}
2636
[email protected]04b4a6c2008-08-02 00:44:472637void RenderView::OnMsgShouldClose() {
initial.commit09911bf2008-07-26 23:55:292638 bool should_close = webview()->ShouldClose();
[email protected]04b4a6c2008-08-02 00:44:472639 Send(new ViewHostMsg_ShouldClose_ACK(routing_id_, should_close));
initial.commit09911bf2008-07-26 23:55:292640}
2641
2642void RenderView::OnClosePage(int new_render_process_host_id,
[email protected]04b4a6c2008-08-02 00:44:472643 int new_request_id) {
initial.commit09911bf2008-07-26 23:55:292644 // TODO(creis): We'd rather use webview()->Close() here, but that currently
2645 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs
2646 // in the onunload handler from appearing. For now, we're bypassing that and
2647 // calling the FrameLoader's CloseURL method directly. This should be
2648 // revisited to avoid having two ways to close a page. Having a single way
2649 // to close that can run onunload is also useful for fixing
2650 // http://b/issue?id=753080.
2651 WebFrame* main_frame = webview()->GetMainFrame();
2652 if (main_frame)
2653 main_frame->ClosePage();
2654
2655 Send(new ViewHostMsg_ClosePage_ACK(routing_id_,
2656 new_render_process_host_id,
[email protected]04b4a6c2008-08-02 00:44:472657 new_request_id));
initial.commit09911bf2008-07-26 23:55:292658}
2659
2660void RenderView::OnThemeChanged() {
[email protected]6c8afae52009-01-22 02:24:572661#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292662 gfx::NativeTheme::instance()->CloseHandles();
2663 gfx::Rect view_rect(0, 0, size_.width(), size_.height());
2664 DidInvalidateRect(webwidget_, view_rect);
[email protected]6c8afae52009-01-22 02:24:572665#else // defined(OS_WIN)
2666 // TODO(port): we don't support theming on non-Windows platforms yet
2667 NOTIMPLEMENTED();
2668#endif
initial.commit09911bf2008-07-26 23:55:292669}
2670
[email protected]f46aff62008-10-16 07:58:052671void RenderView::DidAddHistoryItem() {
[email protected]f8901082008-10-31 23:34:032672 // We don't want to update the history length for the start page
2673 // navigation.
2674 WebFrame* main_frame = webview()->GetMainFrame();
2675 DCHECK(main_frame != NULL);
2676
2677 WebDataSource* ds = main_frame->GetDataSource();
2678 DCHECK(ds != NULL);
2679
[email protected]77f17a82009-05-21 04:42:542680 NavigationState* navigation_state =
2681 static_cast<NavigationState*>(ds->GetExtraData());
[email protected]f8901082008-10-31 23:34:032682
[email protected]77f17a82009-05-21 04:42:542683 if (navigation_state &&
2684 navigation_state->transition_type == PageTransition::START_PAGE)
[email protected]f8901082008-10-31 23:34:032685 return;
2686
[email protected]f46aff62008-10-16 07:58:052687 history_back_list_count_++;
2688 history_forward_list_count_ = 0;
2689}
2690
[email protected]28790922009-03-09 19:48:372691void RenderView::OnMessageFromExternalHost(const std::string& message,
2692 const std::string& origin,
2693 const std::string& target) {
[email protected]3ac14a052008-08-15 21:22:152694 if (message.empty())
2695 return;
2696
[email protected]28790922009-03-09 19:48:372697 external_host_bindings_.ForwardMessageFromExternalHost(message, origin,
2698 target);
[email protected]3ac14a052008-08-15 21:22:152699}
2700
[email protected]0aa55312008-10-17 21:53:082701void RenderView::OnDisassociateFromPopupCount() {
2702 if (decrement_shared_popup_at_destruction_)
2703 shared_popup_counter_->data--;
2704 shared_popup_counter_ = new SharedRenderViewCounter(0);
2705 decrement_shared_popup_at_destruction_ = false;
2706}
2707
initial.commit09911bf2008-07-26 23:55:292708std::string RenderView::GetAltHTMLForTemplate(
2709 const DictionaryValue& error_strings, int template_resource_id) const {
2710 const StringPiece template_html(
2711 ResourceBundle::GetSharedInstance().GetRawDataResource(
2712 template_resource_id));
2713
2714 if (template_html.empty()) {
2715 NOTREACHED() << "unable to load template. ID: " << template_resource_id;
2716 return "";
2717 }
2718 // "t" is the id of the templates root node.
2719 return jstemplate_builder::GetTemplateHtml(
2720 template_html, &error_strings, "t");
2721}
[email protected]0e79b9e2009-02-13 04:20:482722
2723MessageLoop* RenderView::GetMessageLoopForIO() {
2724 // Assume that we have only one RenderThread in the process and the owner loop
2725 // of RenderThread is an IO message loop.
[email protected]8930d472009-02-21 08:05:282726 if (RenderThread::current())
2727 return RenderThread::current()->owner_loop();
[email protected]0e79b9e2009-02-13 04:20:482728 return NULL;
2729}
[email protected]6f56d482009-02-20 05:02:562730
[email protected]30f75e62009-02-25 22:01:002731void RenderView::OnMoveOrResizeStarted() {
2732 if (webview())
2733 webview()->HideAutofillPopup();
2734}
2735
[email protected]30f75e62009-02-25 22:01:002736void RenderView::OnResize(const gfx::Size& new_size,
2737 const gfx::Rect& resizer_rect) {
2738 if (webview())
2739 webview()->HideAutofillPopup();
2740 RenderWidget::OnResize(new_size, resizer_rect);
2741}
[email protected]0aa477bd2009-03-23 22:21:432742
[email protected]05d478752009-04-08 23:38:162743void RenderView::OnClearFocusedNode() {
2744 if (webview())
2745 webview()->ClearFocusedNode();
2746}
2747
[email protected]699ab0d2009-04-23 23:19:142748void RenderView::OnSetBackground(const SkBitmap& background) {
2749 if (webview())
2750 webview()->SetIsTransparent(!background.empty());
2751
2752 SetBackground(background);
2753}
2754
[email protected]309d7a282009-03-24 09:18:272755void RenderView::SendExtensionRequest(const std::string& name,
2756 const std::string& args,
[email protected]c6619182009-05-12 14:59:322757 int request_id,
[email protected]2f25d7b92009-06-10 00:06:472758 bool has_callback) {
[email protected]c6619182009-05-12 14:59:322759 Send(new ViewHostMsg_ExtensionRequest(routing_id_, name, args, request_id,
[email protected]2f25d7b92009-06-10 00:06:472760 has_callback));
[email protected]309d7a282009-03-24 09:18:272761}
2762
[email protected]c6619182009-05-12 14:59:322763void RenderView::OnExtensionResponse(int request_id,
2764 bool success,
2765 const std::string& response,
2766 const std::string& error) {
[email protected]2f25d7b92009-06-10 00:06:472767 ExtensionProcessBindings::HandleResponse(request_id, success, response,
2768 error);
[email protected]309d7a282009-03-24 09:18:272769}
[email protected]c20210e62009-04-03 21:39:262770
[email protected]e7e4f3c2009-04-21 15:24:082771// Dump all load time histograms.
[email protected]c20210e62009-04-03 21:39:262772//
[email protected]e7e4f3c2009-04-21 15:24:082773// There are 7 histograms measuring various times.
[email protected]c20210e62009-04-03 21:39:262774// The time points we keep are
2775// request: time document was requested by user
2776// start: time load of document started
2777// finishDoc: main document loaded, before onload()
2778// finish: after onload() and all resources are loaded
[email protected]e7e4f3c2009-04-21 15:24:082779// firstLayout: first layout performed
[email protected]c20210e62009-04-03 21:39:262780// The times that we histogram are
2781// requestToStart,
2782// startToFinishDoc,
2783// finishDocToFinish,
2784// startToFinish,
2785// requestToFinish,
[email protected]e7e4f3c2009-04-21 15:24:082786// requestToFirstLayout
2787// startToFirstLayout
[email protected]c20210e62009-04-03 21:39:262788//
[email protected]e7e4f3c2009-04-21 15:24:082789// It's possible for the request time not to be set, if a client
2790// redirect had been done (the user never requested the page)
2791// Also, it's possible to load a page without ever laying it out
2792// so firstLayout can be 0.
[email protected]c20210e62009-04-03 21:39:262793void RenderView::DumpLoadHistograms() const {
2794 WebFrame* main_frame = webview()->GetMainFrame();
2795 WebDataSource* ds = main_frame->GetDataSource();
[email protected]c20210e62009-04-03 21:39:262796 Time request_time = ds->GetRequestTime();
2797 Time start_load_time = ds->GetStartLoadTime();
2798 Time finish_document_load_time = ds->GetFinishDocumentLoadTime();
2799 Time finish_load_time = ds->GetFinishLoadTime();
[email protected]e7e4f3c2009-04-21 15:24:082800 Time first_layout_time = ds->GetFirstLayoutTime();
[email protected]c20210e62009-04-03 21:39:262801 TimeDelta request_to_start = start_load_time - request_time;
2802 TimeDelta start_to_finish_doc = finish_document_load_time - start_load_time;
[email protected]e7e4f3c2009-04-21 15:24:082803 TimeDelta finish_doc_to_finish =
2804 finish_load_time - finish_document_load_time;
[email protected]c20210e62009-04-03 21:39:262805 TimeDelta start_to_finish = finish_load_time - start_load_time;
2806 TimeDelta request_to_finish = finish_load_time - start_load_time;
[email protected]e7e4f3c2009-04-21 15:24:082807 TimeDelta request_to_first_layout = first_layout_time - request_time;
2808 TimeDelta start_to_first_layout = first_layout_time - start_load_time;
[email protected]c20210e62009-04-03 21:39:262809
[email protected]e7e4f3c2009-04-21 15:24:082810 // Client side redirects will have no request time
2811 if (request_time.ToInternalValue() != 0) {
[email protected]f929f2f22009-06-12 16:56:582812 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.RequestToStart", request_to_start);
2813 UMA_HISTOGRAM_CLIPPED_TIMES(
2814 FieldTrial::MakeName("Renderer2.RequestToFinish_L", "DnsImpact").data(),
2815 request_to_finish, base::TimeDelta::FromMilliseconds(10),
2816 base::TimeDelta::FromMinutes(10), 100);
[email protected]e7e4f3c2009-04-21 15:24:082817 if (request_to_first_layout.ToInternalValue() >= 0) {
[email protected]f929f2f22009-06-12 16:56:582818 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.RequestToFirstLayout",
[email protected]4646f292009-05-20 03:49:052819 request_to_first_layout);
[email protected]e7e4f3c2009-04-21 15:24:082820 }
2821 }
[email protected]f929f2f22009-06-12 16:56:582822 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.StartToFinishDoc", start_to_finish_doc);
2823 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.FinishDocToFinish",
2824 finish_doc_to_finish);
2825 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.StartToFinish", start_to_finish);
[email protected]e7e4f3c2009-04-21 15:24:082826 if (start_to_first_layout.ToInternalValue() >= 0) {
[email protected]f929f2f22009-06-12 16:56:582827 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.StartToFirstLayout",
2828 start_to_first_layout);
[email protected]c20210e62009-04-03 21:39:262829 }
2830}
[email protected]e846d0d2009-05-20 00:53:062831
2832void RenderView::FocusAccessibilityObject(
2833 WebCore::AccessibilityObject* acc_obj) {
2834#if defined(OS_WIN)
2835 if (!web_accessibility_manager_.get()) {
2836 web_accessibility_manager_.reset(
2837 webkit_glue::WebAccessibilityManager::Create());
2838 }
2839
2840 // Retrieve the accessibility object id of the AccessibilityObject.
2841 int acc_obj_id = web_accessibility_manager_->FocusAccObj(acc_obj);
2842
2843 // If id is valid, alert the browser side that an accessibility focus change
2844 // occurred.
2845 if (acc_obj_id >= 0)
2846 Send(new ViewHostMsg_AccessibilityFocusChange(routing_id_, acc_obj_id));
2847
2848#else // defined(OS_WIN)
2849 // TODO(port): accessibility not yet implemented
2850 NOTIMPLEMENTED();
2851#endif
2852}