blob: f6cc47c1bbf89009fe35a062ce2b2b7750fb9870 [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"
[email protected]8380c092009-06-25 17:45:5121#include "base/process_util.h"
initial.commit09911bf2008-07-26 23:55:2922#include "base/string_piece.h"
23#include "base/string_util.h"
[email protected]6c8afae52009-01-22 02:24:5724#include "build/build_config.h"
[email protected]81e63782009-02-27 19:35:0925#include "chrome/common/bindings_policy.h"
initial.commit09911bf2008-07-26 23:55:2926#include "chrome/common/chrome_switches.h"
[email protected]f0af6a72009-05-30 05:25:1727#include "chrome/common/chrome_constants.h"
initial.commit09911bf2008-07-26 23:55:2928#include "chrome/common/jstemplate_builder.h"
[email protected]630e26b2008-10-14 22:55:1729#include "chrome/common/page_zoom.h"
[email protected]e09ba552009-02-05 03:26:2930#include "chrome/common/render_messages.h"
[email protected]9b6f40e2009-06-11 15:54:2631#include "chrome/common/renderer_preferences.h"
initial.commit09911bf2008-07-26 23:55:2932#include "chrome/common/thumbnail_score.h"
[email protected]6de74452009-02-25 18:04:5933#include "chrome/common/url_constants.h"
initial.commit09911bf2008-07-26 23:55:2934#include "chrome/renderer/about_handler.h"
[email protected]5fb88962009-04-16 19:03:2535#include "chrome/renderer/audio_message_filter.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]ed3fb032009-06-16 19:50:5642#include "chrome/renderer/navigation_state.h"
[email protected]d81c1e52009-06-03 22:09:5043#include "chrome/renderer/print_web_view_helper.h"
[email protected]39008c02009-02-11 23:59:2544#include "chrome/renderer/render_process.h"
[email protected]fcf19542009-03-30 21:24:0745#include "chrome/renderer/renderer_logging.h"
[email protected]0938d3c2009-01-09 20:37:3546#include "chrome/renderer/user_script_slave.h"
initial.commit09911bf2008-07-26 23:55:2947#include "chrome/renderer/visitedlink_slave.h"
[email protected]ba4b17f2009-02-11 21:32:2948#include "chrome/renderer/webplugin_delegate_proxy.h"
[email protected]eb47a132009-03-04 00:39:5649#include "chrome/renderer/webworker_proxy.h"
[email protected]34ac8f32009-02-22 23:03:2750#include "grit/generated_resources.h"
51#include "grit/renderer_resources.h"
[email protected]f11ca0732009-04-11 00:09:3452#include "net/base/data_url.h"
initial.commit09911bf2008-07-26 23:55:2953#include "net/base/escape.h"
54#include "net/base/net_errors.h"
[email protected]c399a8a2008-11-22 19:38:0055#include "skia/ext/bitmap_platform_device.h"
[email protected]83c9e6552008-12-03 16:22:1056#include "skia/ext/image_operations.h"
[email protected]726985e22009-06-18 21:09:2857#include "webkit/api/public/WebDataSource.h"
[email protected]afdcf5c2009-05-10 20:30:4158#include "webkit/api/public/WebDragData.h"
[email protected]daa8c58e2009-06-15 17:21:1059#include "webkit/api/public/WebForm.h"
[email protected]afdcf5c2009-05-10 20:30:4160#include "webkit/api/public/WebPoint.h"
61#include "webkit/api/public/WebRect.h"
62#include "webkit/api/public/WebScriptSource.h"
63#include "webkit/api/public/WebSize.h"
[email protected]726985e22009-06-18 21:09:2864#include "webkit/api/public/WebURL.h"
65#include "webkit/api/public/WebURLError.h"
66#include "webkit/api/public/WebURLRequest.h"
67#include "webkit/api/public/WebURLResponse.h"
68#include "webkit/api/public/WebVector.h"
[email protected]ba4b17f2009-02-11 21:32:2969#include "webkit/default_plugin/default_plugin_shared.h"
initial.commit09911bf2008-07-26 23:55:2970#include "webkit/glue/dom_operations.h"
71#include "webkit/glue/dom_serializer.h"
[email protected]f11ca0732009-04-11 00:09:3472#include "webkit/glue/image_decoder.h"
[email protected]8380c092009-06-25 17:45:5173#include "webkit/glue/media/simple_data_source.h"
initial.commit09911bf2008-07-26 23:55:2974#include "webkit/glue/password_form.h"
[email protected]ba4b17f2009-02-11 21:32:2975#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:2976#include "webkit/glue/searchable_form_data.h"
[email protected]6a983b42009-03-20 20:12:2577#include "webkit/glue/webaccessibilitymanager_impl.h"
[email protected]611cad42009-03-16 18:51:3478#include "webkit/glue/webdevtoolsagent_delegate.h"
initial.commit09911bf2008-07-26 23:55:2979#include "webkit/glue/webdropdata.h"
initial.commit09911bf2008-07-26 23:55:2980#include "webkit/glue/webframe.h"
initial.commit09911bf2008-07-26 23:55:2981#include "webkit/glue/webkit_glue.h"
[email protected]add51772009-06-11 18:25:1782#include "webkit/glue/webmediaplayer_impl.h"
initial.commit09911bf2008-07-26 23:55:2983#include "webkit/glue/webpreferences.h"
[email protected]b94d3322009-02-12 19:49:0484#include "webkit/glue/webplugin_delegate.h"
[email protected]00d7e622009-04-21 23:06:0585#include "webkit/glue/webtextinput.h"
initial.commit09911bf2008-07-26 23:55:2986#include "webkit/glue/webview.h"
initial.commit09911bf2008-07-26 23:55:2987
[email protected]6c8afae52009-01-22 02:24:5788#if defined(OS_WIN)
89// TODO(port): these files are currently Windows only because they concern:
[email protected]6c8afae52009-01-22 02:24:5790// * theming
[email protected]6c8afae52009-01-22 02:24:5791#include "base/gfx/native_theme.h"
[email protected]6c8afae52009-01-22 02:24:5792#endif
93
[email protected]c20210e62009-04-03 21:39:2694using base::Time;
[email protected]e1acf6f2008-10-27 20:43:3395using base::TimeDelta;
[email protected]daa8c58e2009-06-15 17:21:1096using webkit_glue::AutofillForm;
[email protected]ed3fb032009-06-16 19:50:5697using webkit_glue::PasswordForm;
[email protected]daa8c58e2009-06-15 17:21:1098using webkit_glue::PasswordFormDomManager;
99using webkit_glue::SearchableFormData;
[email protected]0dea3ea2009-03-31 23:30:59100using WebKit::WebConsoleMessage;
[email protected]726985e22009-06-18 21:09:28101using WebKit::WebDataSource;
[email protected]e80c73b2009-04-07 23:24:58102using WebKit::WebDragData;
[email protected]daa8c58e2009-06-15 17:21:10103using WebKit::WebForm;
[email protected]726985e22009-06-18 21:09:28104using WebKit::WebNavigationType;
[email protected]b3f2b912009-04-09 16:18:52105using WebKit::WebRect;
[email protected]4f999132009-03-31 18:08:40106using WebKit::WebScriptSource;
[email protected]726985e22009-06-18 21:09:28107using WebKit::WebString;
108using WebKit::WebURL;
109using WebKit::WebURLError;
110using WebKit::WebURLRequest;
111using WebKit::WebURLResponse;
[email protected]27ba8532009-04-24 20:22:43112using WebKit::WebWorker;
113using WebKit::WebWorkerClient;
[email protected]726985e22009-06-18 21:09:28114using WebKit::WebVector;
[email protected]e1acf6f2008-10-27 20:43:33115
initial.commit09911bf2008-07-26 23:55:29116//-----------------------------------------------------------------------------
117
118// define to write the time necessary for thumbnail/DOM text retrieval,
119// respectively, into the system debug log
120// #define TIME_BITMAP_RETRIEVAL
121// #define TIME_TEXT_RETRIEVAL
122
123// maximum number of characters in the document to index, any text beyond this
124// point will be clipped
[email protected]6c8afae52009-01-22 02:24:57125static const size_t kMaxIndexChars = 65535;
initial.commit09911bf2008-07-26 23:55:29126
127// Size of the thumbnails that we'll generate
128static const int kThumbnailWidth = 196;
129static const int kThumbnailHeight = 136;
130
131// Delay in milliseconds that we'll wait before capturing the page contents
132// and thumbnail.
133static const int kDelayForCaptureMs = 500;
134
135// Typically, we capture the page data once the page is loaded.
136// Sometimes, the page never finishes to load, preventing the page capture
137// To workaround this problem, we always perform a capture after the following
138// delay.
139static const int kDelayForForcedCaptureMs = 6000;
140
[email protected]81a34412009-01-05 19:17:24141// The default value for RenderView.delay_seconds_for_form_state_sync_, see
142// that variable for more.
143const int kDefaultDelaySecondsForFormStateSync = 5;
initial.commit09911bf2008-07-26 23:55:29144
145// The next available page ID to use. This ensures that the page IDs are
146// globally unique in the renderer.
147static int32 next_page_id_ = 1;
148
[email protected]0aa55312008-10-17 21:53:08149// The maximum number of popups that can be spawned from one page.
150static const int kMaximumNumberOfUnacknowledgedPopups = 25;
151
initial.commit09911bf2008-07-26 23:55:29152static const char* const kUnreachableWebDataURL =
[email protected]60e448982009-05-06 04:21:16153 "chrome://chromewebdata/";
initial.commit09911bf2008-07-26 23:55:29154
[email protected]50b691c2008-10-31 19:08:35155static const char* const kBackForwardNavigationScheme = "history";
156
[email protected]726985e22009-06-18 21:09:28157static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
158 WebVector<WebURL> urls;
159 ds->redirectChain(urls);
160 result->reserve(urls.size());
161 for (size_t i = 0; i < urls.size(); ++i)
162 result->push_back(urls[i]);
163}
164
initial.commit09911bf2008-07-26 23:55:29165///////////////////////////////////////////////////////////////////////////////
166
[email protected]81a34412009-01-05 19:17:24167RenderView::RenderView(RenderThreadBase* render_thread)
168 : RenderWidget(render_thread, true),
[email protected]81e63782009-02-27 19:35:09169 enabled_bindings_(0),
[email protected]e75cb49e2009-01-05 23:13:21170 target_url_status_(TARGET_NONE),
[email protected]81a34412009-01-05 19:17:24171 is_loading_(false),
[email protected]e75cb49e2009-01-05 23:13:21172 navigation_gesture_(NavigationGestureUnknown),
[email protected]81a34412009-01-05 19:17:24173 page_id_(-1),
174 last_page_id_sent_to_browser_(-1),
175 last_indexed_page_id_(-1),
[email protected]81a34412009-01-05 19:17:24176 opened_by_user_gesture_(true),
[email protected]bb063b72009-03-27 23:18:50177 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
[email protected]81a34412009-01-05 19:17:24178 first_default_plugin_(NULL),
[email protected]e4ac5df2009-03-17 15:33:11179 devtools_agent_(NULL),
180 devtools_client_(NULL),
[email protected]81a34412009-01-05 19:17:24181 history_back_list_count_(0),
182 history_forward_list_count_(0),
[email protected]81a34412009-01-05 19:17:24183 has_unload_listener_(false),
184 decrement_shared_popup_at_destruction_(false),
[email protected]81a34412009-01-05 19:17:24185 form_field_autofill_request_id_(0),
186 popup_notification_visible_(false),
[email protected]0666aef2009-05-13 19:48:08187 delay_seconds_for_form_state_sync_(kDefaultDelaySecondsForFormStateSync),
188 preferred_width_(0),
[email protected]9b6f40e2009-06-11 15:54:26189 send_preferred_width_changes_(false) {
initial.commit09911bf2008-07-26 23:55:29190}
191
192RenderView::~RenderView() {
[email protected]0aa55312008-10-17 21:53:08193 if (decrement_shared_popup_at_destruction_)
194 shared_popup_counter_->data--;
195
initial.commit09911bf2008-07-26 23:55:29196 // Clear any back-pointers that might still be held by plugins.
197 PluginDelegateList::iterator it = plugin_delegates_.begin();
198 while (it != plugin_delegates_.end()) {
199 (*it)->DropRenderView();
200 it = plugin_delegates_.erase(it);
201 }
202
[email protected]5fb88962009-04-16 19:03:25203 render_thread_->RemoveFilter(audio_message_filter_);
initial.commit09911bf2008-07-26 23:55:29204}
205
206/*static*/
[email protected]0aa55312008-10-17 21:53:08207RenderView* RenderView::Create(
[email protected]81a34412009-01-05 19:17:24208 RenderThreadBase* render_thread,
[email protected]18bcc3c2009-01-27 21:39:15209 gfx::NativeViewId parent_hwnd,
[email protected]1c4947f2009-01-15 22:25:11210 base::WaitableEvent* modal_dialog_event,
[email protected]0aa55312008-10-17 21:53:08211 int32 opener_id,
[email protected]80d96fa2009-06-10 22:34:51212 const RendererPreferences& renderer_prefs,
[email protected]0aa55312008-10-17 21:53:08213 const WebPreferences& webkit_prefs,
214 SharedRenderViewCounter* counter,
215 int32 routing_id) {
initial.commit09911bf2008-07-26 23:55:29216 DCHECK(routing_id != MSG_ROUTING_NONE);
[email protected]81a34412009-01-05 19:17:24217 scoped_refptr<RenderView> view = new RenderView(render_thread);
initial.commit09911bf2008-07-26 23:55:29218 view->Init(parent_hwnd,
219 modal_dialog_event,
220 opener_id,
[email protected]80d96fa2009-06-10 22:34:51221 renderer_prefs,
initial.commit09911bf2008-07-26 23:55:29222 webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08223 counter,
initial.commit09911bf2008-07-26 23:55:29224 routing_id); // adds reference
225 return view;
226}
227
228/*static*/
229void RenderView::SetNextPageID(int32 next_page_id) {
230 // This method should only be called during process startup, and the given
231 // page id had better not exceed our current next page id!
[email protected]4646f292009-05-20 03:49:05232 DCHECK_EQ(next_page_id_, 1);
initial.commit09911bf2008-07-26 23:55:29233 DCHECK(next_page_id >= next_page_id_);
234 next_page_id_ = next_page_id;
235}
236
237void RenderView::PluginDestroyed(WebPluginDelegateProxy* proxy) {
238 PluginDelegateList::iterator it =
239 std::find(plugin_delegates_.begin(), plugin_delegates_.end(), proxy);
240 DCHECK(it != plugin_delegates_.end());
241 plugin_delegates_.erase(it);
242 // If the plugin is deleted, we need to clear our reference in case user
243 // clicks the info bar to install. Unfortunately we are getting
244 // PluginDestroyed in single process mode. However, that is not a huge
245 // concern.
246 if (proxy == first_default_plugin_)
247 first_default_plugin_ = NULL;
248}
249
[email protected]690a99c2009-01-06 16:48:45250void RenderView::PluginCrashed(const FilePath& plugin_path) {
initial.commit09911bf2008-07-26 23:55:29251 Send(new ViewHostMsg_CrashedPlugin(routing_id_, plugin_path));
252}
253
254
255void RenderView::JSOutOfMemory() {
256 Send(new ViewHostMsg_JSOutOfMemory(routing_id_));
257}
258
[email protected]18bcc3c2009-01-27 21:39:15259void RenderView::Init(gfx::NativeViewId parent_hwnd,
[email protected]1c4947f2009-01-15 22:25:11260 base::WaitableEvent* modal_dialog_event,
initial.commit09911bf2008-07-26 23:55:29261 int32 opener_id,
[email protected]80d96fa2009-06-10 22:34:51262 const RendererPreferences& renderer_prefs,
initial.commit09911bf2008-07-26 23:55:29263 const WebPreferences& webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08264 SharedRenderViewCounter* counter,
initial.commit09911bf2008-07-26 23:55:29265 int32 routing_id) {
266 DCHECK(!webview());
267
268 if (opener_id != MSG_ROUTING_NONE)
269 opener_id_ = opener_id;
270
[email protected]0aa55312008-10-17 21:53:08271 if (counter) {
272 shared_popup_counter_ = counter;
273 shared_popup_counter_->data++;
274 decrement_shared_popup_at_destruction_ = true;
275 } else {
276 shared_popup_counter_ = new SharedRenderViewCounter(0);
277 decrement_shared_popup_at_destruction_ = false;
278 }
279
[email protected]80d96fa2009-06-10 22:34:51280 OnSetRendererPrefs(renderer_prefs);
281
[email protected]58bfc6b2009-06-24 09:45:02282 devtools_agent_.reset(new DevToolsAgent(routing_id, this));
[email protected]9b9d7282009-04-08 14:13:04283
[email protected]c5b3b5e2009-02-13 06:41:11284 webwidget_ = WebView::Create(this, webkit_prefs);
initial.commit09911bf2008-07-26 23:55:29285
[email protected]2e417c82009-04-02 22:30:26286#if defined(OS_LINUX)
287 // We have to enable ourselves as the editor delegate on linux so we can copy
288 // text selections to the X clipboard.
289 webview()->SetUseEditorDelegate(true);
290#endif
291
initial.commit09911bf2008-07-26 23:55:29292 // Don't let WebCore keep a B/F list - we have our own.
293 // We let it keep 1 entry because FrameLoader::goToItem expects an item in the
294 // backForwardList, which is used only in ASSERTs.
295 webview()->SetBackForwardListSize(1);
296
297 routing_id_ = routing_id;
[email protected]81a34412009-01-05 19:17:24298 render_thread_->AddRoute(routing_id_, this);
initial.commit09911bf2008-07-26 23:55:29299 // Take a reference on behalf of the RenderThread. This will be balanced
300 // when we receive ViewMsg_Close.
301 AddRef();
302
303 // If this is a popup, we must wait for the CreatingNew_ACK message before
304 // completing initialization. Otherwise, we can finish it now.
305 if (opener_id == MSG_ROUTING_NONE) {
306 did_show_ = true;
307 CompleteInit(parent_hwnd);
308 }
309
310 host_window_ = parent_hwnd;
[email protected]1c4947f2009-01-15 22:25:11311 modal_dialog_event_.reset(modal_dialog_event);
initial.commit09911bf2008-07-26 23:55:29312
[email protected]58bfc6b2009-06-24 09:45:02313 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]81e63782009-02-27 19:35:09314 if (command_line.HasSwitch(switches::kDomAutomationController))
315 enabled_bindings_ |= BindingsPolicy::DOM_AUTOMATION;
initial.commit09911bf2008-07-26 23:55:29316
[email protected]5fb88962009-04-16 19:03:25317 audio_message_filter_ = new AudioMessageFilter(routing_id_);
318 render_thread_->AddFilter(audio_message_filter_);
initial.commit09911bf2008-07-26 23:55:29319}
320
321void RenderView::OnMessageReceived(const IPC::Message& message) {
[email protected]f8b6b6f2009-03-10 16:48:26322 WebFrame* main_frame = webview() ? webview()->GetMainFrame() : NULL;
323 renderer_logging::ScopedActiveRenderingURLSetter url_setter(
324 main_frame ? main_frame->GetURL() : GURL());
[email protected]f8b6b6f2009-03-10 16:48:26325
[email protected]b2abac72009-02-26 12:39:28326 // If this is developer tools renderer intercept tools messages first.
[email protected]e4ac5df2009-03-17 15:33:11327 if (devtools_client_.get() && devtools_client_->OnMessageReceived(message))
[email protected]b2abac72009-02-26 12:39:28328 return;
[email protected]b4b967e2009-04-22 11:33:05329 if (devtools_agent_.get() && devtools_agent_->OnMessageReceived(message))
330 return;
[email protected]b2abac72009-02-26 12:39:28331
initial.commit09911bf2008-07-26 23:55:29332 IPC_BEGIN_MESSAGE_MAP(RenderView, message)
initial.commit09911bf2008-07-26 23:55:29333 IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)
initial.commit09911bf2008-07-26 23:55:29334 IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)
[email protected]82270452009-06-19 15:58:01335 IPC_MESSAGE_HANDLER(ViewMsg_PrintingDone, OnPrintingDone)
initial.commit09911bf2008-07-26 23:55:29336 IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
337 IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
338 IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText)
339 IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
340 IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)
341 IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)
342 IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)
343 IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)
344 IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)
345 IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)
[email protected]bbbd545c2008-12-15 20:18:04346 IPC_MESSAGE_HANDLER(ViewMsg_ToggleSpellCheck, OnToggleSpellCheck)
initial.commit09911bf2008-07-26 23:55:29347 IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)
348 IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)
349 IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
[email protected]4b59ae602009-06-23 20:58:15350 IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand)
initial.commit09911bf2008-07-26 23:55:29351 IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
[email protected]630e26b2008-10-14 22:55:17352 IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
[email protected]ea8c7452009-04-02 20:47:06353 IPC_MESSAGE_HANDLER(ViewMsg_InsertText, OnInsertText)
initial.commit09911bf2008-07-26 23:55:29354 IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
[email protected]b2abac72009-02-26 12:39:28355 IPC_MESSAGE_HANDLER(ViewMsg_SetupDevToolsClient, OnSetupDevToolsClient)
initial.commit09911bf2008-07-26 23:55:29356 IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)
357 IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
[email protected]1810e132009-03-24 23:35:48358 IPC_MESSAGE_HANDLER(ViewMsg_CSSInsertRequest, OnCSSInsertRequest)
initial.commit09911bf2008-07-26 23:55:29359 IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)
initial.commit09911bf2008-07-26 23:55:29360 IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)
361 IPC_MESSAGE_HANDLER(ViewMsg_UploadFile, OnUploadFileRequest)
362 IPC_MESSAGE_HANDLER(ViewMsg_FormFill, OnFormFill)
363 IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)
364 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)
365 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)
366 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)
367 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)
[email protected]18cb2572008-08-21 20:34:45368 IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)
initial.commit09911bf2008-07-26 23:55:29369 IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)
[email protected]266eb6f2008-09-30 23:56:50370 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved,
371 OnDragSourceEndedOrMoved)
initial.commit09911bf2008-07-26 23:55:29372 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,
373 OnDragSourceSystemDragEnded)
374 IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)
375 IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)
376 IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)
377 IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
378 IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)
379 IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)
380 IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
381 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)
382 IPC_MESSAGE_HANDLER(ViewMsg_UpdateBackForwardListCount,
383 OnUpdateBackForwardListCount)
384 IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,
385 OnGetAllSavableResourceLinksForCurrentPage)
[email protected]f09c7182009-03-10 12:54:04386 IPC_MESSAGE_HANDLER(
387 ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,
388 OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)
initial.commit09911bf2008-07-26 23:55:29389 IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)
[email protected]266eb6f2008-09-30 23:56:50390 IPC_MESSAGE_HANDLER(ViewMsg_GetAccessibilityInfo, OnGetAccessibilityInfo)
391 IPC_MESSAGE_HANDLER(ViewMsg_ClearAccessibilityInfo,
392 OnClearAccessibilityInfo)
initial.commit09911bf2008-07-26 23:55:29393 IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose)
394 IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
395 IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)
[email protected]18cb2572008-08-21 20:34:45396 IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,
397 OnMessageFromExternalHost)
[email protected]0aa55312008-10-17 21:53:08398 IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
399 OnDisassociateFromPopupCount)
[email protected]0ebf3872008-11-07 21:35:03400 IPC_MESSAGE_HANDLER(ViewMsg_AutofillSuggestions,
401 OnReceivedAutofillSuggestions)
[email protected]2c4410d2009-05-06 23:46:22402 IPC_MESSAGE_HANDLER(ViewMsg_PopupNotificationVisibilityChanged,
403 OnPopupNotificationVisibilityChanged)
[email protected]30f75e62009-02-25 22:01:00404 IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
[email protected]309d7a282009-03-24 09:18:27405 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionResponse, OnExtensionResponse)
[email protected]05d478752009-04-08 23:38:16406 IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
[email protected]699ab0d2009-04-23 23:19:14407 IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
[email protected]0666aef2009-05-13 19:48:08408 IPC_MESSAGE_HANDLER(ViewMsg_EnableIntrinsicWidthChangedMode,
409 OnEnableIntrinsicWidthChangedMode)
[email protected]80d96fa2009-06-10 22:34:51410 IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
[email protected]634a6f92008-12-01 21:39:31411
initial.commit09911bf2008-07-26 23:55:29412 // Have the super handle all other messages.
413 IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))
414 IPC_END_MESSAGE_MAP()
415}
416
initial.commit09911bf2008-07-26 23:55:29417void RenderView::SendThumbnail() {
418 WebFrame* main_frame = webview()->GetMainFrame();
419 if (!main_frame)
420 return;
421
422 // get the URL for this page
423 GURL url(main_frame->GetURL());
424 if (url.is_empty())
425 return;
426
427 if (size_.IsEmpty())
428 return; // Don't create an empty thumbnail!
429
430 ThumbnailScore score;
431 SkBitmap thumbnail;
[email protected]b6e4bec2008-11-12 01:17:15432 if (!CaptureThumbnail(main_frame, kThumbnailWidth, kThumbnailHeight,
433 &thumbnail, &score))
434 return;
435
initial.commit09911bf2008-07-26 23:55:29436 // send the thumbnail message to the browser process
[email protected]674741932009-02-04 23:44:46437 Send(new ViewHostMsg_Thumbnail(routing_id_, url, score, thumbnail));
initial.commit09911bf2008-07-26 23:55:29438}
439
[email protected]068637222009-01-29 16:58:07440void RenderView::OnPrintPages() {
initial.commit09911bf2008-07-26 23:55:29441 DCHECK(webview());
[email protected]068637222009-01-29 16:58:07442 if (webview()) {
443 // The renderer own the control flow as if it was a window.print() call.
444 ScriptedPrint(webview()->GetMainFrame());
initial.commit09911bf2008-07-26 23:55:29445 }
initial.commit09911bf2008-07-26 23:55:29446}
447
[email protected]82270452009-06-19 15:58:01448void RenderView::OnPrintingDone(int document_cookie, bool success) {
449 // Ignoring document cookie here since only one print job can be outstanding
450 // per renderer and document_cookie is 0 when printing is successful.
451 DCHECK(print_helper_.get());
452 if (print_helper_.get() != NULL) {
453 print_helper_->DidFinishPrinting(success);
454 }
455}
456
initial.commit09911bf2008-07-26 23:55:29457void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) {
458 if (load_id != page_id_)
459 return; // this capture call is no longer relevant due to navigation
460 if (load_id == last_indexed_page_id_)
461 return; // we already indexed this page
462
463 if (!webview())
464 return;
465
466 WebFrame* main_frame = webview()->GetMainFrame();
467 if (!main_frame)
468 return;
469
470 // Don't index/capture pages that are in view source mode.
471 if (main_frame->GetInViewSourceMode())
472 return;
473
474 // Don't index/capture pages that failed to load. This only checks the top
475 // level frame so the thumbnail may contain a frame that failed to load.
476 WebDataSource* ds = main_frame->GetDataSource();
[email protected]726985e22009-06-18 21:09:28477 if (ds && ds->hasUnreachableURL())
initial.commit09911bf2008-07-26 23:55:29478 return;
479
480 if (!preliminary_capture)
481 last_indexed_page_id_ = load_id;
482
483 // get the URL for this page
484 GURL url(main_frame->GetURL());
485 if (url.is_empty())
486 return;
487
488 // full text
489 std::wstring contents;
490 CaptureText(main_frame, &contents);
491 if (contents.size()) {
492 // Send the text to the browser for indexing.
493 Send(new ViewHostMsg_PageContents(url, load_id, contents));
494 }
495
496 // thumbnail
497 SendThumbnail();
498}
499
500void RenderView::CaptureText(WebFrame* frame, std::wstring* contents) {
501 contents->clear();
502 if (!frame)
503 return;
504
[email protected]0faf0bd92008-09-09 20:53:27505 // Don't index any https pages. People generally don't want their bank
506 // accounts, etc. indexed on their computer, especially since some of these
507 // things are not marked cachable.
508 // TODO(brettw) we may want to consider more elaborate heuristics such as
509 // the cachability of the page. We may also want to consider subframes (this
510 // test will still index subframes if the subframe is SSL).
511 if (frame->GetURL().SchemeIsSecure())
512 return;
513
initial.commit09911bf2008-07-26 23:55:29514#ifdef TIME_TEXT_RETRIEVAL
515 double begin = time_util::GetHighResolutionTimeNow();
516#endif
517
518 // get the contents of the frame
519 frame->GetContentAsPlainText(kMaxIndexChars, contents);
520
521#ifdef TIME_TEXT_RETRIEVAL
522 double end = time_util::GetHighResolutionTimeNow();
523 char buf[128];
524 sprintf_s(buf, "%d chars retrieved for indexing in %gms\n",
525 contents.size(), (end - begin)*1000);
526 OutputDebugStringA(buf);
527#endif
528
529 // When the contents are clipped to the maximum, we don't want to have a
530 // partial word indexed at the end that might have been clipped. Therefore,
531 // terminate the string at the last space to ensure no words are clipped.
532 if (contents->size() == kMaxIndexChars) {
533 size_t last_space_index = contents->find_last_of(kWhitespaceWide);
534 if (last_space_index == std::wstring::npos)
535 return; // don't index if we got a huge block of text with no spaces
536 contents->resize(last_space_index);
537 }
538}
539
[email protected]b6e4bec2008-11-12 01:17:15540bool RenderView::CaptureThumbnail(WebFrame* frame,
initial.commit09911bf2008-07-26 23:55:29541 int w,
542 int h,
543 SkBitmap* thumbnail,
544 ThumbnailScore* score) {
545#ifdef TIME_BITMAP_RETRIEVAL
546 double begin = time_util::GetHighResolutionTimeNow();
547#endif
548
[email protected]21f527e2008-12-17 23:29:40549 scoped_ptr<skia::BitmapPlatformDevice> device;
[email protected]b6e4bec2008-11-12 01:17:15550 if (!frame->CaptureImage(&device, true))
551 return false;
552
553 const SkBitmap& src_bmp = device->accessBitmap(false);
initial.commit09911bf2008-07-26 23:55:29554
555 SkRect dest_rect;
556 dest_rect.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
557 float dest_aspect = dest_rect.width() / dest_rect.height();
558
559 // Get the src rect so that we can preserve the aspect ratio while filling
560 // the destination.
561 SkIRect src_rect;
562 if (src_bmp.width() < dest_rect.width() ||
563 src_bmp.height() < dest_rect.height()) {
564 // Source image is smaller: we clip the part of source image within the
565 // dest rect, and then stretch it to fill the dest rect. We don't respect
566 // the aspect ratio in this case.
567 src_rect.set(0, 0, static_cast<S16CPU>(dest_rect.width()),
568 static_cast<S16CPU>(dest_rect.height()));
569 score->good_clipping = false;
570 } else {
571 float src_aspect = static_cast<float>(src_bmp.width()) / src_bmp.height();
572 if (src_aspect > dest_aspect) {
573 // Wider than tall, clip horizontally: we center the smaller thumbnail in
574 // the wider screen.
575 S16CPU new_width = static_cast<S16CPU>(src_bmp.height() * dest_aspect);
576 S16CPU x_offset = (src_bmp.width() - new_width) / 2;
577 src_rect.set(x_offset, 0, new_width + x_offset, src_bmp.height());
578 score->good_clipping = false;
579 } else {
580 src_rect.set(0, 0, src_bmp.width(),
581 static_cast<S16CPU>(src_bmp.width() / dest_aspect));
582 score->good_clipping = true;
583 }
584 }
585
[email protected]b3f2b912009-04-09 16:18:52586 score->at_top = (frame->ScrollOffset().height == 0);
initial.commit09911bf2008-07-26 23:55:29587
588 SkBitmap subset;
[email protected]b6e4bec2008-11-12 01:17:15589 device->accessBitmap(false).extractSubset(&subset, src_rect);
initial.commit09911bf2008-07-26 23:55:29590
591 // Resample the subset that we want to get it the right size.
[email protected]465b34b72008-12-12 20:19:14592 *thumbnail = skia::ImageOperations::Resize(
593 subset, skia::ImageOperations::RESIZE_LANCZOS3, w, h);
initial.commit09911bf2008-07-26 23:55:29594
595 score->boring_score = CalculateBoringScore(thumbnail);
596
597#ifdef TIME_BITMAP_RETRIEVAL
598 double end = time_util::GetHighResolutionTimeNow();
599 char buf[128];
600 sprintf_s(buf, "thumbnail in %gms\n", (end - begin) * 1000);
601 OutputDebugStringA(buf);
602#endif
[email protected]b6e4bec2008-11-12 01:17:15603 return true;
initial.commit09911bf2008-07-26 23:55:29604}
605
606double RenderView::CalculateBoringScore(SkBitmap* bitmap) {
607 int histogram[256] = {0};
608 color_utils::BuildLumaHistogram(bitmap, histogram);
609
610 int color_count = *std::max_element(histogram, histogram + 256);
611 int pixel_count = bitmap->width() * bitmap->height();
612 return static_cast<double>(color_count) / pixel_count;
613}
614
615void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {
616 if (!webview())
617 return;
618
[email protected]f8b6b6f2009-03-10 16:48:26619 renderer_logging::ScopedActiveRenderingURLSetter url_setter(params.url);
[email protected]f8b6b6f2009-03-10 16:48:26620
initial.commit09911bf2008-07-26 23:55:29621 AboutHandler::MaybeHandle(params.url);
622
623 bool is_reload = params.reload;
624
625 WebFrame* main_frame = webview()->GetMainFrame();
[email protected]606843fa2008-12-02 19:08:56626 if (is_reload && !main_frame->HasCurrentHistoryState()) {
initial.commit09911bf2008-07-26 23:55:29627 // We cannot reload if we do not have any history state. This happens, for
628 // example, when recovering from a crash. Our workaround here is a bit of
629 // a hack since it means that reload after a crashed tab does not cause an
630 // end-to-end cache validation.
631 is_reload = false;
632 }
633
[email protected]77f17a82009-05-21 04:42:54634 // A navigation resulting from loading a javascript URL should not be treated
635 // as a browser initiated event. Instead, we want it to look as if the page
636 // initiated any load resulting from JS execution.
637 if (!params.url.SchemeIs(chrome::kJavaScriptScheme)) {
[email protected]daa8c58e2009-06-15 17:21:10638 pending_navigation_state_.reset(NavigationState::CreateBrowserInitiated(
[email protected]77f17a82009-05-21 04:42:54639 params.page_id, params.transition, params.request_time));
640 }
initial.commit09911bf2008-07-26 23:55:29641
[email protected]04d3c6e2009-05-22 17:00:13642 // If we are reloading, then WebKit will use the history state of the current
643 // page, so we should just ignore any given history state. Otherwise, if we
644 // have history state, then we need to navigate to it, which corresponds to a
645 // back/forward navigation event.
646 if (!is_reload && !params.state.empty()) {
647 // We must know the page ID of the page we are navigating back to.
[email protected]f929f2f22009-06-12 16:56:58648 DCHECK_NE(params.page_id, -1);
[email protected]04d3c6e2009-05-22 17:00:13649 main_frame->LoadHistoryState(params.state);
650 } else {
651 // Navigate to the given URL.
[email protected]726985e22009-06-18 21:09:28652 WebURLRequest request(params.url);
initial.commit09911bf2008-07-26 23:55:29653
[email protected]04d3c6e2009-05-22 17:00:13654 // TODO(darin): WebFrame should just have a Reload method.
655
[email protected]726985e22009-06-18 21:09:28656 WebURLRequest::CachePolicy cache_policy;
[email protected]04d3c6e2009-05-22 17:00:13657 if (is_reload) {
[email protected]726985e22009-06-18 21:09:28658 cache_policy = WebURLRequest::ReloadIgnoringCacheData;
[email protected]04d3c6e2009-05-22 17:00:13659 } else {
660 // A session history navigation should have been accompanied by state.
[email protected]f929f2f22009-06-12 16:56:58661 DCHECK_EQ(params.page_id, -1);
[email protected]04d3c6e2009-05-22 17:00:13662 if (main_frame->GetInViewSourceMode()) {
[email protected]726985e22009-06-18 21:09:28663 cache_policy = WebURLRequest::ReturnCacheDataElseLoad;
[email protected]04d3c6e2009-05-22 17:00:13664 } else {
[email protected]726985e22009-06-18 21:09:28665 cache_policy = WebURLRequest::UseProtocolCachePolicy;
[email protected]04d3c6e2009-05-22 17:00:13666 }
667 }
[email protected]726985e22009-06-18 21:09:28668 request.setCachePolicy(cache_policy);
[email protected]04d3c6e2009-05-22 17:00:13669
[email protected]726985e22009-06-18 21:09:28670 if (params.referrer.is_valid()) {
671 request.setHTTPHeaderField(WebString::fromUTF8("Referer"),
672 WebString::fromUTF8(params.referrer.spec()));
673 }
[email protected]04d3c6e2009-05-22 17:00:13674
[email protected]726985e22009-06-18 21:09:28675 main_frame->LoadRequest(request);
[email protected]c0588052008-10-27 23:01:50676 }
677
[email protected]77f17a82009-05-21 04:42:54678 // In case LoadRequest failed before DidCreateDataSource was called.
679 pending_navigation_state_.reset();
initial.commit09911bf2008-07-26 23:55:29680}
681
682// Stop loading the current page
683void RenderView::OnStop() {
684 if (webview())
685 webview()->StopLoading();
686}
687
688void RenderView::OnLoadAlternateHTMLText(const std::string& html_contents,
689 bool new_navigation,
690 const GURL& display_url,
691 const std::string& security_info) {
692 if (!webview())
693 return;
694
[email protected]726985e22009-06-18 21:09:28695 WebURLRequest request;
696 request.initialize();
697 request.setURL(GURL(kUnreachableWebDataURL));
698 request.setSecurityInfo(security_info);
initial.commit09911bf2008-07-26 23:55:29699
[email protected]726985e22009-06-18 21:09:28700 webview()->GetMainFrame()->LoadAlternateHTMLString(request,
initial.commit09911bf2008-07-26 23:55:29701 html_contents,
702 display_url,
703 !new_navigation);
704}
705
706void RenderView::OnCopyImageAt(int x, int y) {
707 webview()->CopyImageAt(x, y);
708}
709
[email protected]68b1e922009-06-23 16:00:25710void RenderView::OnExecuteEditCommand(const std::string& name,
711 const std::string& value) {
712 if (!webview() || !webview()->GetFocusedFrame())
713 return;
714
[email protected]4b59ae602009-06-23 20:58:15715 webview()->GetFocusedFrame()->ExecuteEditCommandByName(name, value);
[email protected]68b1e922009-06-23 16:00:25716}
717
[email protected]b2abac72009-02-26 12:39:28718void RenderView::OnSetupDevToolsClient() {
[email protected]e4ac5df2009-03-17 15:33:11719 DCHECK(!devtools_client_.get());
720 devtools_client_.reset(new DevToolsClient(this));
[email protected]b2abac72009-02-26 12:39:28721}
722
initial.commit09911bf2008-07-26 23:55:29723void RenderView::OnStopFinding(bool clear_selection) {
724 WebView* view = webview();
725 if (!view)
726 return;
727
728 if (clear_selection)
729 view->GetFocusedFrame()->ClearSelection();
730
731 WebFrame* frame = view->GetMainFrame();
732 while (frame) {
[email protected]65134c432008-09-26 21:47:20733 frame->StopFinding(clear_selection);
initial.commit09911bf2008-07-26 23:55:29734 frame = view->GetNextFrameAfter(frame, false);
735 }
736}
737
738void RenderView::OnFindReplyAck() {
739 // Check if there is any queued up request waiting to be sent.
740 if (queued_find_reply_message_.get()) {
741 // Send the search result over to the browser process.
742 Send(queued_find_reply_message_.get());
743 queued_find_reply_message_.release();
744 }
745}
746
747void RenderView::OnUpdateTargetURLAck() {
748 // Check if there is a targeturl waiting to be sent.
749 if (target_url_status_ == TARGET_PENDING) {
750 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_,
751 pending_target_url_));
752 }
753
754 target_url_status_ = TARGET_NONE;
755}
756
757void RenderView::OnUndo() {
758 if (!webview())
759 return;
760
761 webview()->GetFocusedFrame()->Undo();
762}
763
764void RenderView::OnRedo() {
765 if (!webview())
766 return;
767
768 webview()->GetFocusedFrame()->Redo();
769}
770
771void RenderView::OnCut() {
772 if (!webview())
773 return;
774
775 webview()->GetFocusedFrame()->Cut();
776}
777
778void RenderView::OnCopy() {
779 if (!webview())
780 return;
781
782 webview()->GetFocusedFrame()->Copy();
783}
784
785void RenderView::OnPaste() {
786 if (!webview())
787 return;
788
789 webview()->GetFocusedFrame()->Paste();
790}
791
792void RenderView::OnReplace(const std::wstring& text) {
793 if (!webview())
794 return;
795
796 webview()->GetFocusedFrame()->Replace(text);
797}
798
[email protected]bbbd545c2008-12-15 20:18:04799void RenderView::OnToggleSpellCheck() {
800 if (!webview())
801 return;
802
803 webview()->GetFocusedFrame()->ToggleSpellCheck();
804}
805
initial.commit09911bf2008-07-26 23:55:29806void RenderView::OnDelete() {
807 if (!webview())
808 return;
809
810 webview()->GetFocusedFrame()->Delete();
811}
812
813void RenderView::OnSelectAll() {
814 if (!webview())
815 return;
816
817 webview()->GetFocusedFrame()->SelectAll();
818}
819
820void RenderView::OnSetInitialFocus(bool reverse) {
821 if (!webview())
822 return;
823 webview()->SetInitialFocus(reverse);
824}
825
826///////////////////////////////////////////////////////////////////////////////
827
828// Tell the embedding application that the URL of the active page has changed
829void RenderView::UpdateURL(WebFrame* frame) {
830 WebDataSource* ds = frame->GetDataSource();
831 DCHECK(ds);
832
[email protected]726985e22009-06-18 21:09:28833 const WebURLRequest& request = ds->request();
834 const WebURLRequest& original_request = ds->originalRequest();
835 const WebURLResponse& response = ds->response();
initial.commit09911bf2008-07-26 23:55:29836
[email protected]daa8c58e2009-06-15 17:21:10837 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
838 DCHECK(navigation_state);
initial.commit09911bf2008-07-26 23:55:29839
840 ViewHostMsg_FrameNavigate_Params params;
[email protected]726985e22009-06-18 21:09:28841 params.http_status_code = response.httpStatusCode();
initial.commit09911bf2008-07-26 23:55:29842 params.is_post = false;
843 params.page_id = page_id_;
[email protected]726985e22009-06-18 21:09:28844 params.is_content_filtered = response.isContentFiltered();
845 if (!request.securityInfo().isEmpty()) {
initial.commit09911bf2008-07-26 23:55:29846 // SSL state specified in the request takes precedence over the one in the
847 // response.
848 // So far this is only intended for error pages that are not expected to be
849 // over ssl, so we should not get any clash.
[email protected]726985e22009-06-18 21:09:28850 DCHECK(response.securityInfo().isEmpty());
851 params.security_info = request.securityInfo();
initial.commit09911bf2008-07-26 23:55:29852 } else {
[email protected]726985e22009-06-18 21:09:28853 params.security_info = response.securityInfo();
initial.commit09911bf2008-07-26 23:55:29854 }
855
856 // Set the URL to be displayed in the browser UI to the user.
[email protected]726985e22009-06-18 21:09:28857 if (ds->hasUnreachableURL()) {
858 params.url = ds->unreachableURL();
initial.commit09911bf2008-07-26 23:55:29859 } else {
[email protected]726985e22009-06-18 21:09:28860 params.url = request.url();
initial.commit09911bf2008-07-26 23:55:29861 }
862
[email protected]726985e22009-06-18 21:09:28863 GetRedirectChain(ds, &params.redirects);
864 params.should_update_history = !ds->hasUnreachableURL();
initial.commit09911bf2008-07-26 23:55:29865
866 const SearchableFormData* searchable_form_data =
[email protected]daa8c58e2009-06-15 17:21:10867 navigation_state->searchable_form_data();
initial.commit09911bf2008-07-26 23:55:29868 if (searchable_form_data) {
869 params.searchable_form_url = searchable_form_data->url();
870 params.searchable_form_element_name = searchable_form_data->element_name();
871 params.searchable_form_encoding = searchable_form_data->encoding();
872 }
873
874 const PasswordForm* password_form_data =
[email protected]daa8c58e2009-06-15 17:21:10875 navigation_state->password_form_data();
initial.commit09911bf2008-07-26 23:55:29876 if (password_form_data)
877 params.password_form = *password_form_data;
878
879 params.gesture = navigation_gesture_;
880 navigation_gesture_ = NavigationGestureUnknown;
881
[email protected]77f17a82009-05-21 04:42:54882 if (!frame->GetParent()) {
initial.commit09911bf2008-07-26 23:55:29883 // Top-level navigation.
884
885 // Update contents MIME type for main frame.
[email protected]726985e22009-06-18 21:09:28886 params.contents_mime_type = UTF16ToUTF8(ds->response().mimeType());
initial.commit09911bf2008-07-26 23:55:29887
[email protected]daa8c58e2009-06-15 17:21:10888 params.transition = navigation_state->transition_type();
initial.commit09911bf2008-07-26 23:55:29889 if (!PageTransition::IsMainFrame(params.transition)) {
890 // If the main frame does a load, it should not be reported as a subframe
891 // navigation. This can occur in the following case:
892 // 1. You're on a site with frames.
893 // 2. You do a subframe navigation. This is stored with transition type
894 // MANUAL_SUBFRAME.
895 // 3. You navigate to some non-frame site, say, google.com.
896 // 4. You navigate back to the page from step 2. Since it was initially
897 // MANUAL_SUBFRAME, it will be that same transition type here.
898 // We don't want that, because any navigation that changes the toplevel
899 // frame should be tracked as a toplevel navigation (this allows us to
900 // update the URL bar, etc).
901 params.transition = PageTransition::LINK;
902 }
903
initial.commit09911bf2008-07-26 23:55:29904 // If we have a valid consumed client redirect source,
905 // the page contained a client redirect (meta refresh, document.loc...),
906 // so we set the referrer and transition to match.
907 if (completed_client_redirect_src_.is_valid()) {
[email protected]77e09a92008-08-01 18:11:04908 DCHECK(completed_client_redirect_src_ == params.redirects[0]);
initial.commit09911bf2008-07-26 23:55:29909 params.referrer = completed_client_redirect_src_;
910 params.transition = static_cast<PageTransition::Type>(
911 params.transition | PageTransition::CLIENT_REDIRECT);
912 } else {
913 // Bug 654101: the referrer will be empty on https->http transitions. It
914 // would be nice if we could get the real referrer from somewhere.
[email protected]726985e22009-06-18 21:09:28915 params.referrer = GURL(
916 original_request.httpHeaderField(WebString::fromUTF8("Referer")));
initial.commit09911bf2008-07-26 23:55:29917 }
918
[email protected]726985e22009-06-18 21:09:28919 string16 method = request.httpMethod();
920 if (EqualsASCII(method, "POST"))
initial.commit09911bf2008-07-26 23:55:29921 params.is_post = true;
922
923 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
924 } else {
925 // Subframe navigation: the type depends on whether this navigation
926 // generated a new session history entry. When they do generate a session
927 // history entry, it means the user initiated the navigation and we should
928 // mark it as such. This test checks if this is the first time UpdateURL
929 // has been called since WillNavigateToURL was called to initiate the load.
930 if (page_id_ > last_page_id_sent_to_browser_)
931 params.transition = PageTransition::MANUAL_SUBFRAME;
932 else
933 params.transition = PageTransition::AUTO_SUBFRAME;
934
initial.commit09911bf2008-07-26 23:55:29935 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
936 }
937
938 last_page_id_sent_to_browser_ =
939 std::max(last_page_id_sent_to_browser_, page_id_);
940
941 // If we end up reusing this WebRequest (for example, due to a #ref click),
[email protected]daa8c58e2009-06-15 17:21:10942 // we don't want the transition type to persist. Just clear it.
943 navigation_state->set_transition_type(PageTransition::LINK);
[email protected]266eb6f2008-09-30 23:56:50944
[email protected]6c8afae52009-01-22 02:24:57945#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:25946 if (web_accessibility_manager_.get()) {
[email protected]be645db2009-02-06 20:36:33947 // Clear accessibility info cache.
[email protected]6a983b42009-03-20 20:12:25948 web_accessibility_manager_->ClearAccObjMap(-1, true);
[email protected]266eb6f2008-09-30 23:56:50949 }
[email protected]6c8afae52009-01-22 02:24:57950#else
[email protected]7d926f92009-03-03 14:26:54951 // TODO(port): accessibility not yet implemented. See http://crbug.com/8288.
[email protected]6c8afae52009-01-22 02:24:57952#endif
initial.commit09911bf2008-07-26 23:55:29953}
954
955// Tell the embedding application that the title of the active page has changed
956void RenderView::UpdateTitle(WebFrame* frame, const std::wstring& title) {
957 // Ignore all but top level navigations...
[email protected]f0af6a72009-05-30 05:25:17958 if (webview()->GetMainFrame() == frame) {
959 Send(new ViewHostMsg_UpdateTitle(
960 routing_id_,
961 page_id_,
962 title.length() > chrome::kMaxTitleChars ?
963 title.substr(0, chrome::kMaxTitleChars) : title));
964 }
initial.commit09911bf2008-07-26 23:55:29965}
966
967void RenderView::UpdateEncoding(WebFrame* frame,
[email protected]e38f40152008-09-12 23:08:30968 const std::wstring& encoding_name) {
initial.commit09911bf2008-07-26 23:55:29969 // Only update main frame's encoding_name.
970 if (webview()->GetMainFrame() == frame &&
971 last_encoding_name_ != encoding_name) {
[email protected]e38f40152008-09-12 23:08:30972 // Save the encoding name for later comparing.
initial.commit09911bf2008-07-26 23:55:29973 last_encoding_name_ = encoding_name;
974
[email protected]e38f40152008-09-12 23:08:30975 Send(new ViewHostMsg_UpdateEncoding(routing_id_, last_encoding_name_));
initial.commit09911bf2008-07-26 23:55:29976 }
977}
978
[email protected]f4d34b52008-11-24 23:05:01979// Sends the previous session history state to the browser so it will be saved
980// before we navigate to a new page. This must be called *before* the page ID
981// has been updated so we know what it was.
initial.commit09911bf2008-07-26 23:55:29982void RenderView::UpdateSessionHistory(WebFrame* frame) {
983 // If we have a valid page ID at this point, then it corresponds to the page
984 // we are navigating away from. Otherwise, this is the first navigation, so
985 // there is no past session history to record.
986 if (page_id_ == -1)
987 return;
988
initial.commit09911bf2008-07-26 23:55:29989 std::string state;
[email protected]606843fa2008-12-02 19:08:56990 if (!webview()->GetMainFrame()->GetPreviousHistoryState(&state))
initial.commit09911bf2008-07-26 23:55:29991 return;
[email protected]606843fa2008-12-02 19:08:56992 Send(new ViewHostMsg_UpdateState(routing_id_, page_id_, state));
initial.commit09911bf2008-07-26 23:55:29993}
994
995///////////////////////////////////////////////////////////////////////////////
996// WebViewDelegate
997
[email protected]80d96fa2009-06-10 22:34:51998bool RenderView::CanAcceptLoadDrops() const {
999 return renderer_preferences_.can_accept_load_drops;
1000}
1001
initial.commit09911bf2008-07-26 23:55:291002void RenderView::DidStartLoading(WebView* webview) {
1003 if (is_loading_) {
1004 DLOG(WARNING) << "DidStartLoading called while loading";
1005 return;
1006 }
1007
1008 is_loading_ = true;
1009 // Clear the pointer so that we can assign it only when there is an unknown
1010 // plugin on a page.
1011 first_default_plugin_ = NULL;
1012
[email protected]329581b2009-04-28 06:52:351013 Send(new ViewHostMsg_DidStartLoading(routing_id_));
initial.commit09911bf2008-07-26 23:55:291014}
1015
1016void RenderView::DidStopLoading(WebView* webview) {
1017 if (!is_loading_) {
1018 DLOG(WARNING) << "DidStopLoading called while not loading";
1019 return;
1020 }
1021
1022 is_loading_ = false;
1023
1024 // NOTE: For now we're doing the safest thing, and sending out notification
1025 // when done loading. This currently isn't an issue as the favicon is only
1026 // displayed when done loading. Ideally we would send notification when
1027 // finished parsing the head, but webkit doesn't support that yet.
1028 // The feed discovery code would also benefit from access to the head.
1029 GURL favicon_url(webview->GetMainFrame()->GetFavIconURL());
1030 if (!favicon_url.is_empty())
1031 Send(new ViewHostMsg_UpdateFavIconURL(routing_id_, page_id_, favicon_url));
1032
1033 AddGURLSearchProvider(webview->GetMainFrame()->GetOSDDURL(),
1034 true); // autodetected
1035
[email protected]329581b2009-04-28 06:52:351036 Send(new ViewHostMsg_DidStopLoading(routing_id_));
initial.commit09911bf2008-07-26 23:55:291037
1038 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1039 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo, page_id_,
1040 false),
1041 kDelayForCaptureMs);
1042
1043 // The page is loaded. Try to process the file we need to upload if any.
1044 ProcessPendingUpload();
1045
1046 // Since the page is done loading, we are sure we don't need to try
1047 // again.
1048 ResetPendingUpload();
1049}
1050
[email protected]77f17a82009-05-21 04:42:541051void RenderView::DidCreateDataSource(WebFrame* frame, WebDataSource* ds) {
[email protected]daa8c58e2009-06-15 17:21:101052 // The rest of RenderView assumes that a WebDataSource will always have a
1053 // non-null NavigationState.
1054 if (pending_navigation_state_.get()) {
[email protected]726985e22009-06-18 21:09:281055 ds->setExtraData(pending_navigation_state_.release());
[email protected]daa8c58e2009-06-15 17:21:101056 } else {
[email protected]726985e22009-06-18 21:09:281057 ds->setExtraData(NavigationState::CreateContentInitiated());
[email protected]daa8c58e2009-06-15 17:21:101058 }
[email protected]77f17a82009-05-21 04:42:541059}
1060
initial.commit09911bf2008-07-26 23:55:291061void RenderView::DidStartProvisionalLoadForFrame(
1062 WebView* webview,
1063 WebFrame* frame,
1064 NavigationGesture gesture) {
[email protected]ed3fb032009-06-16 19:50:561065 WebDataSource* ds = frame->GetProvisionalDataSource();
1066 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
1067
1068 navigation_state->set_start_load_time(Time::Now());
1069
1070 // Update the request time if WebKit has better knowledge of it.
1071 if (navigation_state->request_time().is_null()) {
[email protected]726985e22009-06-18 21:09:281072 double event_time = ds->triggeringEventTime();
[email protected]ed3fb032009-06-16 19:50:561073 if (event_time != 0.0)
1074 navigation_state->set_request_time(Time::FromDoubleT(event_time));
1075 }
1076
1077 bool is_top_most = !frame->GetParent();
1078 if (is_top_most) {
initial.commit09911bf2008-07-26 23:55:291079 navigation_gesture_ = gesture;
[email protected]266eb6f2008-09-30 23:56:501080
[email protected]77e09a92008-08-01 18:11:041081 // Make sure redirect tracking state is clear for the new load.
1082 completed_client_redirect_src_ = GURL();
1083 }
initial.commit09911bf2008-07-26 23:55:291084
1085 Send(new ViewHostMsg_DidStartProvisionalLoadForFrame(
[email protected]726985e22009-06-18 21:09:281086 routing_id_, is_top_most, ds->request().url()));
initial.commit09911bf2008-07-26 23:55:291087}
1088
1089bool RenderView::DidLoadResourceFromMemoryCache(WebView* webview,
[email protected]726985e22009-06-18 21:09:281090 const WebURLRequest& request,
1091 const WebURLResponse& response,
initial.commit09911bf2008-07-26 23:55:291092 WebFrame* frame) {
1093 // Let the browser know we loaded a resource from the memory cache. This
1094 // message is needed to display the correct SSL indicators.
1095 Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(routing_id_,
[email protected]726985e22009-06-18 21:09:281096 request.url(), frame->GetSecurityOrigin(),
[email protected]ffc45862009-03-17 06:11:081097 frame->GetTop()->GetSecurityOrigin(),
[email protected]726985e22009-06-18 21:09:281098 response.securityInfo()));
initial.commit09911bf2008-07-26 23:55:291099
1100 return false;
1101}
1102
1103void RenderView::DidReceiveProvisionalLoadServerRedirect(WebView* webview,
1104 WebFrame* frame) {
1105 if (frame == webview->GetMainFrame()) {
1106 // Received a redirect on the main frame.
1107 WebDataSource* data_source =
1108 webview->GetMainFrame()->GetProvisionalDataSource();
1109 if (!data_source) {
1110 // Should only be invoked when we have a data source.
1111 NOTREACHED();
1112 return;
1113 }
[email protected]726985e22009-06-18 21:09:281114 std::vector<GURL> redirects;
1115 GetRedirectChain(data_source, &redirects);
initial.commit09911bf2008-07-26 23:55:291116 if (redirects.size() >= 2) {
1117 Send(new ViewHostMsg_DidRedirectProvisionalLoad(
1118 routing_id_, page_id_, redirects[redirects.size() - 2],
1119 redirects[redirects.size() - 1]));
1120 }
1121 }
1122}
1123
1124void RenderView::DidFailProvisionalLoadWithError(WebView* webview,
[email protected]726985e22009-06-18 21:09:281125 const WebURLError& error,
initial.commit09911bf2008-07-26 23:55:291126 WebFrame* frame) {
1127 // Notify the browser that we failed a provisional load with an error.
1128 //
1129 // Note: It is important this notification occur before DidStopLoading so the
1130 // SSL manager can react to the provisional load failure before being
1131 // notified the load stopped.
1132 //
1133 WebDataSource* ds = frame->GetProvisionalDataSource();
1134 DCHECK(ds);
1135
[email protected]726985e22009-06-18 21:09:281136 const WebURLRequest& failed_request = ds->request();
initial.commit09911bf2008-07-26 23:55:291137
1138 bool show_repost_interstitial =
[email protected]726985e22009-06-18 21:09:281139 (error.reason == net::ERR_CACHE_MISS &&
1140 EqualsASCII(failed_request.httpMethod(), "POST"));
initial.commit09911bf2008-07-26 23:55:291141 Send(new ViewHostMsg_DidFailProvisionalLoadWithError(
[email protected]726985e22009-06-18 21:09:281142 routing_id_, !frame->GetParent(),
1143 error.reason, error.unreachableURL,
initial.commit09911bf2008-07-26 23:55:291144 show_repost_interstitial));
1145
initial.commit09911bf2008-07-26 23:55:291146 // Don't display an error page if this is simply a cancelled load. Aside
1147 // from being dumb, WebCore doesn't expect it and it will cause a crash.
[email protected]726985e22009-06-18 21:09:281148 if (error.reason == net::ERR_ABORTED)
initial.commit09911bf2008-07-26 23:55:291149 return;
1150
[email protected]546ddd172009-06-25 00:25:011151 // Make sure we never show errors in view source mode.
1152 frame->SetInViewSourceMode(false);
1153
initial.commit09911bf2008-07-26 23:55:291154 // If this is a failed back/forward/reload navigation, then we need to do a
1155 // 'replace' load. This is necessary to avoid messing up session history.
1156 // Otherwise, we do a normal load, which simulates a 'go' navigation as far
1157 // as session history is concerned.
[email protected]daa8c58e2009-06-15 17:21:101158 bool replace = !NavigationState::FromDataSource(ds)->is_new_navigation();
initial.commit09911bf2008-07-26 23:55:291159
[email protected]5df266ac2008-10-15 19:50:131160 // Use the alternate error page service if this is a DNS failure or
1161 // connection failure. ERR_CONNECTION_FAILED can be dropped once we no longer
1162 // use winhttp.
[email protected]726985e22009-06-18 21:09:281163 int ec = error.reason;
[email protected]5df266ac2008-10-15 19:50:131164 if (ec == net::ERR_NAME_NOT_RESOLVED ||
1165 ec == net::ERR_CONNECTION_FAILED ||
1166 ec == net::ERR_CONNECTION_REFUSED ||
1167 ec == net::ERR_ADDRESS_UNREACHABLE ||
1168 ec == net::ERR_TIMED_OUT) {
[email protected]726985e22009-06-18 21:09:281169 const GURL& failed_url = error.unreachableURL;
[email protected]5df266ac2008-10-15 19:50:131170 const GURL& error_page_url = GetAlternateErrorPageURL(failed_url,
1171 ec == net::ERR_NAME_NOT_RESOLVED ? WebViewDelegate::DNS_ERROR
1172 : WebViewDelegate::CONNECTION_ERROR);
1173 if (error_page_url.is_valid()) {
1174 // Ask the WebFrame to fetch the alternate error page for us.
[email protected]726985e22009-06-18 21:09:281175 frame->LoadAlternateHTMLErrorPage(failed_request, error, error_page_url,
[email protected]5df266ac2008-10-15 19:50:131176 replace, GURL(kUnreachableWebDataURL));
1177 return;
1178 }
initial.commit09911bf2008-07-26 23:55:291179 }
[email protected]5df266ac2008-10-15 19:50:131180
[email protected]be645db2009-02-06 20:36:331181 // Fallback to a local error page.
[email protected]726985e22009-06-18 21:09:281182 LoadNavigationErrorPage(frame, failed_request, error, std::string(),
[email protected]5df266ac2008-10-15 19:50:131183 replace);
initial.commit09911bf2008-07-26 23:55:291184}
1185
1186void RenderView::LoadNavigationErrorPage(WebFrame* frame,
[email protected]726985e22009-06-18 21:09:281187 const WebURLRequest& failed_request,
1188 const WebURLError& error,
initial.commit09911bf2008-07-26 23:55:291189 const std::string& html,
1190 bool replace) {
[email protected]726985e22009-06-18 21:09:281191 GURL failed_url = error.unreachableURL;
initial.commit09911bf2008-07-26 23:55:291192
1193 std::string alt_html;
1194 if (html.empty()) {
1195 // Use a local error page.
1196 int resource_id;
1197 DictionaryValue error_strings;
[email protected]726985e22009-06-18 21:09:281198 if (error.reason == net::ERR_CACHE_MISS &&
1199 EqualsASCII(failed_request.httpMethod(), "POST")) {
initial.commit09911bf2008-07-26 23:55:291200 GetFormRepostErrorValues(failed_url, &error_strings);
1201 resource_id = IDR_ERROR_NO_DETAILS_HTML;
1202 } else {
1203 GetLocalizedErrorValues(error, &error_strings);
1204 resource_id = IDR_NET_ERROR_HTML;
1205 }
[email protected]8e50b602009-03-03 22:59:431206 error_strings.SetString(L"textdirection",
1207 (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) ?
1208 L"rtl" : L"ltr");
initial.commit09911bf2008-07-26 23:55:291209
1210 alt_html = GetAltHTMLForTemplate(error_strings, resource_id);
1211 } else {
1212 alt_html = html;
1213 }
1214
1215 // Use a data: URL as the site URL to prevent against XSS attacks.
[email protected]726985e22009-06-18 21:09:281216 WebURLRequest request(failed_request);
1217 request.setURL(GURL(kUnreachableWebDataURL));
initial.commit09911bf2008-07-26 23:55:291218
[email protected]726985e22009-06-18 21:09:281219 frame->LoadAlternateHTMLString(request, alt_html, failed_url, replace);
initial.commit09911bf2008-07-26 23:55:291220}
1221
1222void RenderView::DidCommitLoadForFrame(WebView *webview, WebFrame* frame,
1223 bool is_new_navigation) {
[email protected]daa8c58e2009-06-15 17:21:101224 NavigationState* navigation_state =
1225 NavigationState::FromDataSource(frame->GetDataSource());
initial.commit09911bf2008-07-26 23:55:291226
1227 if (is_new_navigation) {
1228 // When we perform a new navigation, we need to update the previous session
1229 // history entry with state for the page we are leaving.
1230 UpdateSessionHistory(frame);
1231
1232 // We bump our Page ID to correspond with the new session history entry.
1233 page_id_ = next_page_id_++;
1234
1235 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1236 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo,
1237 page_id_, true),
1238 kDelayForForcedCaptureMs);
1239 } else {
[email protected]77f17a82009-05-21 04:42:541240 // Inspect the navigation_state on the main frame (set in our Navigate
1241 // method) to see if the navigation corresponds to a session history
1242 // navigation... Note: |frame| may or may not be the toplevel frame, but
1243 // for the case of capturing session history, the first committed frame
1244 // suffices. We keep track of whether we've seen this commit before so
1245 // that only capture session history once per navigation.
[email protected]f4d34b52008-11-24 23:05:011246 //
1247 // Note that we need to check if the page ID changed. In the case of a
1248 // reload, the page ID doesn't change, and UpdateSessionHistory gets the
1249 // previous URL and the current page ID, which would be wrong.
[email protected]daa8c58e2009-06-15 17:21:101250 if (!navigation_state->is_new_navigation() &&
1251 !navigation_state->request_committed() &&
[email protected]77f17a82009-05-21 04:42:541252 page_id_ != navigation_state->pending_page_id()) {
initial.commit09911bf2008-07-26 23:55:291253 // This is a successful session history navigation!
1254 UpdateSessionHistory(frame);
[email protected]77f17a82009-05-21 04:42:541255 page_id_ = navigation_state->pending_page_id();
initial.commit09911bf2008-07-26 23:55:291256 }
1257 }
1258
1259 // Remember that we've already processed this request, so we don't update
1260 // the session history again. We do this regardless of whether this is
1261 // a session history navigation, because if we attempted a session history
1262 // navigation without valid HistoryItem state, WebCore will think it is a
1263 // new navigation.
[email protected]daa8c58e2009-06-15 17:21:101264 navigation_state->set_request_committed(true);
initial.commit09911bf2008-07-26 23:55:291265
1266 UpdateURL(frame);
1267
1268 // If this committed load was initiated by a client redirect, we're
1269 // at the last stop now, so clear it.
1270 completed_client_redirect_src_ = GURL();
1271
1272 // Check whether we have new encoding name.
1273 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
1274}
1275
1276void RenderView::DidReceiveTitle(WebView* webview,
1277 const std::wstring& title,
1278 WebFrame* frame) {
1279 UpdateTitle(frame, title);
1280
1281 // Also check whether we have new encoding name.
1282 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
1283}
1284
1285void RenderView::DidFinishLoadForFrame(WebView* webview, WebFrame* frame) {
[email protected]c20210e62009-04-03 21:39:261286 if (webview->GetMainFrame() == frame) {
1287 const GURL& url = frame->GetURL();
1288 if (url.SchemeIs("http") || url.SchemeIs("https"))
1289 DumpLoadHistograms();
1290 }
initial.commit09911bf2008-07-26 23:55:291291}
1292
1293void RenderView::DidFailLoadWithError(WebView* webview,
[email protected]726985e22009-06-18 21:09:281294 const WebURLError& error,
initial.commit09911bf2008-07-26 23:55:291295 WebFrame* frame) {
[email protected]546ddd172009-06-25 00:25:011296 // Currently this function is empty. When you implement something here and it
1297 // will display any error messages in HTML, please make sure to call
1298 // frame->SetInViewSourceMode(false) not to show them in view source mode.
initial.commit09911bf2008-07-26 23:55:291299}
1300
1301void RenderView::DidFinishDocumentLoadForFrame(WebView* webview,
1302 WebFrame* frame) {
[email protected]09b8f82f2009-06-16 20:22:111303 Send(new ViewHostMsg_DocumentLoadedInFrame(routing_id_));
1304
[email protected]daa8c58e2009-06-15 17:21:101305 // The document has now been fully loaded. Scan for password forms to be
1306 // sent up to the browser.
1307 SendPasswordForms(frame);
1308
initial.commit09911bf2008-07-26 23:55:291309 // Check whether we have new encoding name.
1310 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
[email protected]1e0f70402008-10-16 23:57:471311
[email protected]8930d472009-02-21 08:05:281312 if (RenderThread::current()) // Will be NULL during unit tests.
1313 RenderThread::current()->user_script_slave()->InjectScripts(
[email protected]0afe8272009-02-14 04:15:161314 frame, UserScript::DOCUMENT_END);
initial.commit09911bf2008-07-26 23:55:291315}
1316
1317void RenderView::DidHandleOnloadEventsForFrame(WebView* webview,
1318 WebFrame* frame) {
1319}
1320
1321void RenderView::DidChangeLocationWithinPageForFrame(WebView* webview,
1322 WebFrame* frame,
1323 bool is_new_navigation) {
[email protected]77f17a82009-05-21 04:42:541324 // If this was a reference fragment navigation that we initiated, then we
1325 // could end up having a non-null pending navigation state. We just need to
1326 // update the ExtraData on the datasource so that others who read the
1327 // ExtraData will get the new NavigationState. Similarly, if we did not
[email protected]daa8c58e2009-06-15 17:21:101328 // initiate this navigation, then we need to take care to reset any pre-
1329 // existing navigation state to a content-initiated navigation state.
1330 // DidCreateDataSource conveniently takes care of this for us.
1331 DidCreateDataSource(frame, frame->GetDataSource());
[email protected]77f17a82009-05-21 04:42:541332
initial.commit09911bf2008-07-26 23:55:291333 DidCommitLoadForFrame(webview, frame, is_new_navigation);
[email protected]77f17a82009-05-21 04:42:541334
[email protected]9d806f52009-03-12 22:50:541335 const string16& title =
[email protected]726985e22009-06-18 21:09:281336 webview->GetMainFrame()->GetDataSource()->pageTitle();
[email protected]9d806f52009-03-12 22:50:541337 UpdateTitle(frame, UTF16ToWideHack(title));
initial.commit09911bf2008-07-26 23:55:291338}
1339
initial.commit09911bf2008-07-26 23:55:291340void RenderView::DidCompleteClientRedirect(WebView* webview,
1341 WebFrame* frame,
1342 const GURL& source) {
1343 if (webview->GetMainFrame() == frame)
1344 completed_client_redirect_src_ = source;
1345}
1346
[email protected]daa8c58e2009-06-15 17:21:101347void RenderView::WillSubmitForm(WebView* webview, WebFrame* frame,
1348 const WebForm& form) {
1349 NavigationState* navigation_state =
1350 NavigationState::FromDataSource(frame->GetProvisionalDataSource());
1351
1352 if (navigation_state->transition_type() == PageTransition::LINK)
1353 navigation_state->set_transition_type(PageTransition::FORM_SUBMIT);
1354
1355 // Save these to be processed when the ensuing navigation is committed.
1356 navigation_state->set_searchable_form_data(
1357 SearchableFormData::Create(form));
1358 navigation_state->set_password_form_data(
1359 PasswordFormDomManager::CreatePasswordForm(form));
1360
1361 if (form.isAutoCompleteEnabled()) {
1362 scoped_ptr<AutofillForm> autofill_form(AutofillForm::Create(form));
1363 if (autofill_form.get())
1364 Send(new ViewHostMsg_AutofillFormSubmitted(routing_id_, *autofill_form));
1365 }
1366}
1367
[email protected]5b35a6b2009-03-16 19:58:081368void RenderView::WillSendRequest(WebView* webview,
1369 uint32 identifier,
[email protected]726985e22009-06-18 21:09:281370 WebURLRequest* request) {
1371 request->setRequestorID(routing_id_);
[email protected]5b35a6b2009-03-16 19:58:081372}
1373
initial.commit09911bf2008-07-26 23:55:291374void RenderView::BindDOMAutomationController(WebFrame* webframe) {
1375 dom_automation_controller_.set_message_sender(this);
1376 dom_automation_controller_.set_routing_id(routing_id_);
1377 dom_automation_controller_.BindToJavascript(webframe,
1378 L"domAutomationController");
1379}
1380
1381void RenderView::WindowObjectCleared(WebFrame* webframe) {
[email protected]81e63782009-02-27 19:35:091382 if (BindingsPolicy::is_dom_automation_enabled(enabled_bindings_))
initial.commit09911bf2008-07-26 23:55:291383 BindDOMAutomationController(webframe);
[email protected]81e63782009-02-27 19:35:091384 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_)) {
initial.commit09911bf2008-07-26 23:55:291385 dom_ui_bindings_.set_message_sender(this);
1386 dom_ui_bindings_.set_routing_id(routing_id_);
1387 dom_ui_bindings_.BindToJavascript(webframe, L"chrome");
1388 }
[email protected]81e63782009-02-27 19:35:091389 if (BindingsPolicy::is_external_host_enabled(enabled_bindings_)) {
[email protected]18cb2572008-08-21 20:34:451390 external_host_bindings_.set_message_sender(this);
1391 external_host_bindings_.set_routing_id(routing_id_);
1392 external_host_bindings_.BindToJavascript(webframe, L"externalHost");
1393 }
initial.commit09911bf2008-07-26 23:55:291394}
1395
[email protected]0afe8272009-02-14 04:15:161396void RenderView::DocumentElementAvailable(WebFrame* frame) {
[email protected]4b8323b2009-04-17 18:45:441397 // TODO(mpcomplete): remove this before Chrome extensions ship.
1398 // HACK. This is a temporary workaround to allow cross-origin XHR for Chrome
1399 // extensions. It grants full access to every origin, when we really want
1400 // to be able to restrict them more specifically.
[email protected]d959ce22009-04-15 21:03:421401 if (frame->GetURL().SchemeIs(chrome::kExtensionScheme))
[email protected]4b8323b2009-04-17 18:45:441402 frame->GrantUniversalAccess();
[email protected]d959ce22009-04-15 21:03:421403
[email protected]d02982242009-06-19 02:51:421404 // Tell extensions to self-register their js contexts.
1405 // TODO(rafaelw): This is kind of gross. We need a way to call through
1406 // the glue layer to retrieve the current v8::Context.
1407 if (frame->GetURL().SchemeIs(chrome::kExtensionScheme))
1408 ExtensionProcessBindings::RegisterExtensionContext(frame);
[email protected]85b99842009-05-16 02:01:251409
[email protected]8930d472009-02-21 08:05:281410 if (RenderThread::current()) // Will be NULL during unit tests.
1411 RenderThread::current()->user_script_slave()->InjectScripts(
[email protected]0afe8272009-02-14 04:15:161412 frame, UserScript::DOCUMENT_START);
1413}
1414
initial.commit09911bf2008-07-26 23:55:291415WindowOpenDisposition RenderView::DispositionForNavigationAction(
1416 WebView* webview,
1417 WebFrame* frame,
[email protected]726985e22009-06-18 21:09:281418 const WebURLRequest& request,
initial.commit09911bf2008-07-26 23:55:291419 WebNavigationType type,
1420 WindowOpenDisposition disposition,
1421 bool is_redirect) {
[email protected]daa8c58e2009-06-15 17:21:101422 // A content initiated navigation may have originated from a link-click,
1423 // script, drag-n-drop operation, etc.
[email protected]77f17a82009-05-21 04:42:541424 bool is_content_initiated =
[email protected]daa8c58e2009-06-15 17:21:101425 NavigationState::FromDataSource(frame->GetProvisionalDataSource())->
1426 is_content_initiated();
[email protected]77f17a82009-05-21 04:42:541427
initial.commit09911bf2008-07-26 23:55:291428 // Webkit is asking whether to navigate to a new URL.
1429 // This is fine normally, except if we're showing UI from one security
1430 // context and they're trying to navigate to a different context.
[email protected]726985e22009-06-18 21:09:281431 const GURL& url = request.url();
[email protected]77f17a82009-05-21 04:42:541432
initial.commit09911bf2008-07-26 23:55:291433 // We only care about navigations that are within the current tab (as opposed
1434 // to, for example, opening a new window).
1435 // But we sometimes navigate to about:blank to clear a tab, and we want to
1436 // still allow that.
[email protected]77f17a82009-05-21 04:42:541437 if (disposition == CURRENT_TAB && is_content_initiated &&
1438 frame->GetParent() == NULL && !url.SchemeIs(chrome::kAboutScheme)) {
1439 // When we received such unsolicited navigations, we sometimes want to
1440 // punt them up to the browser to handle.
1441 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_) ||
[email protected]1e5f53a2009-06-15 23:48:041442 BindingsPolicy::is_extension_enabled(enabled_bindings_) ||
[email protected]77f17a82009-05-21 04:42:541443 frame->GetInViewSourceMode() ||
1444 url.SchemeIs(chrome::kViewSourceScheme)) {
1445 OpenURL(webview, url, GURL(), disposition);
1446 return IGNORE_ACTION; // Suppress the load here.
initial.commit09911bf2008-07-26 23:55:291447 }
1448 }
1449
1450 // Detect when a page is "forking" a new tab that can be safely rendered in
1451 // its own process. This is done by sites like Gmail that try to open links
1452 // in new windows without script connections back to the original page. We
1453 // treat such cases as browser navigations (in which we will create a new
1454 // renderer for a cross-site navigation), rather than WebKit navigations.
1455 //
1456 // We use the following heuristic to decide whether to fork a new page in its
1457 // own process:
1458 // The parent page must open a new tab to about:blank, set the new tab's
1459 // window.opener to null, and then redirect the tab to a cross-site URL using
1460 // JavaScript.
1461 bool is_fork =
1462 // Must start from a tab showing about:blank, which is later redirected.
[email protected]6aad4bd2009-02-26 22:55:171463 frame->GetURL() == GURL("about:blank") &&
initial.commit09911bf2008-07-26 23:55:291464 // Must be the first real navigation of the tab.
1465 GetHistoryBackListCount() < 1 &&
1466 GetHistoryForwardListCount() < 1 &&
1467 // The parent page must have set the child's window.opener to null before
1468 // redirecting to the desired URL.
1469 frame->GetOpener() == NULL &&
1470 // Must be a top-level frame.
1471 frame->GetParent() == NULL &&
[email protected]77f17a82009-05-21 04:42:541472 // Must not have issued the request from this page.
1473 is_content_initiated &&
initial.commit09911bf2008-07-26 23:55:291474 // Must be targeted at the current tab.
1475 disposition == CURRENT_TAB &&
1476 // Must be a JavaScript navigation, which appears as "other".
[email protected]726985e22009-06-18 21:09:281477 type == WebKit::WebNavigationTypeOther;
initial.commit09911bf2008-07-26 23:55:291478 if (is_fork) {
1479 // Open the URL via the browser, not via WebKit.
[email protected]c0588052008-10-27 23:01:501480 OpenURL(webview, url, GURL(), disposition);
initial.commit09911bf2008-07-26 23:55:291481 return IGNORE_ACTION;
1482 }
1483
1484 return disposition;
1485}
1486
[email protected]a455d3812009-03-05 20:18:071487void RenderView::RunJavaScriptAlert(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291488 const std::wstring& message) {
[email protected]478ff2ed2009-04-21 23:49:181489 RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptAlert,
initial.commit09911bf2008-07-26 23:55:291490 message,
1491 std::wstring(),
[email protected]a455d3812009-03-05 20:18:071492 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291493 NULL);
1494}
1495
[email protected]a455d3812009-03-05 20:18:071496bool RenderView::RunJavaScriptConfirm(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291497 const std::wstring& message) {
[email protected]478ff2ed2009-04-21 23:49:181498 return RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptConfirm,
initial.commit09911bf2008-07-26 23:55:291499 message,
1500 std::wstring(),
[email protected]a455d3812009-03-05 20:18:071501 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291502 NULL);
1503}
1504
[email protected]a455d3812009-03-05 20:18:071505bool RenderView::RunJavaScriptPrompt(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291506 const std::wstring& message,
1507 const std::wstring& default_value,
1508 std::wstring* result) {
[email protected]478ff2ed2009-04-21 23:49:181509 return RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptPrompt,
initial.commit09911bf2008-07-26 23:55:291510 message,
1511 default_value,
[email protected]a455d3812009-03-05 20:18:071512 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291513 result);
1514}
1515
1516bool RenderView::RunJavaScriptMessage(int type,
1517 const std::wstring& message,
1518 const std::wstring& default_value,
[email protected]a455d3812009-03-05 20:18:071519 const GURL& frame_url,
initial.commit09911bf2008-07-26 23:55:291520 std::wstring* result) {
1521 bool success = false;
1522 std::wstring result_temp;
1523 if (!result)
1524 result = &result_temp;
1525 IPC::SyncMessage* msg = new ViewHostMsg_RunJavaScriptMessage(
[email protected]a455d3812009-03-05 20:18:071526 routing_id_, message, default_value, frame_url, type, &success, result);
initial.commit09911bf2008-07-26 23:55:291527
[email protected]1c4947f2009-01-15 22:25:111528 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291529 Send(msg);
1530
1531 return success;
1532}
1533
1534void RenderView::AddGURLSearchProvider(const GURL& osd_url, bool autodetected) {
1535 if (!osd_url.is_empty())
1536 Send(new ViewHostMsg_PageHasOSDD(routing_id_, page_id_, osd_url,
1537 autodetected));
1538}
1539
[email protected]a455d3812009-03-05 20:18:071540bool RenderView::RunBeforeUnloadConfirm(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291541 const std::wstring& message) {
1542 bool success = false;
1543 // This is an ignored return value, but is included so we can accept the same
1544 // response as RunJavaScriptMessage.
1545 std::wstring ignored_result;
1546 IPC::SyncMessage* msg = new ViewHostMsg_RunBeforeUnloadConfirm(
[email protected]a455d3812009-03-05 20:18:071547 routing_id_, webframe->GetURL(), message, &success, &ignored_result);
initial.commit09911bf2008-07-26 23:55:291548
[email protected]1c4947f2009-01-15 22:25:111549 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291550 Send(msg);
1551
1552 return success;
1553}
1554
[email protected]0ebf3872008-11-07 21:35:031555void RenderView::QueryFormFieldAutofill(const std::wstring& field_name,
1556 const std::wstring& text,
1557 int64 node_id) {
1558 static int message_id_counter = 0;
1559 form_field_autofill_request_id_ = message_id_counter++;
1560 Send(new ViewHostMsg_QueryFormFieldAutofill(routing_id_,
1561 field_name, text,
1562 node_id,
1563 form_field_autofill_request_id_));
1564}
1565
[email protected]4d2b6fb2009-03-20 22:28:171566void RenderView::RemoveStoredAutofillEntry(const std::wstring& name,
1567 const std::wstring& value) {
1568 Send(new ViewHostMsg_RemoveAutofillEntry(routing_id_, name, value));
1569}
1570
[email protected]0ebf3872008-11-07 21:35:031571void RenderView::OnReceivedAutofillSuggestions(
1572 int64 node_id,
1573 int request_id,
[email protected]8d0f15c2008-11-11 01:01:091574 const std::vector<std::wstring>& suggestions,
[email protected]0ebf3872008-11-07 21:35:031575 int default_suggestion_index) {
1576 if (!webview() || request_id != form_field_autofill_request_id_)
1577 return;
1578
1579 webview()->AutofillSuggestionsForNode(node_id, suggestions,
1580 default_suggestion_index);
1581}
1582
[email protected]2c4410d2009-05-06 23:46:221583void RenderView::OnPopupNotificationVisibilityChanged(bool visible) {
[email protected]634a6f92008-12-01 21:39:311584 popup_notification_visible_ = visible;
1585}
1586
initial.commit09911bf2008-07-26 23:55:291587void RenderView::ShowModalHTMLDialog(const GURL& url, int width, int height,
1588 const std::string& json_arguments,
1589 std::string* json_retval) {
1590 IPC::SyncMessage* msg = new ViewHostMsg_ShowModalHTMLDialog(
1591 routing_id_, url, width, height, json_arguments, json_retval);
1592
[email protected]1c4947f2009-01-15 22:25:111593 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291594 Send(msg);
1595}
1596
1597uint32 RenderView::GetCPBrowsingContext() {
1598 uint32 context = 0;
1599 Send(new ViewHostMsg_GetCPBrowsingContext(&context));
1600 return context;
1601}
1602
1603// Tell the browser to display a destination link.
1604void RenderView::UpdateTargetURL(WebView* webview, const GURL& url) {
1605 if (url != target_url_) {
1606 if (target_url_status_ == TARGET_INFLIGHT ||
1607 target_url_status_ == TARGET_PENDING) {
1608 // If we have a request in-flight, save the URL to be sent when we
1609 // receive an ACK to the in-flight request. We can happily overwrite
1610 // any existing pending sends.
1611 pending_target_url_ = url;
1612 target_url_status_ = TARGET_PENDING;
1613 } else {
1614 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_, url));
1615 target_url_ = url;
1616 target_url_status_ = TARGET_INFLIGHT;
1617 }
1618 }
1619}
1620
[email protected]b62d1a8c2009-01-13 23:54:571621void RenderView::RunFileChooser(bool multi_select,
[email protected]b949f1112009-04-12 20:03:081622 const string16& title,
1623 const FilePath& default_filename,
initial.commit09911bf2008-07-26 23:55:291624 WebFileChooserCallback* file_chooser) {
1625 if (file_chooser_.get()) {
1626 // TODO(brettw): bug 1235154: This should be a synchronous message to deal
1627 // with the fact that web pages can programatically trigger this. With the
1628 // asnychronous messages, we can get an additional call when one is pending,
1629 // which this test is for. For now, we just ignore the additional file
1630 // chooser request. WebKit doesn't do anything to expect the callback, so
1631 // we can just ignore calling it.
1632 delete file_chooser;
1633 return;
1634 }
1635 file_chooser_.reset(file_chooser);
[email protected]b62d1a8c2009-01-13 23:54:571636 Send(new ViewHostMsg_RunFileChooser(routing_id_, multi_select, title,
[email protected]b949f1112009-04-12 20:03:081637 default_filename));
initial.commit09911bf2008-07-26 23:55:291638}
1639
1640void RenderView::AddMessageToConsole(WebView* webview,
1641 const std::wstring& message,
1642 unsigned int line_no,
1643 const std::wstring& source_id) {
1644 Send(new ViewHostMsg_AddMessageToConsole(routing_id_, message,
1645 static_cast<int32>(line_no),
1646 source_id));
1647}
1648
1649void RenderView::AddSearchProvider(const std::string& url) {
1650 AddGURLSearchProvider(GURL(url),
1651 false); // not autodetected
1652}
1653
[email protected]c88a70fe2009-05-05 20:00:221654WebView* RenderView::CreateWebView(WebView* webview,
1655 bool user_gesture,
1656 const GURL& creator_url) {
[email protected]0aa55312008-10-17 21:53:081657 // Check to make sure we aren't overloading on popups.
1658 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups)
1659 return NULL;
1660
[email protected]634a6f92008-12-01 21:39:311661 // This window can't be closed from a window.close() call until we receive a
1662 // message from the Browser process explicitly allowing it.
1663 popup_notification_visible_ = true;
1664
initial.commit09911bf2008-07-26 23:55:291665 int32 routing_id = MSG_ROUTING_NONE;
[email protected]6c8afae52009-01-22 02:24:571666
[email protected]18bcc3c2009-01-27 21:39:151667 ModalDialogEvent modal_dialog_event;
[email protected]6c8afae52009-01-22 02:24:571668 render_thread_->Send(
[email protected]15787f8f2008-10-17 15:29:031669 new ViewHostMsg_CreateWindow(routing_id_, user_gesture, &routing_id,
1670 &modal_dialog_event));
initial.commit09911bf2008-07-26 23:55:291671 if (routing_id == MSG_ROUTING_NONE) {
initial.commit09911bf2008-07-26 23:55:291672 return NULL;
1673 }
1674
1675 // The WebView holds a reference to this new RenderView
[email protected]80d96fa2009-06-10 22:34:511676 const WebPreferences& web_prefs = webview->GetPreferences();
[email protected]6c8afae52009-01-22 02:24:571677 base::WaitableEvent* waitable_event = new base::WaitableEvent
1678#if defined(OS_WIN)
[email protected]18bcc3c2009-01-27 21:39:151679 (modal_dialog_event.event);
[email protected]6c8afae52009-01-22 02:24:571680#else
1681 (true, false);
1682#endif
[email protected]81a34412009-01-05 19:17:241683 RenderView* view = RenderView::Create(render_thread_,
[email protected]1c4947f2009-01-15 22:25:111684 NULL, waitable_event, routing_id_,
[email protected]80d96fa2009-06-10 22:34:511685 renderer_preferences_, web_prefs,
1686 shared_popup_counter_, routing_id);
[email protected]ed4bf2d2009-05-05 00:10:061687 view->opened_by_user_gesture_ = user_gesture;
[email protected]c88a70fe2009-05-05 20:00:221688 view->creator_url_ = creator_url;
initial.commit09911bf2008-07-26 23:55:291689
1690 // Copy over the alternate error page URL so we can have alt error pages in
1691 // the new render view (we don't need the browser to send the URL back down).
1692 view->alternate_error_page_url_ = alternate_error_page_url_;
1693
1694 return view->webview();
1695}
1696
[email protected]0ebf3872008-11-07 21:35:031697WebWidget* RenderView::CreatePopupWidget(WebView* webview,
[email protected]cfd727f2009-01-09 20:21:111698 bool activatable) {
[email protected]8085dbc82008-09-26 22:53:441699 RenderWidget* widget = RenderWidget::Create(routing_id_,
[email protected]81a34412009-01-05 19:17:241700 render_thread_,
[email protected]cfd727f2009-01-09 20:21:111701 activatable);
initial.commit09911bf2008-07-26 23:55:291702 return widget->webwidget();
1703}
1704
1705WebPluginDelegate* RenderView::CreatePluginDelegate(
1706 WebView* webview,
1707 const GURL& url,
1708 const std::string& mime_type,
1709 const std::string& clsid,
1710 std::string* actual_mime_type) {
[email protected]ffeba6d2009-04-27 20:43:261711#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]6273e2e72009-04-17 00:13:551712 if (!PluginChannelHost::IsListening())
1713 return NULL;
1714
[email protected]9dd9e8382009-06-05 18:23:211715 GURL policy_url;
1716 if (webview->GetMainFrame())
1717 policy_url = webview->GetMainFrame()->GetURL();
1718
[email protected]f5cdaff2009-05-19 21:01:471719 FilePath path;
1720 render_thread_->Send(
[email protected]9dd9e8382009-06-05 18:23:211721 new ViewHostMsg_GetPluginPath(url, policy_url, mime_type, clsid, &path,
[email protected]f5cdaff2009-05-19 21:01:471722 actual_mime_type));
1723 if (path.value().empty())
1724 return NULL;
1725
1726 std::string mime_type_to_use;
1727 if (!actual_mime_type->empty())
1728 mime_type_to_use = *actual_mime_type;
1729 else
1730 mime_type_to_use = mime_type;
1731
[email protected]ffeba6d2009-04-27 20:43:261732#if !defined(OS_LINUX) // In-proc plugins aren't supported on Linux.
[email protected]88a1fb47a2009-03-13 00:18:061733 if (RenderProcess::current()->in_process_plugins()) {
[email protected]b94d3322009-02-12 19:49:041734 return WebPluginDelegate::Create(path,
1735 mime_type_to_use,
1736 gfx::NativeViewFromId(host_window_));
initial.commit09911bf2008-07-26 23:55:291737 }
[email protected]ffeba6d2009-04-27 20:43:261738#endif
initial.commit09911bf2008-07-26 23:55:291739
1740 WebPluginDelegateProxy* proxy =
[email protected]f5cdaff2009-05-19 21:01:471741 WebPluginDelegateProxy::Create(url, mime_type_to_use, clsid, this);
initial.commit09911bf2008-07-26 23:55:291742 if (!proxy)
1743 return NULL;
1744
1745 // We hold onto the proxy so we can poke it when we are painting. See our
1746 // DidPaint implementation below.
1747 plugin_delegates_.push_back(proxy);
1748
1749 return proxy;
[email protected]6c8afae52009-01-22 02:24:571750#else
[email protected]157e5d22009-04-23 18:43:351751 // TODO(port): Plugins currently not supported
1752 NOTIMPLEMENTED();
1753 return NULL;
[email protected]6c8afae52009-01-22 02:24:571754#endif
initial.commit09911bf2008-07-26 23:55:291755}
1756
[email protected]4e6be3f2009-05-07 02:24:441757WebKit::WebMediaPlayer* RenderView::CreateWebMediaPlayer(
1758 WebKit::WebMediaPlayerClient* client) {
[email protected]add51772009-06-11 18:25:171759 scoped_refptr<media::FilterFactoryCollection> factory =
1760 new media::FilterFactoryCollection();
1761 // Add in any custom filter factories first.
1762 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
1763 if (!cmd_line->HasSwitch(switches::kDisableAudio)) {
1764 // Add the chrome specific audio renderer.
1765 factory->AddFactory(
1766 AudioRendererImpl::CreateFactory(audio_message_filter()));
1767 }
[email protected]8380c092009-06-25 17:45:511768
1769 // TODO(hclam): obtain the following parameters from |client|.
1770 webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory =
1771 new webkit_glue::MediaResourceLoaderBridgeFactory(
1772 GURL::EmptyGURL(), // referrer
1773 "null", // frame origin
1774 "null", // main_frame_origin
1775 base::GetCurrentProcId(),
1776 WebAppCacheContext::kNoAppCacheContextId,
1777 routing_id());
1778
[email protected]add51772009-06-11 18:25:171779 if (!cmd_line->HasSwitch(switches::kSimpleDataSource)) {
1780 // Add the chrome specific media data source.
[email protected]70ab61c92009-06-16 19:29:391781 factory->AddFactory(
1782 BufferedDataSource::CreateFactory(MessageLoop::current(),
[email protected]8380c092009-06-25 17:45:511783 bridge_factory));
1784 } else {
1785 factory->AddFactory(
1786 webkit_glue::SimpleDataSource::CreateFactory(MessageLoop::current(),
1787 bridge_factory));
[email protected]add51772009-06-11 18:25:171788 }
1789 return new webkit_glue::WebMediaPlayerImpl(client, factory);
[email protected]ec9212f2008-12-18 21:40:361790}
1791
initial.commit09911bf2008-07-26 23:55:291792void RenderView::OnMissingPluginStatus(WebPluginDelegate* delegate,
1793 int status) {
[email protected]6c8afae52009-01-22 02:24:571794#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291795 if (first_default_plugin_ == NULL) {
1796 // Show the InfoBar for the first available plugin.
1797 if (status == default_plugin::MISSING_PLUGIN_AVAILABLE) {
1798 first_default_plugin_ = delegate;
1799 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1800 }
1801 } else {
1802 // Closes the InfoBar if user clicks on the plugin (instead of the InfoBar)
1803 // to start the download/install.
1804 if (status == default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD) {
1805 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1806 }
1807 }
[email protected]6c8afae52009-01-22 02:24:571808#else
1809 // TODO(port): plugins current not supported
1810 NOTIMPLEMENTED();
1811#endif
initial.commit09911bf2008-07-26 23:55:291812}
1813
[email protected]eb47a132009-03-04 00:39:561814WebWorker* RenderView::CreateWebWorker(WebWorkerClient* client) {
1815#if defined(OS_WIN)
[email protected]ec775ef2009-05-01 21:20:471816 return new WebWorkerProxy(client, RenderThread::current(), routing_id_);
[email protected]eb47a132009-03-04 00:39:561817#else
1818 // TODO(port): out of process workers
1819 NOTIMPLEMENTED();
1820 return NULL;
1821#endif
1822}
1823
initial.commit09911bf2008-07-26 23:55:291824void RenderView::OpenURL(WebView* webview, const GURL& url,
[email protected]c0588052008-10-27 23:01:501825 const GURL& referrer,
initial.commit09911bf2008-07-26 23:55:291826 WindowOpenDisposition disposition) {
[email protected]c0588052008-10-27 23:01:501827 Send(new ViewHostMsg_OpenURL(routing_id_, url, referrer, disposition));
initial.commit09911bf2008-07-26 23:55:291828}
1829
[email protected]1d522202009-04-04 01:56:421830void RenderView::DidContentsSizeChange(WebWidget* webwidget,
1831 int new_width,
1832 int new_height) {
[email protected]0666aef2009-05-13 19:48:081833 // We don't always want to send the change messages over IPC, only if we've
1834 // be put in that mode by getting a |ViewMsg_EnableIntrinsicWidthChangedMode|
1835 // message.
1836 // TODO(rafaelw): Figure out where the best place to set this for extensions
1837 // is. It isn't clean to test for ExtensionView by examining the
1838 // enabled_bindings. This needs to be generalized as it becomes clear what
1839 // extension toolbars need.
1840 if (BindingsPolicy::is_extension_enabled(enabled_bindings_) ||
1841 send_preferred_width_changes_) {
1842 // WebCore likes to tell us things have changed even when they haven't, so
1843 // cache the width and only send the IPC message when we're sure the
1844 // width is different.
[email protected]1d522202009-04-04 01:56:421845 int width = webview()->GetMainFrame()->GetContentsPreferredWidth();
[email protected]0666aef2009-05-13 19:48:081846 if (width != preferred_width_) {
1847 Send(new ViewHostMsg_DidContentsPreferredWidthChange(routing_id_, width));
1848 preferred_width_ = width;
1849 }
[email protected]1d522202009-04-04 01:56:421850 }
1851}
1852
initial.commit09911bf2008-07-26 23:55:291853// We are supposed to get a single call to Show for a newly created RenderView
1854// that was created via RenderView::CreateWebView. So, we wait until this
1855// point to dispatch the ShowView message.
1856//
1857// This method provides us with the information about how to display the newly
1858// created RenderView (i.e., as a constrained popup or as a new tab).
1859//
1860void RenderView::Show(WebWidget* webwidget, WindowOpenDisposition disposition) {
1861 DCHECK(!did_show_) << "received extraneous Show call";
1862 DCHECK(opener_id_ != MSG_ROUTING_NONE);
1863
1864 if (did_show_)
1865 return;
1866 did_show_ = true;
1867
1868 // NOTE: initial_pos_ may still have its default values at this point, but
1869 // that's okay. It'll be ignored if disposition is not NEW_POPUP, or the
1870 // browser process will impose a default position otherwise.
[email protected]35f7d212009-04-29 21:19:271871 Send(new ViewHostMsg_ShowView(opener_id_, routing_id_, disposition,
[email protected]c88a70fe2009-05-05 20:00:221872 initial_pos_, opened_by_user_gesture_, creator_url_));
[email protected]2533ce12009-05-09 00:02:241873 SetPendingWindowRect(initial_pos_);
initial.commit09911bf2008-07-26 23:55:291874}
1875
[email protected]634a6f92008-12-01 21:39:311876void RenderView::CloseWidgetSoon(WebWidget* webwidget) {
[email protected]2c4410d2009-05-06 23:46:221877 if (!popup_notification_visible_)
[email protected]634a6f92008-12-01 21:39:311878 RenderWidget::CloseWidgetSoon(webwidget);
1879}
1880
initial.commit09911bf2008-07-26 23:55:291881void RenderView::RunModal(WebWidget* webwidget) {
1882 DCHECK(did_show_) << "should already have shown the view";
1883
1884 IPC::SyncMessage* msg = new ViewHostMsg_RunModal(routing_id_);
1885
[email protected]1c4947f2009-01-15 22:25:111886 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291887 Send(msg);
1888}
1889
1890void RenderView::SyncNavigationState() {
1891 if (!webview())
1892 return;
1893
initial.commit09911bf2008-07-26 23:55:291894 std::string state;
[email protected]606843fa2008-12-02 19:08:561895 if (!webview()->GetMainFrame()->GetCurrentHistoryState(&state))
initial.commit09911bf2008-07-26 23:55:291896 return;
[email protected]606843fa2008-12-02 19:08:561897 Send(new ViewHostMsg_UpdateState(routing_id_, page_id_, state));
initial.commit09911bf2008-07-26 23:55:291898}
1899
1900void RenderView::ShowContextMenu(WebView* webview,
[email protected]124646932009-01-28 18:39:021901 ContextNode node,
initial.commit09911bf2008-07-26 23:55:291902 int x,
1903 int y,
1904 const GURL& link_url,
1905 const GURL& image_url,
1906 const GURL& page_url,
1907 const GURL& frame_url,
1908 const std::wstring& selection_text,
1909 const std::wstring& misspelled_word,
[email protected]6aa376b2008-09-23 18:49:521910 int edit_flags,
[email protected]c9825a42009-05-01 22:51:501911 const std::string& security_info,
1912 const std::string& frame_charset) {
[email protected]e09ba552009-02-05 03:26:291913 ContextMenuParams params;
[email protected]124646932009-01-28 18:39:021914 params.node = node;
initial.commit09911bf2008-07-26 23:55:291915 params.x = x;
1916 params.y = y;
1917 params.image_url = image_url;
1918 params.link_url = link_url;
[email protected]e6c79812009-04-22 22:31:421919 params.unfiltered_link_url = link_url;
initial.commit09911bf2008-07-26 23:55:291920 params.page_url = page_url;
1921 params.frame_url = frame_url;
1922 params.selection_text = selection_text;
1923 params.misspelled_word = misspelled_word;
[email protected]be645db2009-02-06 20:36:331924 params.spellcheck_enabled =
[email protected]bbbd545c2008-12-15 20:18:041925 webview->GetFocusedFrame()->SpellCheckEnabled();
initial.commit09911bf2008-07-26 23:55:291926 params.edit_flags = edit_flags;
[email protected]6aa376b2008-09-23 18:49:521927 params.security_info = security_info;
[email protected]c9825a42009-05-01 22:51:501928 params.frame_charset = frame_charset;
initial.commit09911bf2008-07-26 23:55:291929 Send(new ViewHostMsg_ContextMenu(routing_id_, params));
1930}
1931
[email protected]e80c73b2009-04-07 23:24:581932void RenderView::StartDragging(WebView* webview,
1933 const WebDragData& drag_data) {
1934 Send(new ViewHostMsg_StartDragging(routing_id_, WebDropData(drag_data)));
initial.commit09911bf2008-07-26 23:55:291935}
1936
1937void RenderView::TakeFocus(WebView* webview, bool reverse) {
1938 Send(new ViewHostMsg_TakeFocus(routing_id_, reverse));
1939}
1940
1941void RenderView::DidDownloadImage(int id,
1942 const GURL& image_url,
1943 bool errored,
1944 const SkBitmap& image) {
1945 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, errored,
1946 image));
1947}
1948
1949
1950void RenderView::OnDownloadImage(int id,
1951 const GURL& image_url,
1952 int image_size) {
[email protected]f11ca0732009-04-11 00:09:341953 bool data_image_failed = false;
1954 if (image_url.SchemeIs("data")) {
1955 SkBitmap data_image = ImageFromDataUrl(image_url);
1956 data_image_failed = data_image.empty();
1957 if (!data_image_failed) {
1958 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, false,
1959 data_image));
1960 }
1961 }
1962
1963 if (data_image_failed || !webview()->DownloadImage(id, image_url, image_size))
initial.commit09911bf2008-07-26 23:55:291964 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, true,
1965 SkBitmap()));
1966}
1967
[email protected]f11ca0732009-04-11 00:09:341968SkBitmap RenderView::ImageFromDataUrl(const GURL& url) const {
1969 std::string mime_type, char_set, data;
1970 if (net::DataURL::Parse(url, &mime_type, &char_set, &data) && !data.empty()) {
1971 // Decode the favicon using WebKit's image decoder.
1972 webkit_glue::ImageDecoder decoder(gfx::Size(kFavIconSize, kFavIconSize));
1973 const unsigned char* src_data =
1974 reinterpret_cast<const unsigned char*>(&data[0]);
1975
1976 return decoder.Decode(src_data, data.size());
1977 }
1978 return SkBitmap();
1979}
1980
initial.commit09911bf2008-07-26 23:55:291981void RenderView::OnGetApplicationInfo(int page_id) {
1982 webkit_glue::WebApplicationInfo app_info;
1983 if (page_id == page_id_)
1984 webkit_glue::GetApplicationInfo(webview(), &app_info);
1985
1986 // Prune out any data URLs in the set of icons. The browser process expects
1987 // any icon with a data URL to have originated from a favicon. We don't want
1988 // to decode arbitrary data URLs in the browser process. See
1989 // http://b/issue?id=1162972
1990 for (size_t i = 0; i < app_info.icons.size(); ++i) {
[email protected]6de74452009-02-25 18:04:591991 if (app_info.icons[i].url.SchemeIs(chrome::kDataScheme)) {
initial.commit09911bf2008-07-26 23:55:291992 app_info.icons.erase(app_info.icons.begin() + i);
1993 --i;
1994 }
1995 }
1996
1997 Send(new ViewHostMsg_DidGetApplicationInfo(routing_id_, page_id, app_info));
1998}
1999
2000GURL RenderView::GetAlternateErrorPageURL(const GURL& failedURL,
2001 ErrorPageType error_type) {
2002 if (failedURL.SchemeIsSecure()) {
2003 // If the URL that failed was secure, then the embedding web page was not
2004 // expecting a network attacker to be able to manipulate its contents. As
2005 // we fetch alternate error pages over HTTP, we would be allowing a network
2006 // attacker to manipulate the contents of the response if we tried to use
2007 // the link doctor here.
2008 return GURL::EmptyGURL();
2009 }
2010
2011 // Grab the base URL from the browser process.
2012 if (!alternate_error_page_url_.is_valid())
2013 return GURL::EmptyGURL();
2014
2015 // Strip query params from the failed URL.
2016 GURL::Replacements remove_params;
2017 remove_params.ClearUsername();
2018 remove_params.ClearPassword();
2019 remove_params.ClearQuery();
2020 remove_params.ClearRef();
2021 const GURL url_to_send = failedURL.ReplaceComponents(remove_params);
2022
2023 // Construct the query params to send to link doctor.
2024 std::string params(alternate_error_page_url_.query());
2025 params.append("&url=");
2026 params.append(EscapeQueryParamValue(url_to_send.spec()));
2027 params.append("&sourceid=chrome");
2028 params.append("&error=");
2029 switch (error_type) {
2030 case DNS_ERROR:
2031 params.append("dnserror");
2032 break;
2033
2034 case HTTP_404:
2035 params.append("http404");
2036 break;
2037
[email protected]5df266ac2008-10-15 19:50:132038 case CONNECTION_ERROR:
[email protected]e1f934b2009-01-26 20:41:332039 params.append("connectionfailure");
[email protected]5df266ac2008-10-15 19:50:132040 break;
2041
initial.commit09911bf2008-07-26 23:55:292042 default:
2043 NOTREACHED() << "unknown ErrorPageType";
2044 }
2045
2046 // OK, build the final url to return.
2047 GURL::Replacements link_doctor_params;
2048 link_doctor_params.SetQueryStr(params);
2049 GURL url = alternate_error_page_url_.ReplaceComponents(link_doctor_params);
2050 return url;
2051}
2052
[email protected]7ea066a2009-04-06 20:21:592053void RenderView::OnFind(int request_id,
2054 const string16& search_text,
2055 const WebKit::WebFindOptions& options) {
initial.commit09911bf2008-07-26 23:55:292056 WebFrame* main_frame = webview()->GetMainFrame();
2057 WebFrame* frame_after_main = webview()->GetNextFrameAfter(main_frame, true);
2058 WebFrame* focused_frame = webview()->GetFocusedFrame();
2059 WebFrame* search_frame = focused_frame; // start searching focused frame.
2060
2061 bool multi_frame = (frame_after_main != main_frame);
2062
2063 // If we have multiple frames, we don't want to wrap the search within the
2064 // frame, so we check here if we only have main_frame in the chain.
2065 bool wrap_within_frame = !multi_frame;
2066
[email protected]b3f2b912009-04-09 16:18:522067 WebRect selection_rect;
initial.commit09911bf2008-07-26 23:55:292068 bool result = false;
2069
2070 do {
[email protected]7ea066a2009-04-06 20:21:592071 result = search_frame->Find(
2072 request_id, search_text, options, wrap_within_frame, &selection_rect);
initial.commit09911bf2008-07-26 23:55:292073
2074 if (!result) {
2075 // don't leave text selected as you move to the next frame.
2076 search_frame->ClearSelection();
2077
2078 // Find the next frame, but skip the invisible ones.
2079 do {
2080 // What is the next frame to search? (we might be going backwards). Note
2081 // that we specify wrap=true so that search_frame never becomes NULL.
[email protected]7ea066a2009-04-06 20:21:592082 search_frame = options.forward ?
initial.commit09911bf2008-07-26 23:55:292083 webview()->GetNextFrameAfter(search_frame, true) :
2084 webview()->GetPreviousFrameBefore(search_frame, true);
2085 } while (!search_frame->Visible() && search_frame != focused_frame);
2086
[email protected]884db412008-11-24 23:46:502087 // Make sure selection doesn't affect the search operation in new frame.
initial.commit09911bf2008-07-26 23:55:292088 search_frame->ClearSelection();
2089
2090 // If we have multiple frames and we have wrapped back around to the
2091 // focused frame, we need to search it once more allowing wrap within
2092 // the frame, otherwise it will report 'no match' if the focused frame has
2093 // reported matches, but no frames after the focused_frame contain a
2094 // match for the search word(s).
2095 if (multi_frame && search_frame == focused_frame) {
[email protected]7ea066a2009-04-06 20:21:592096 result = search_frame->Find(
2097 request_id, search_text, options, true, // Force wrapping.
2098 &selection_rect);
initial.commit09911bf2008-07-26 23:55:292099 }
2100 }
2101
2102 // TODO(jcampan): http://b/issue?id=1157486 Remove StoreForFocus call once
2103 // we have the fix for 792423.
2104 search_frame->GetView()->StoreFocusForFrame(search_frame);
2105 webview()->SetFocusedFrame(search_frame);
2106 } while (!result && search_frame != focused_frame);
2107
2108 // Make sure we don't leave any frame focused or the focus won't be restored
2109 // properly in WebViewImpl::SetFocus(). Note that we are talking here about
2110 // focused on the SelectionController, not FocusController.
2111 // webview()->GetFocusedFrame() will still return the last focused frame (as
2112 // it queries the FocusController).
2113 // TODO(jcampan): http://b/issue?id=1157486 Remove next line once we have the
2114 // fix for 792423.
2115 webview()->SetFocusedFrame(NULL);
2116
[email protected]7ea066a2009-04-06 20:21:592117 if (options.findNext) {
[email protected]4f3dc372009-02-24 00:10:292118 // Force the main_frame to report the actual count.
[email protected]7ea066a2009-04-06 20:21:592119 main_frame->IncreaseMatchCount(0, request_id);
[email protected]4f3dc372009-02-24 00:10:292120 } else {
2121 // If nothing is found, set result to "0 of 0", otherwise, set it to
2122 // "-1 of 1" to indicate that we found at least one item, but we don't know
2123 // yet what is active.
2124 int ordinal = result ? -1 : 0; // -1 here means, we might know more later.
2125 int match_count = result ? 1 : 0; // 1 here means possibly more coming.
initial.commit09911bf2008-07-26 23:55:292126
[email protected]4f3dc372009-02-24 00:10:292127 // If we find no matches then this will be our last status update.
2128 // Otherwise the scoping effort will send more results.
2129 bool final_status_update = !result;
initial.commit09911bf2008-07-26 23:55:292130
[email protected]4f3dc372009-02-24 00:10:292131 // Send the search result over to the browser process.
[email protected]4f999132009-03-31 18:08:402132 Send(new ViewHostMsg_Find_Reply(routing_id_,
[email protected]7ea066a2009-04-06 20:21:592133 request_id,
[email protected]4f3dc372009-02-24 00:10:292134 match_count,
2135 selection_rect,
2136 ordinal,
2137 final_status_update));
initial.commit09911bf2008-07-26 23:55:292138
initial.commit09911bf2008-07-26 23:55:292139 // Scoping effort begins, starting with the mainframe.
2140 search_frame = main_frame;
2141
2142 main_frame->ResetMatchCount();
2143
2144 do {
2145 // Cancel all old scoping requests before starting a new one.
2146 search_frame->CancelPendingScopingEffort();
2147
2148 // We don't start another scoping effort unless at least one match has
2149 // been found.
2150 if (result) {
2151 // Start new scoping request. If the scoping function determines that it
2152 // needs to scope, it will defer until later.
[email protected]7ea066a2009-04-06 20:21:592153 search_frame->ScopeStringMatches(request_id,
2154 search_text,
2155 options,
initial.commit09911bf2008-07-26 23:55:292156 true); // reset the tickmarks
2157 }
2158
2159 // Iterate to the next frame. The frame will not necessarily scope, for
2160 // example if it is not visible.
2161 search_frame = webview()->GetNextFrameAfter(search_frame, true);
2162 } while (search_frame != main_frame);
2163 }
2164}
2165
2166void RenderView::ReportFindInPageMatchCount(int count, int request_id,
2167 bool final_update) {
2168 // If we have a message that has been queued up, then we should just replace
2169 // it. The ACK from the browser will make sure it gets sent when the browser
2170 // wants it.
2171 if (queued_find_reply_message_.get()) {
2172 IPC::Message* msg = new ViewHostMsg_Find_Reply(
2173 routing_id_,
2174 request_id,
2175 count,
[email protected]b3f2b912009-04-09 16:18:522176 gfx::Rect(),
initial.commit09911bf2008-07-26 23:55:292177 -1, // Don't update active match ordinal.
2178 final_update);
2179 queued_find_reply_message_.reset(msg);
2180 } else {
2181 // Send the search result over to the browser process.
2182 Send(new ViewHostMsg_Find_Reply(
2183 routing_id_,
2184 request_id,
2185 count,
[email protected]b3f2b912009-04-09 16:18:522186 gfx::Rect(),
initial.commit09911bf2008-07-26 23:55:292187 -1, // // Don't update active match ordinal.
2188 final_update));
2189 }
2190}
2191
2192void RenderView::ReportFindInPageSelection(int request_id,
2193 int active_match_ordinal,
[email protected]b3f2b912009-04-09 16:18:522194 const WebRect& selection_rect) {
initial.commit09911bf2008-07-26 23:55:292195 // Send the search result over to the browser process.
2196 Send(new ViewHostMsg_Find_Reply(routing_id_,
2197 request_id,
2198 -1,
2199 selection_rect,
2200 active_match_ordinal,
2201 false));
2202}
2203
[email protected]ed4bf2d2009-05-05 00:10:062204bool RenderView::WasOpenedByUserGesture() const {
initial.commit09911bf2008-07-26 23:55:292205 return opened_by_user_gesture_;
2206}
2207
[email protected]7f40fc5b2009-06-12 19:23:082208void RenderView::SpellCheck(const std::wstring& word, int* misspell_location,
2209 int* misspell_length) {
2210 Send(new ViewHostMsg_SpellCheck(routing_id_, word, misspell_location,
2211 misspell_length));
initial.commit09911bf2008-07-26 23:55:292212}
2213
[email protected]26ea6c42009-06-10 22:32:212214std::wstring RenderView::GetAutoCorrectWord(
2215 const std::wstring& misspelled_word) {
2216 std::wstring autocorrect_word;
[email protected]eda2b5a2009-05-12 19:30:212217 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2218 if (command_line.HasSwitch(switches::kAutoSpellCorrect)) {
2219 Send(new ViewHostMsg_GetAutoCorrectWord(routing_id_, misspelled_word,
2220 &autocorrect_word));
2221 }
[email protected]26ea6c42009-06-10 22:32:212222
2223 return autocorrect_word;
[email protected]eda2b5a2009-05-12 19:30:212224}
2225
initial.commit09911bf2008-07-26 23:55:292226void RenderView::SetInputMethodState(bool enabled) {
2227 // Save the updated IME status and mark the input focus has been updated.
2228 // The IME status is to be sent to a browser process next time when
2229 // the input caret is rendered.
[email protected]9f23f592008-11-17 08:36:342230 if (!ime_control_busy_) {
2231 ime_control_updated_ = true;
2232 ime_control_new_state_ = enabled;
2233 }
initial.commit09911bf2008-07-26 23:55:292234}
2235
2236void RenderView::ScriptedPrint(WebFrame* frame) {
[email protected]82270452009-06-19 15:58:012237 if (print_helper_.get() == NULL) {
2238 print_helper_.reset(new PrintWebViewHelper(this));
2239 }
2240 print_helper_->SyncPrint(frame);
initial.commit09911bf2008-07-26 23:55:292241}
2242
initial.commit09911bf2008-07-26 23:55:292243void RenderView::UserMetricsRecordAction(const std::wstring& action) {
2244 Send(new ViewHostMsg_UserMetricsRecordAction(routing_id_, action));
2245}
2246
2247void RenderView::DnsPrefetch(const std::vector<std::string>& host_names) {
2248 Send(new ViewHostMsg_DnsPrefetch(host_names));
2249}
2250
[email protected]630e26b2008-10-14 22:55:172251void RenderView::OnZoom(int function) {
2252 static const bool kZoomIsTextOnly = false;
2253 switch (function) {
2254 case PageZoom::SMALLER:
2255 webview()->ZoomOut(kZoomIsTextOnly);
initial.commit09911bf2008-07-26 23:55:292256 break;
[email protected]630e26b2008-10-14 22:55:172257 case PageZoom::STANDARD:
2258 webview()->ResetZoom();
initial.commit09911bf2008-07-26 23:55:292259 break;
[email protected]630e26b2008-10-14 22:55:172260 case PageZoom::LARGER:
2261 webview()->ZoomIn(kZoomIsTextOnly);
initial.commit09911bf2008-07-26 23:55:292262 break;
2263 default:
2264 NOTREACHED();
2265 }
2266}
2267
[email protected]ea8c7452009-04-02 20:47:062268void RenderView::OnInsertText(const string16& text) {
[email protected]5f9e0b82009-05-08 22:13:392269 WebFrame* frame = webview()->GetFocusedFrame();
2270 if (!frame)
2271 return;
2272 WebTextInput* text_input = frame->GetTextInput();
[email protected]00d7e622009-04-21 23:06:052273 if (text_input)
[email protected]7be0e172009-05-14 01:05:272274 text_input->InsertText(text);
[email protected]ea8c7452009-04-02 20:47:062275}
2276
[email protected]e38f40152008-09-12 23:08:302277void RenderView::OnSetPageEncoding(const std::wstring& encoding_name) {
initial.commit09911bf2008-07-26 23:55:292278 webview()->SetPageEncoding(encoding_name);
2279}
2280
[email protected]f6e59a62009-05-13 21:12:032281void RenderView::NavigateBackForwardSoon(int offset) {
[email protected]f46aff62008-10-16 07:58:052282 history_back_list_count_ += offset;
2283 history_forward_list_count_ -= offset;
2284
initial.commit09911bf2008-07-26 23:55:292285 Send(new ViewHostMsg_GoToEntryAtOffset(routing_id_, offset));
2286}
2287
2288int RenderView::GetHistoryBackListCount() {
2289 return history_back_list_count_;
2290}
2291
2292int RenderView::GetHistoryForwardListCount() {
2293 return history_forward_list_count_;
2294}
2295
2296void RenderView::OnNavStateChanged(WebView* webview) {
[email protected]81a34412009-01-05 19:17:242297 if (!nav_state_sync_timer_.IsRunning()) {
2298 nav_state_sync_timer_.Start(
2299 TimeDelta::FromSeconds(delay_seconds_for_form_state_sync_), this,
2300 &RenderView::SyncNavigationState);
2301 }
initial.commit09911bf2008-07-26 23:55:292302}
2303
2304void RenderView::SetTooltipText(WebView* webview,
2305 const std::wstring& tooltip_text) {
2306 Send(new ViewHostMsg_SetTooltipText(routing_id_, tooltip_text));
2307}
2308
[email protected]2e417c82009-04-02 22:30:262309void RenderView::DidChangeSelection(bool is_empty_selection) {
2310#if defined(OS_LINUX)
[email protected]d5d7b8002009-05-18 21:20:542311 // TODO(estade): investigate incremental updates to the selection so that we
2312 // don't send the entire selection over IPC every time.
[email protected]2e417c82009-04-02 22:30:262313 if (!is_empty_selection) {
[email protected]d5d7b8002009-05-18 21:20:542314 // Sometimes we get repeated DidChangeSelection calls from webkit when
2315 // the selection hasn't actually changed. We don't want to report these
2316 // because it will cause us to continually claim the X clipboard.
2317 const std::string& this_selection =
2318 webview()->GetFocusedFrame()->GetSelection(false);
2319 if (this_selection == last_selection_)
2320 return;
2321
[email protected]dbadbcc2009-04-09 00:57:102322 Send(new ViewHostMsg_SelectionChanged(routing_id_,
[email protected]d5d7b8002009-05-18 21:20:542323 this_selection));
2324 last_selection_ = this_selection;
[email protected]2e417c82009-04-02 22:30:262325 }
2326#endif
2327}
2328
initial.commit09911bf2008-07-26 23:55:292329void RenderView::DownloadUrl(const GURL& url, const GURL& referrer) {
2330 Send(new ViewHostMsg_DownloadUrl(routing_id_, url, referrer));
2331}
2332
[email protected]0df30122009-06-03 12:13:082333void RenderView::UpdateInspectorSettings(const std::wstring& raw_settings) {
2334 Send(new ViewHostMsg_UpdateInspectorSettings(routing_id_, raw_settings));
2335}
2336
[email protected]611cad42009-03-16 18:51:342337WebDevToolsAgentDelegate* RenderView::GetWebDevToolsAgentDelegate() {
[email protected]b75b7d072009-04-06 13:47:002338 return devtools_agent_.get();
[email protected]611cad42009-03-16 18:51:342339}
2340
[email protected]ea8c7452009-04-02 20:47:062341void RenderView::PasteFromSelectionClipboard() {
2342 Send(new ViewHostMsg_PasteFromSelectionClipboard(routing_id_));
2343}
2344
initial.commit09911bf2008-07-26 23:55:292345WebFrame* RenderView::GetChildFrame(const std::wstring& frame_xpath) const {
2346 WebFrame* web_frame;
2347 if (frame_xpath.empty()) {
2348 web_frame = webview()->GetMainFrame();
2349 } else {
2350 web_frame = webview()->GetMainFrame()->GetChildFrame(frame_xpath);
2351 }
2352
2353 return web_frame;
2354}
2355
[email protected]f29acf52008-11-03 20:08:332356void RenderView::EvaluateScript(const std::wstring& frame_xpath,
2357 const std::wstring& script) {
initial.commit09911bf2008-07-26 23:55:292358 WebFrame* web_frame = GetChildFrame(frame_xpath);
2359 if (!web_frame)
2360 return;
2361
[email protected]4f999132009-03-31 18:08:402362 web_frame->ExecuteScript(WebScriptSource(WideToUTF16Hack(script)));
initial.commit09911bf2008-07-26 23:55:292363}
2364
[email protected]1810e132009-03-24 23:35:482365void RenderView::InsertCSS(const std::wstring& frame_xpath,
2366 const std::string& css) {
2367 WebFrame* web_frame = GetChildFrame(frame_xpath);
2368 if (!web_frame)
2369 return;
2370
2371 web_frame->InsertCSSStyles(css);
2372}
2373
initial.commit09911bf2008-07-26 23:55:292374void RenderView::OnScriptEvalRequest(const std::wstring& frame_xpath,
2375 const std::wstring& jscript) {
[email protected]f29acf52008-11-03 20:08:332376 EvaluateScript(frame_xpath, jscript);
initial.commit09911bf2008-07-26 23:55:292377}
2378
[email protected]1810e132009-03-24 23:35:482379void RenderView::OnCSSInsertRequest(const std::wstring& frame_xpath,
2380 const std::string& css) {
2381 InsertCSS(frame_xpath, css);
[email protected]ae461542009-06-19 19:03:412382
2383 // Notify RenderViewHost that css has been inserted into the frame.
2384 Send(new ViewHostMsg_OnCSSInserted(routing_id_));
[email protected]1810e132009-03-24 23:35:482385}
2386
[email protected]7ea066a2009-04-06 20:21:592387void RenderView::OnAddMessageToConsole(
2388 const string16& frame_xpath,
2389 const string16& message,
2390 const WebConsoleMessage::Level& level) {
2391 WebFrame* web_frame = GetChildFrame(UTF16ToWideHack(frame_xpath));
[email protected]0dea3ea2009-03-31 23:30:592392 if (web_frame)
[email protected]7ea066a2009-04-06 20:21:592393 web_frame->AddMessageToConsole(WebConsoleMessage(level, message));
initial.commit09911bf2008-07-26 23:55:292394}
2395
[email protected]81e63782009-02-27 19:35:092396void RenderView::OnAllowBindings(int enabled_bindings_flags) {
2397 enabled_bindings_ |= enabled_bindings_flags;
initial.commit09911bf2008-07-26 23:55:292398}
2399
2400void RenderView::OnSetDOMUIProperty(const std::string& name,
2401 const std::string& value) {
[email protected]81e63782009-02-27 19:35:092402 DCHECK(BindingsPolicy::is_dom_ui_enabled(enabled_bindings_));
initial.commit09911bf2008-07-26 23:55:292403 dom_ui_bindings_.SetProperty(name, value);
2404}
2405
2406void RenderView::OnReservePageIDRange(int size_of_range) {
2407 next_page_id_ += size_of_range + 1;
2408}
2409
[email protected]e80c73b2009-04-07 23:24:582410void RenderView::OnDragSourceEndedOrMoved(const gfx::Point& client_point,
2411 const gfx::Point& screen_point,
initial.commit09911bf2008-07-26 23:55:292412 bool ended) {
2413 if (ended)
[email protected]e80c73b2009-04-07 23:24:582414 webview()->DragSourceEndedAt(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292415 else
[email protected]e80c73b2009-04-07 23:24:582416 webview()->DragSourceMovedTo(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292417}
2418
2419void RenderView::OnDragSourceSystemDragEnded() {
2420 webview()->DragSourceSystemDragEnded();
2421}
2422
2423void RenderView::OnUploadFileRequest(const ViewMsg_UploadFile_Params& p) {
2424 webkit_glue::FileUploadData* f = new webkit_glue::FileUploadData;
2425 f->file_path = p.file_path;
2426 f->form_name = p.form;
2427 f->file_name = p.file;
2428 f->submit_name = p.submit;
2429
2430 // Build the other form values map.
2431 if (!p.other_values.empty()) {
2432 std::vector<std::wstring> e;
2433 std::vector<std::wstring> kvp;
2434 std::vector<std::wstring>::iterator i;
2435
2436 SplitString(p.other_values, L'\n', &e);
2437 for (i = e.begin(); i != e.end(); ++i) {
2438 SplitString(*i, L'=', &kvp);
2439 if (kvp.size() == 2)
2440 f->other_form_values[kvp[0]] = kvp[1];
2441 kvp.clear();
2442 }
2443 }
2444
2445 pending_upload_data_.reset(f);
2446 ProcessPendingUpload();
2447}
2448
2449void RenderView::ProcessPendingUpload() {
2450 webkit_glue::FileUploadData* f = pending_upload_data_.get();
2451 if (f && webview() && webkit_glue::FillFormToUploadFile(webview(), *f))
2452 ResetPendingUpload();
2453}
2454
2455void RenderView::ResetPendingUpload() {
2456 pending_upload_data_.reset();
2457}
2458
2459void RenderView::OnFormFill(const FormData& form) {
2460 webkit_glue::FillForm(this->webview(), form);
2461}
2462
2463void RenderView::OnFillPasswordForm(
[email protected]daa8c58e2009-06-15 17:21:102464 const webkit_glue::PasswordFormDomManager::FillData& form_data) {
initial.commit09911bf2008-07-26 23:55:292465 webkit_glue::FillPasswordForm(this->webview(), form_data);
2466}
2467
2468void RenderView::OnDragTargetDragEnter(const WebDropData& drop_data,
[email protected]e80c73b2009-04-07 23:24:582469 const gfx::Point& client_point,
2470 const gfx::Point& screen_point) {
2471 bool is_drop_target = webview()->DragTargetDragEnter(
2472 drop_data.ToDragData(),
2473 drop_data.identity,
2474 client_point,
2475 screen_point);
initial.commit09911bf2008-07-26 23:55:292476
2477 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target));
2478}
2479
[email protected]e80c73b2009-04-07 23:24:582480void RenderView::OnDragTargetDragOver(const gfx::Point& client_point,
2481 const gfx::Point& screen_point) {
2482 bool is_drop_target =
2483 webview()->DragTargetDragOver(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292484
2485 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target));
2486}
2487
2488void RenderView::OnDragTargetDragLeave() {
2489 webview()->DragTargetDragLeave();
2490}
2491
[email protected]e80c73b2009-04-07 23:24:582492void RenderView::OnDragTargetDrop(const gfx::Point& client_point,
2493 const gfx::Point& screen_point) {
2494 webview()->DragTargetDrop(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292495}
2496
2497void RenderView::OnUpdateWebPreferences(const WebPreferences& prefs) {
2498 webview()->SetPreferences(prefs);
2499}
2500
2501void RenderView::OnSetAltErrorPageURL(const GURL& url) {
2502 alternate_error_page_url_ = url;
2503}
2504
initial.commit09911bf2008-07-26 23:55:292505void RenderView::OnInstallMissingPlugin() {
2506 // This could happen when the first default plugin is deleted.
2507 if (first_default_plugin_ == NULL)
2508 return;
2509 first_default_plugin_->InstallMissingPlugin();
2510}
2511
[email protected]b62d1a8c2009-01-13 23:54:572512void RenderView::OnFileChooserResponse(
[email protected]561abe62009-04-06 18:08:342513 const std::vector<FilePath>& file_names) {
[email protected]8029f5672009-03-20 22:33:362514 // This could happen if we navigated to a different page before the user
2515 // closed the chooser.
2516 if (!file_chooser_.get())
2517 return;
2518
[email protected]b62d1a8c2009-01-13 23:54:572519 file_chooser_->OnFileChoose(file_names);
initial.commit09911bf2008-07-26 23:55:292520 file_chooser_.reset();
2521}
2522
2523void RenderView::OnEnableViewSourceMode() {
2524 if (!webview())
2525 return;
2526 WebFrame* main_frame = webview()->GetMainFrame();
2527 if (!main_frame)
2528 return;
2529
2530 main_frame->SetInViewSourceMode(true);
2531}
2532
[email protected]0666aef2009-05-13 19:48:082533void RenderView::OnEnableIntrinsicWidthChangedMode() {
2534 send_preferred_width_changes_ = true;
2535}
2536
[email protected]80d96fa2009-06-10 22:34:512537void RenderView::OnSetRendererPrefs(const RendererPreferences& renderer_prefs) {
2538 renderer_preferences_ = renderer_prefs;
2539}
2540
initial.commit09911bf2008-07-26 23:55:292541void RenderView::OnUpdateBackForwardListCount(int back_list_count,
2542 int forward_list_count) {
2543 history_back_list_count_ = back_list_count;
2544 history_forward_list_count_ = forward_list_count;
2545}
2546
[email protected]266eb6f2008-09-30 23:56:502547void RenderView::OnGetAccessibilityInfo(
[email protected]6a983b42009-03-20 20:12:252548 const webkit_glue::WebAccessibility::InParams& in_params,
2549 webkit_glue::WebAccessibility::OutParams* out_params) {
[email protected]6c8afae52009-01-22 02:24:572550#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:252551 if (!web_accessibility_manager_.get()) {
2552 web_accessibility_manager_.reset(
2553 webkit_glue::WebAccessibilityManager::Create());
2554 }
[email protected]266eb6f2008-09-30 23:56:502555
[email protected]6a983b42009-03-20 20:12:252556 if (!web_accessibility_manager_->GetAccObjInfo(webview(), in_params,
2557 out_params)) {
[email protected]266eb6f2008-09-30 23:56:502558 return;
2559 }
[email protected]6c8afae52009-01-22 02:24:572560#else // defined(OS_WIN)
2561 // TODO(port): accessibility not yet implemented
2562 NOTIMPLEMENTED();
2563#endif
[email protected]266eb6f2008-09-30 23:56:502564}
2565
[email protected]6a983b42009-03-20 20:12:252566void RenderView::OnClearAccessibilityInfo(int acc_obj_id, bool clear_all) {
[email protected]6c8afae52009-01-22 02:24:572567#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:252568 if (!web_accessibility_manager_.get()) {
[email protected]266eb6f2008-09-30 23:56:502569 // If accessibility is not activated, ignore clearing message.
2570 return;
2571 }
[email protected]e846d0d2009-05-20 00:53:062572
[email protected]6a983b42009-03-20 20:12:252573 if (!web_accessibility_manager_->ClearAccObjMap(acc_obj_id, clear_all))
[email protected]266eb6f2008-09-30 23:56:502574 return;
[email protected]e846d0d2009-05-20 00:53:062575
[email protected]6c8afae52009-01-22 02:24:572576#else // defined(OS_WIN)
2577 // TODO(port): accessibility not yet implemented
2578 NOTIMPLEMENTED();
2579#endif
[email protected]266eb6f2008-09-30 23:56:502580}
2581
initial.commit09911bf2008-07-26 23:55:292582void RenderView::OnGetAllSavableResourceLinksForCurrentPage(
2583 const GURL& page_url) {
2584 // Prepare list to storage all savable resource links.
2585 std::vector<GURL> resources_list;
2586 std::vector<GURL> referrers_list;
2587 std::vector<GURL> frames_list;
2588 webkit_glue::SavableResourcesResult result(&resources_list,
2589 &referrers_list,
2590 &frames_list);
2591
2592 if (!webkit_glue::GetAllSavableResourceLinksForCurrentPage(webview(),
2593 page_url,
2594 &result)) {
2595 // If something is wrong when collecting all savable resource links,
2596 // send empty list to embedder(browser) to tell it failed.
2597 referrers_list.clear();
2598 resources_list.clear();
2599 frames_list.clear();
2600 }
2601
2602 // Send result of all savable resource links to embedder.
2603 Send(new ViewHostMsg_SendCurrentPageAllSavableResourceLinks(routing_id_,
2604 resources_list,
2605 referrers_list,
2606 frames_list));
2607}
2608
2609void RenderView::OnGetSerializedHtmlDataForCurrentPageWithLocalLinks(
[email protected]f6b48532009-02-12 01:56:322610 const std::vector<GURL>& links,
[email protected]fde6714d12009-02-18 22:39:312611 const std::vector<FilePath>& local_paths,
2612 const FilePath& local_directory_name) {
initial.commit09911bf2008-07-26 23:55:292613 webkit_glue::DomSerializer dom_serializer(webview()->GetMainFrame(),
2614 true,
2615 this,
2616 links,
2617 local_paths,
2618 local_directory_name);
2619 dom_serializer.SerializeDom();
2620}
2621
2622void RenderView::DidSerializeDataForFrame(const GURL& frame_url,
2623 const std::string& data, PageSavingSerializationStatus status) {
2624 Send(new ViewHostMsg_SendSerializedHtmlData(routing_id_,
2625 frame_url, data, static_cast<int32>(status)));
2626}
2627
[email protected]04b4a6c2008-08-02 00:44:472628void RenderView::OnMsgShouldClose() {
initial.commit09911bf2008-07-26 23:55:292629 bool should_close = webview()->ShouldClose();
[email protected]04b4a6c2008-08-02 00:44:472630 Send(new ViewHostMsg_ShouldClose_ACK(routing_id_, should_close));
initial.commit09911bf2008-07-26 23:55:292631}
2632
2633void RenderView::OnClosePage(int new_render_process_host_id,
[email protected]04b4a6c2008-08-02 00:44:472634 int new_request_id) {
initial.commit09911bf2008-07-26 23:55:292635 // TODO(creis): We'd rather use webview()->Close() here, but that currently
2636 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs
2637 // in the onunload handler from appearing. For now, we're bypassing that and
2638 // calling the FrameLoader's CloseURL method directly. This should be
2639 // revisited to avoid having two ways to close a page. Having a single way
2640 // to close that can run onunload is also useful for fixing
2641 // http://b/issue?id=753080.
2642 WebFrame* main_frame = webview()->GetMainFrame();
2643 if (main_frame)
2644 main_frame->ClosePage();
2645
2646 Send(new ViewHostMsg_ClosePage_ACK(routing_id_,
2647 new_render_process_host_id,
[email protected]04b4a6c2008-08-02 00:44:472648 new_request_id));
initial.commit09911bf2008-07-26 23:55:292649}
2650
2651void RenderView::OnThemeChanged() {
[email protected]6c8afae52009-01-22 02:24:572652#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292653 gfx::NativeTheme::instance()->CloseHandles();
2654 gfx::Rect view_rect(0, 0, size_.width(), size_.height());
2655 DidInvalidateRect(webwidget_, view_rect);
[email protected]6c8afae52009-01-22 02:24:572656#else // defined(OS_WIN)
2657 // TODO(port): we don't support theming on non-Windows platforms yet
2658 NOTIMPLEMENTED();
2659#endif
initial.commit09911bf2008-07-26 23:55:292660}
2661
[email protected]f46aff62008-10-16 07:58:052662void RenderView::DidAddHistoryItem() {
[email protected]f8901082008-10-31 23:34:032663 // We don't want to update the history length for the start page
2664 // navigation.
2665 WebFrame* main_frame = webview()->GetMainFrame();
2666 DCHECK(main_frame != NULL);
2667
2668 WebDataSource* ds = main_frame->GetDataSource();
2669 DCHECK(ds != NULL);
2670
[email protected]daa8c58e2009-06-15 17:21:102671 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
2672 if (navigation_state->transition_type() == PageTransition::START_PAGE)
[email protected]f8901082008-10-31 23:34:032673 return;
2674
[email protected]f46aff62008-10-16 07:58:052675 history_back_list_count_++;
2676 history_forward_list_count_ = 0;
2677}
2678
[email protected]28790922009-03-09 19:48:372679void RenderView::OnMessageFromExternalHost(const std::string& message,
2680 const std::string& origin,
2681 const std::string& target) {
[email protected]3ac14a052008-08-15 21:22:152682 if (message.empty())
2683 return;
2684
[email protected]28790922009-03-09 19:48:372685 external_host_bindings_.ForwardMessageFromExternalHost(message, origin,
2686 target);
[email protected]3ac14a052008-08-15 21:22:152687}
2688
[email protected]0aa55312008-10-17 21:53:082689void RenderView::OnDisassociateFromPopupCount() {
2690 if (decrement_shared_popup_at_destruction_)
2691 shared_popup_counter_->data--;
2692 shared_popup_counter_ = new SharedRenderViewCounter(0);
2693 decrement_shared_popup_at_destruction_ = false;
2694}
2695
initial.commit09911bf2008-07-26 23:55:292696std::string RenderView::GetAltHTMLForTemplate(
2697 const DictionaryValue& error_strings, int template_resource_id) const {
2698 const StringPiece template_html(
2699 ResourceBundle::GetSharedInstance().GetRawDataResource(
2700 template_resource_id));
2701
2702 if (template_html.empty()) {
2703 NOTREACHED() << "unable to load template. ID: " << template_resource_id;
2704 return "";
2705 }
2706 // "t" is the id of the templates root node.
2707 return jstemplate_builder::GetTemplateHtml(
2708 template_html, &error_strings, "t");
2709}
[email protected]0e79b9e2009-02-13 04:20:482710
2711MessageLoop* RenderView::GetMessageLoopForIO() {
2712 // Assume that we have only one RenderThread in the process and the owner loop
2713 // of RenderThread is an IO message loop.
[email protected]8930d472009-02-21 08:05:282714 if (RenderThread::current())
2715 return RenderThread::current()->owner_loop();
[email protected]0e79b9e2009-02-13 04:20:482716 return NULL;
2717}
[email protected]6f56d482009-02-20 05:02:562718
[email protected]30f75e62009-02-25 22:01:002719void RenderView::OnMoveOrResizeStarted() {
2720 if (webview())
2721 webview()->HideAutofillPopup();
2722}
2723
[email protected]30f75e62009-02-25 22:01:002724void RenderView::OnResize(const gfx::Size& new_size,
2725 const gfx::Rect& resizer_rect) {
2726 if (webview())
2727 webview()->HideAutofillPopup();
2728 RenderWidget::OnResize(new_size, resizer_rect);
2729}
[email protected]0aa477bd2009-03-23 22:21:432730
[email protected]05d478752009-04-08 23:38:162731void RenderView::OnClearFocusedNode() {
2732 if (webview())
2733 webview()->ClearFocusedNode();
2734}
2735
[email protected]699ab0d2009-04-23 23:19:142736void RenderView::OnSetBackground(const SkBitmap& background) {
2737 if (webview())
2738 webview()->SetIsTransparent(!background.empty());
2739
2740 SetBackground(background);
2741}
2742
[email protected]309d7a282009-03-24 09:18:272743void RenderView::SendExtensionRequest(const std::string& name,
2744 const std::string& args,
[email protected]c6619182009-05-12 14:59:322745 int request_id,
[email protected]2f25d7b92009-06-10 00:06:472746 bool has_callback) {
[email protected]c6619182009-05-12 14:59:322747 Send(new ViewHostMsg_ExtensionRequest(routing_id_, name, args, request_id,
[email protected]2f25d7b92009-06-10 00:06:472748 has_callback));
[email protected]309d7a282009-03-24 09:18:272749}
2750
[email protected]c6619182009-05-12 14:59:322751void RenderView::OnExtensionResponse(int request_id,
2752 bool success,
2753 const std::string& response,
2754 const std::string& error) {
[email protected]2f25d7b92009-06-10 00:06:472755 ExtensionProcessBindings::HandleResponse(request_id, success, response,
2756 error);
[email protected]309d7a282009-03-24 09:18:272757}
[email protected]c20210e62009-04-03 21:39:262758
[email protected]e7e4f3c2009-04-21 15:24:082759// Dump all load time histograms.
[email protected]c20210e62009-04-03 21:39:262760//
[email protected]e7e4f3c2009-04-21 15:24:082761// There are 7 histograms measuring various times.
[email protected]c20210e62009-04-03 21:39:262762// The time points we keep are
2763// request: time document was requested by user
2764// start: time load of document started
2765// finishDoc: main document loaded, before onload()
2766// finish: after onload() and all resources are loaded
[email protected]e7e4f3c2009-04-21 15:24:082767// firstLayout: first layout performed
[email protected]c20210e62009-04-03 21:39:262768// The times that we histogram are
2769// requestToStart,
2770// startToFinishDoc,
2771// finishDocToFinish,
2772// startToFinish,
2773// requestToFinish,
[email protected]e7e4f3c2009-04-21 15:24:082774// requestToFirstLayout
2775// startToFirstLayout
[email protected]c20210e62009-04-03 21:39:262776//
[email protected]e7e4f3c2009-04-21 15:24:082777// It's possible for the request time not to be set, if a client
2778// redirect had been done (the user never requested the page)
2779// Also, it's possible to load a page without ever laying it out
2780// so firstLayout can be 0.
[email protected]c20210e62009-04-03 21:39:262781void RenderView::DumpLoadHistograms() const {
2782 WebFrame* main_frame = webview()->GetMainFrame();
[email protected]ed3fb032009-06-16 19:50:562783 NavigationState* navigation_state =
2784 NavigationState::FromDataSource(main_frame->GetDataSource());
2785
2786 Time request_time = navigation_state->request_time();
2787 Time start_load_time = navigation_state->start_load_time();
2788 Time finish_document_load_time =
2789 navigation_state->finish_document_load_time();
2790 Time finish_load_time = navigation_state->finish_load_time();
2791 Time first_layout_time = navigation_state->first_layout_time();
2792
[email protected]c20210e62009-04-03 21:39:262793 TimeDelta request_to_start = start_load_time - request_time;
2794 TimeDelta start_to_finish_doc = finish_document_load_time - start_load_time;
[email protected]e7e4f3c2009-04-21 15:24:082795 TimeDelta finish_doc_to_finish =
2796 finish_load_time - finish_document_load_time;
[email protected]c20210e62009-04-03 21:39:262797 TimeDelta start_to_finish = finish_load_time - start_load_time;
[email protected]978077e2009-06-20 22:32:512798 TimeDelta request_to_finish = finish_load_time - request_time;
[email protected]e7e4f3c2009-04-21 15:24:082799 TimeDelta request_to_first_layout = first_layout_time - request_time;
2800 TimeDelta start_to_first_layout = first_layout_time - start_load_time;
[email protected]c20210e62009-04-03 21:39:262801
[email protected]e7e4f3c2009-04-21 15:24:082802 // Client side redirects will have no request time
2803 if (request_time.ToInternalValue() != 0) {
[email protected]f929f2f22009-06-12 16:56:582804 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.RequestToStart", request_to_start);
[email protected]978077e2009-06-20 22:32:512805 UMA_HISTOGRAM_CUSTOM_TIMES(
2806 FieldTrial::MakeName("Renderer2.RequestToFinish_2", "DnsImpact").data(),
[email protected]ed3fb032009-06-16 19:50:562807 request_to_finish, TimeDelta::FromMilliseconds(10),
2808 TimeDelta::FromMinutes(10), 100);
[email protected]e7e4f3c2009-04-21 15:24:082809 if (request_to_first_layout.ToInternalValue() >= 0) {
[email protected]f929f2f22009-06-12 16:56:582810 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.RequestToFirstLayout",
[email protected]4646f292009-05-20 03:49:052811 request_to_first_layout);
[email protected]e7e4f3c2009-04-21 15:24:082812 }
2813 }
[email protected]f929f2f22009-06-12 16:56:582814 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.StartToFinishDoc", start_to_finish_doc);
2815 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.FinishDocToFinish",
2816 finish_doc_to_finish);
2817 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.StartToFinish", start_to_finish);
[email protected]e7e4f3c2009-04-21 15:24:082818 if (start_to_first_layout.ToInternalValue() >= 0) {
[email protected]f929f2f22009-06-12 16:56:582819 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.StartToFirstLayout",
2820 start_to_first_layout);
[email protected]c20210e62009-04-03 21:39:262821 }
2822}
[email protected]e846d0d2009-05-20 00:53:062823
2824void RenderView::FocusAccessibilityObject(
2825 WebCore::AccessibilityObject* acc_obj) {
2826#if defined(OS_WIN)
2827 if (!web_accessibility_manager_.get()) {
2828 web_accessibility_manager_.reset(
2829 webkit_glue::WebAccessibilityManager::Create());
2830 }
2831
2832 // Retrieve the accessibility object id of the AccessibilityObject.
2833 int acc_obj_id = web_accessibility_manager_->FocusAccObj(acc_obj);
2834
2835 // If id is valid, alert the browser side that an accessibility focus change
2836 // occurred.
2837 if (acc_obj_id >= 0)
2838 Send(new ViewHostMsg_AccessibilityFocusChange(routing_id_, acc_obj_id));
2839
2840#else // defined(OS_WIN)
2841 // TODO(port): accessibility not yet implemented
2842 NOTIMPLEMENTED();
2843#endif
2844}
[email protected]daa8c58e2009-06-15 17:21:102845
2846void RenderView::SendPasswordForms(WebFrame* frame) {
2847 std::vector<WebForm> forms;
2848 frame->GetForms(&forms);
2849
2850 std::vector<PasswordForm> password_forms;
2851 for (size_t i = 0; i < forms.size(); ++i) {
2852 const WebForm& form = forms[i];
2853
2854 // Respect autocomplete=off.
2855 if (form.isAutoCompleteEnabled()) {
2856 scoped_ptr<PasswordForm> password_form(
2857 PasswordFormDomManager::CreatePasswordForm(form));
2858 if (password_form.get())
2859 password_forms.push_back(*password_form);
2860 }
2861 }
2862
2863 if (!password_forms.empty())
2864 Send(new ViewHostMsg_PasswordFormsSeen(routing_id_, password_forms));
2865}