blob: f59cfce18d7750f8a70604638806ea269d65e695 [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]f816c012009-06-26 21:48:3238#include "chrome/renderer/extensions/event_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]ca948a22009-06-25 19:36:1760#include "webkit/api/public/WebHistoryItem.h"
[email protected]afdcf5c2009-05-10 20:30:4161#include "webkit/api/public/WebPoint.h"
62#include "webkit/api/public/WebRect.h"
63#include "webkit/api/public/WebScriptSource.h"
64#include "webkit/api/public/WebSize.h"
[email protected]726985e22009-06-18 21:09:2865#include "webkit/api/public/WebURL.h"
66#include "webkit/api/public/WebURLError.h"
67#include "webkit/api/public/WebURLRequest.h"
68#include "webkit/api/public/WebURLResponse.h"
69#include "webkit/api/public/WebVector.h"
[email protected]ba4b17f2009-02-11 21:32:2970#include "webkit/default_plugin/default_plugin_shared.h"
[email protected]ca948a22009-06-25 19:36:1771#include "webkit/glue/glue_serialize.h"
initial.commit09911bf2008-07-26 23:55:2972#include "webkit/glue/dom_operations.h"
73#include "webkit/glue/dom_serializer.h"
[email protected]f11ca0732009-04-11 00:09:3474#include "webkit/glue/image_decoder.h"
[email protected]8380c092009-06-25 17:45:5175#include "webkit/glue/media/simple_data_source.h"
initial.commit09911bf2008-07-26 23:55:2976#include "webkit/glue/password_form.h"
[email protected]ba4b17f2009-02-11 21:32:2977#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:2978#include "webkit/glue/searchable_form_data.h"
[email protected]6a983b42009-03-20 20:12:2579#include "webkit/glue/webaccessibilitymanager_impl.h"
[email protected]611cad42009-03-16 18:51:3480#include "webkit/glue/webdevtoolsagent_delegate.h"
initial.commit09911bf2008-07-26 23:55:2981#include "webkit/glue/webdropdata.h"
initial.commit09911bf2008-07-26 23:55:2982#include "webkit/glue/webframe.h"
initial.commit09911bf2008-07-26 23:55:2983#include "webkit/glue/webkit_glue.h"
[email protected]add51772009-06-11 18:25:1784#include "webkit/glue/webmediaplayer_impl.h"
initial.commit09911bf2008-07-26 23:55:2985#include "webkit/glue/webpreferences.h"
[email protected]b94d3322009-02-12 19:49:0486#include "webkit/glue/webplugin_delegate.h"
[email protected]00d7e622009-04-21 23:06:0587#include "webkit/glue/webtextinput.h"
initial.commit09911bf2008-07-26 23:55:2988#include "webkit/glue/webview.h"
initial.commit09911bf2008-07-26 23:55:2989
[email protected]6c8afae52009-01-22 02:24:5790#if defined(OS_WIN)
91// TODO(port): these files are currently Windows only because they concern:
[email protected]6c8afae52009-01-22 02:24:5792// * theming
[email protected]6c8afae52009-01-22 02:24:5793#include "base/gfx/native_theme.h"
[email protected]6c8afae52009-01-22 02:24:5794#endif
95
[email protected]c20210e62009-04-03 21:39:2696using base::Time;
[email protected]e1acf6f2008-10-27 20:43:3397using base::TimeDelta;
[email protected]daa8c58e2009-06-15 17:21:1098using webkit_glue::AutofillForm;
[email protected]ed3fb032009-06-16 19:50:5699using webkit_glue::PasswordForm;
[email protected]daa8c58e2009-06-15 17:21:10100using webkit_glue::PasswordFormDomManager;
101using webkit_glue::SearchableFormData;
[email protected]0dea3ea2009-03-31 23:30:59102using WebKit::WebConsoleMessage;
[email protected]e6f546c32009-07-01 17:12:55103using WebKit::WebData;
[email protected]726985e22009-06-18 21:09:28104using WebKit::WebDataSource;
[email protected]e80c73b2009-04-07 23:24:58105using WebKit::WebDragData;
[email protected]daa8c58e2009-06-15 17:21:10106using WebKit::WebForm;
[email protected]ca948a22009-06-25 19:36:17107using WebKit::WebHistoryItem;
[email protected]726985e22009-06-18 21:09:28108using WebKit::WebNavigationType;
[email protected]b3f2b912009-04-09 16:18:52109using WebKit::WebRect;
[email protected]4f999132009-03-31 18:08:40110using WebKit::WebScriptSource;
[email protected]8649fb32009-06-26 17:51:02111using WebKit::WebSize;
[email protected]726985e22009-06-18 21:09:28112using WebKit::WebString;
113using WebKit::WebURL;
114using WebKit::WebURLError;
115using WebKit::WebURLRequest;
116using WebKit::WebURLResponse;
[email protected]27ba8532009-04-24 20:22:43117using WebKit::WebWorker;
118using WebKit::WebWorkerClient;
[email protected]726985e22009-06-18 21:09:28119using WebKit::WebVector;
[email protected]e1acf6f2008-10-27 20:43:33120
initial.commit09911bf2008-07-26 23:55:29121//-----------------------------------------------------------------------------
122
123// define to write the time necessary for thumbnail/DOM text retrieval,
124// respectively, into the system debug log
125// #define TIME_BITMAP_RETRIEVAL
126// #define TIME_TEXT_RETRIEVAL
127
128// maximum number of characters in the document to index, any text beyond this
129// point will be clipped
[email protected]6c8afae52009-01-22 02:24:57130static const size_t kMaxIndexChars = 65535;
initial.commit09911bf2008-07-26 23:55:29131
132// Size of the thumbnails that we'll generate
133static const int kThumbnailWidth = 196;
134static const int kThumbnailHeight = 136;
135
136// Delay in milliseconds that we'll wait before capturing the page contents
137// and thumbnail.
138static const int kDelayForCaptureMs = 500;
139
140// Typically, we capture the page data once the page is loaded.
141// Sometimes, the page never finishes to load, preventing the page capture
142// To workaround this problem, we always perform a capture after the following
143// delay.
144static const int kDelayForForcedCaptureMs = 6000;
145
[email protected]81a34412009-01-05 19:17:24146// The default value for RenderView.delay_seconds_for_form_state_sync_, see
147// that variable for more.
148const int kDefaultDelaySecondsForFormStateSync = 5;
initial.commit09911bf2008-07-26 23:55:29149
150// The next available page ID to use. This ensures that the page IDs are
151// globally unique in the renderer.
152static int32 next_page_id_ = 1;
153
[email protected]0aa55312008-10-17 21:53:08154// The maximum number of popups that can be spawned from one page.
155static const int kMaximumNumberOfUnacknowledgedPopups = 25;
156
initial.commit09911bf2008-07-26 23:55:29157static const char* const kUnreachableWebDataURL =
[email protected]60e448982009-05-06 04:21:16158 "chrome://chromewebdata/";
initial.commit09911bf2008-07-26 23:55:29159
[email protected]50b691c2008-10-31 19:08:35160static const char* const kBackForwardNavigationScheme = "history";
161
[email protected]726985e22009-06-18 21:09:28162static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
163 WebVector<WebURL> urls;
164 ds->redirectChain(urls);
165 result->reserve(urls.size());
166 for (size_t i = 0; i < urls.size(); ++i)
167 result->push_back(urls[i]);
168}
169
initial.commit09911bf2008-07-26 23:55:29170///////////////////////////////////////////////////////////////////////////////
171
[email protected]81a34412009-01-05 19:17:24172RenderView::RenderView(RenderThreadBase* render_thread)
173 : RenderWidget(render_thread, true),
[email protected]81e63782009-02-27 19:35:09174 enabled_bindings_(0),
[email protected]e75cb49e2009-01-05 23:13:21175 target_url_status_(TARGET_NONE),
[email protected]81a34412009-01-05 19:17:24176 is_loading_(false),
[email protected]e75cb49e2009-01-05 23:13:21177 navigation_gesture_(NavigationGestureUnknown),
[email protected]81a34412009-01-05 19:17:24178 page_id_(-1),
179 last_page_id_sent_to_browser_(-1),
180 last_indexed_page_id_(-1),
[email protected]81a34412009-01-05 19:17:24181 opened_by_user_gesture_(true),
[email protected]bb063b72009-03-27 23:18:50182 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
[email protected]81a34412009-01-05 19:17:24183 first_default_plugin_(NULL),
[email protected]e4ac5df2009-03-17 15:33:11184 devtools_agent_(NULL),
185 devtools_client_(NULL),
[email protected]81a34412009-01-05 19:17:24186 history_back_list_count_(0),
187 history_forward_list_count_(0),
[email protected]81a34412009-01-05 19:17:24188 has_unload_listener_(false),
189 decrement_shared_popup_at_destruction_(false),
[email protected]81a34412009-01-05 19:17:24190 form_field_autofill_request_id_(0),
191 popup_notification_visible_(false),
[email protected]0666aef2009-05-13 19:48:08192 delay_seconds_for_form_state_sync_(kDefaultDelaySecondsForFormStateSync),
193 preferred_width_(0),
[email protected]9b6f40e2009-06-11 15:54:26194 send_preferred_width_changes_(false) {
initial.commit09911bf2008-07-26 23:55:29195}
196
197RenderView::~RenderView() {
[email protected]0aa55312008-10-17 21:53:08198 if (decrement_shared_popup_at_destruction_)
199 shared_popup_counter_->data--;
200
initial.commit09911bf2008-07-26 23:55:29201 // Clear any back-pointers that might still be held by plugins.
202 PluginDelegateList::iterator it = plugin_delegates_.begin();
203 while (it != plugin_delegates_.end()) {
204 (*it)->DropRenderView();
205 it = plugin_delegates_.erase(it);
206 }
207
[email protected]5fb88962009-04-16 19:03:25208 render_thread_->RemoveFilter(audio_message_filter_);
initial.commit09911bf2008-07-26 23:55:29209}
210
211/*static*/
[email protected]0aa55312008-10-17 21:53:08212RenderView* RenderView::Create(
[email protected]81a34412009-01-05 19:17:24213 RenderThreadBase* render_thread,
[email protected]18bcc3c2009-01-27 21:39:15214 gfx::NativeViewId parent_hwnd,
[email protected]1c4947f2009-01-15 22:25:11215 base::WaitableEvent* modal_dialog_event,
[email protected]0aa55312008-10-17 21:53:08216 int32 opener_id,
[email protected]80d96fa2009-06-10 22:34:51217 const RendererPreferences& renderer_prefs,
[email protected]0aa55312008-10-17 21:53:08218 const WebPreferences& webkit_prefs,
219 SharedRenderViewCounter* counter,
220 int32 routing_id) {
initial.commit09911bf2008-07-26 23:55:29221 DCHECK(routing_id != MSG_ROUTING_NONE);
[email protected]81a34412009-01-05 19:17:24222 scoped_refptr<RenderView> view = new RenderView(render_thread);
initial.commit09911bf2008-07-26 23:55:29223 view->Init(parent_hwnd,
224 modal_dialog_event,
225 opener_id,
[email protected]80d96fa2009-06-10 22:34:51226 renderer_prefs,
initial.commit09911bf2008-07-26 23:55:29227 webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08228 counter,
initial.commit09911bf2008-07-26 23:55:29229 routing_id); // adds reference
230 return view;
231}
232
233/*static*/
234void RenderView::SetNextPageID(int32 next_page_id) {
235 // This method should only be called during process startup, and the given
236 // page id had better not exceed our current next page id!
[email protected]4646f292009-05-20 03:49:05237 DCHECK_EQ(next_page_id_, 1);
initial.commit09911bf2008-07-26 23:55:29238 DCHECK(next_page_id >= next_page_id_);
239 next_page_id_ = next_page_id;
240}
241
242void RenderView::PluginDestroyed(WebPluginDelegateProxy* proxy) {
243 PluginDelegateList::iterator it =
244 std::find(plugin_delegates_.begin(), plugin_delegates_.end(), proxy);
245 DCHECK(it != plugin_delegates_.end());
246 plugin_delegates_.erase(it);
247 // If the plugin is deleted, we need to clear our reference in case user
248 // clicks the info bar to install. Unfortunately we are getting
249 // PluginDestroyed in single process mode. However, that is not a huge
250 // concern.
251 if (proxy == first_default_plugin_)
252 first_default_plugin_ = NULL;
253}
254
[email protected]690a99c2009-01-06 16:48:45255void RenderView::PluginCrashed(const FilePath& plugin_path) {
initial.commit09911bf2008-07-26 23:55:29256 Send(new ViewHostMsg_CrashedPlugin(routing_id_, plugin_path));
257}
258
259
260void RenderView::JSOutOfMemory() {
261 Send(new ViewHostMsg_JSOutOfMemory(routing_id_));
262}
263
[email protected]18bcc3c2009-01-27 21:39:15264void RenderView::Init(gfx::NativeViewId parent_hwnd,
[email protected]1c4947f2009-01-15 22:25:11265 base::WaitableEvent* modal_dialog_event,
initial.commit09911bf2008-07-26 23:55:29266 int32 opener_id,
[email protected]80d96fa2009-06-10 22:34:51267 const RendererPreferences& renderer_prefs,
initial.commit09911bf2008-07-26 23:55:29268 const WebPreferences& webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08269 SharedRenderViewCounter* counter,
initial.commit09911bf2008-07-26 23:55:29270 int32 routing_id) {
271 DCHECK(!webview());
272
273 if (opener_id != MSG_ROUTING_NONE)
274 opener_id_ = opener_id;
275
[email protected]0aa55312008-10-17 21:53:08276 if (counter) {
277 shared_popup_counter_ = counter;
278 shared_popup_counter_->data++;
279 decrement_shared_popup_at_destruction_ = true;
280 } else {
281 shared_popup_counter_ = new SharedRenderViewCounter(0);
282 decrement_shared_popup_at_destruction_ = false;
283 }
284
[email protected]80d96fa2009-06-10 22:34:51285 OnSetRendererPrefs(renderer_prefs);
286
[email protected]58bfc6b2009-06-24 09:45:02287 devtools_agent_.reset(new DevToolsAgent(routing_id, this));
[email protected]9b9d7282009-04-08 14:13:04288
[email protected]c5b3b5e2009-02-13 06:41:11289 webwidget_ = WebView::Create(this, webkit_prefs);
initial.commit09911bf2008-07-26 23:55:29290
[email protected]2e417c82009-04-02 22:30:26291#if defined(OS_LINUX)
292 // We have to enable ourselves as the editor delegate on linux so we can copy
293 // text selections to the X clipboard.
294 webview()->SetUseEditorDelegate(true);
295#endif
296
initial.commit09911bf2008-07-26 23:55:29297 // Don't let WebCore keep a B/F list - we have our own.
298 // We let it keep 1 entry because FrameLoader::goToItem expects an item in the
299 // backForwardList, which is used only in ASSERTs.
300 webview()->SetBackForwardListSize(1);
301
302 routing_id_ = routing_id;
[email protected]81a34412009-01-05 19:17:24303 render_thread_->AddRoute(routing_id_, this);
initial.commit09911bf2008-07-26 23:55:29304 // Take a reference on behalf of the RenderThread. This will be balanced
305 // when we receive ViewMsg_Close.
306 AddRef();
307
308 // If this is a popup, we must wait for the CreatingNew_ACK message before
309 // completing initialization. Otherwise, we can finish it now.
310 if (opener_id == MSG_ROUTING_NONE) {
311 did_show_ = true;
312 CompleteInit(parent_hwnd);
313 }
314
315 host_window_ = parent_hwnd;
[email protected]1c4947f2009-01-15 22:25:11316 modal_dialog_event_.reset(modal_dialog_event);
initial.commit09911bf2008-07-26 23:55:29317
[email protected]58bfc6b2009-06-24 09:45:02318 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]81e63782009-02-27 19:35:09319 if (command_line.HasSwitch(switches::kDomAutomationController))
320 enabled_bindings_ |= BindingsPolicy::DOM_AUTOMATION;
initial.commit09911bf2008-07-26 23:55:29321
[email protected]5fb88962009-04-16 19:03:25322 audio_message_filter_ = new AudioMessageFilter(routing_id_);
323 render_thread_->AddFilter(audio_message_filter_);
initial.commit09911bf2008-07-26 23:55:29324}
325
326void RenderView::OnMessageReceived(const IPC::Message& message) {
[email protected]f8b6b6f2009-03-10 16:48:26327 WebFrame* main_frame = webview() ? webview()->GetMainFrame() : NULL;
328 renderer_logging::ScopedActiveRenderingURLSetter url_setter(
329 main_frame ? main_frame->GetURL() : GURL());
[email protected]f8b6b6f2009-03-10 16:48:26330
[email protected]b2abac72009-02-26 12:39:28331 // If this is developer tools renderer intercept tools messages first.
[email protected]e4ac5df2009-03-17 15:33:11332 if (devtools_client_.get() && devtools_client_->OnMessageReceived(message))
[email protected]b2abac72009-02-26 12:39:28333 return;
[email protected]b4b967e2009-04-22 11:33:05334 if (devtools_agent_.get() && devtools_agent_->OnMessageReceived(message))
335 return;
[email protected]b2abac72009-02-26 12:39:28336
initial.commit09911bf2008-07-26 23:55:29337 IPC_BEGIN_MESSAGE_MAP(RenderView, message)
initial.commit09911bf2008-07-26 23:55:29338 IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)
initial.commit09911bf2008-07-26 23:55:29339 IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)
[email protected]82270452009-06-19 15:58:01340 IPC_MESSAGE_HANDLER(ViewMsg_PrintingDone, OnPrintingDone)
initial.commit09911bf2008-07-26 23:55:29341 IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
342 IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
343 IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText)
344 IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
345 IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)
346 IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)
347 IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)
348 IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)
349 IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)
350 IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)
[email protected]bbbd545c2008-12-15 20:18:04351 IPC_MESSAGE_HANDLER(ViewMsg_ToggleSpellCheck, OnToggleSpellCheck)
initial.commit09911bf2008-07-26 23:55:29352 IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)
353 IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)
354 IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
[email protected]4b59ae602009-06-23 20:58:15355 IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand)
initial.commit09911bf2008-07-26 23:55:29356 IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
[email protected]630e26b2008-10-14 22:55:17357 IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
[email protected]ea8c7452009-04-02 20:47:06358 IPC_MESSAGE_HANDLER(ViewMsg_InsertText, OnInsertText)
initial.commit09911bf2008-07-26 23:55:29359 IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
[email protected]b2abac72009-02-26 12:39:28360 IPC_MESSAGE_HANDLER(ViewMsg_SetupDevToolsClient, OnSetupDevToolsClient)
initial.commit09911bf2008-07-26 23:55:29361 IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)
362 IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
[email protected]1810e132009-03-24 23:35:48363 IPC_MESSAGE_HANDLER(ViewMsg_CSSInsertRequest, OnCSSInsertRequest)
initial.commit09911bf2008-07-26 23:55:29364 IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)
initial.commit09911bf2008-07-26 23:55:29365 IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)
366 IPC_MESSAGE_HANDLER(ViewMsg_UploadFile, OnUploadFileRequest)
367 IPC_MESSAGE_HANDLER(ViewMsg_FormFill, OnFormFill)
368 IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)
369 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)
370 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)
371 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)
372 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)
[email protected]18cb2572008-08-21 20:34:45373 IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)
initial.commit09911bf2008-07-26 23:55:29374 IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)
[email protected]266eb6f2008-09-30 23:56:50375 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved,
376 OnDragSourceEndedOrMoved)
initial.commit09911bf2008-07-26 23:55:29377 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,
378 OnDragSourceSystemDragEnded)
379 IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)
380 IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)
381 IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)
382 IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
383 IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)
384 IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)
385 IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
386 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)
387 IPC_MESSAGE_HANDLER(ViewMsg_UpdateBackForwardListCount,
388 OnUpdateBackForwardListCount)
389 IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,
390 OnGetAllSavableResourceLinksForCurrentPage)
[email protected]f09c7182009-03-10 12:54:04391 IPC_MESSAGE_HANDLER(
392 ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,
393 OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)
initial.commit09911bf2008-07-26 23:55:29394 IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)
[email protected]266eb6f2008-09-30 23:56:50395 IPC_MESSAGE_HANDLER(ViewMsg_GetAccessibilityInfo, OnGetAccessibilityInfo)
396 IPC_MESSAGE_HANDLER(ViewMsg_ClearAccessibilityInfo,
397 OnClearAccessibilityInfo)
initial.commit09911bf2008-07-26 23:55:29398 IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose)
399 IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
400 IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)
[email protected]18cb2572008-08-21 20:34:45401 IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,
402 OnMessageFromExternalHost)
[email protected]0aa55312008-10-17 21:53:08403 IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
404 OnDisassociateFromPopupCount)
[email protected]0ebf3872008-11-07 21:35:03405 IPC_MESSAGE_HANDLER(ViewMsg_AutofillSuggestions,
406 OnReceivedAutofillSuggestions)
[email protected]2c4410d2009-05-06 23:46:22407 IPC_MESSAGE_HANDLER(ViewMsg_PopupNotificationVisibilityChanged,
408 OnPopupNotificationVisibilityChanged)
[email protected]30f75e62009-02-25 22:01:00409 IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
[email protected]309d7a282009-03-24 09:18:27410 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionResponse, OnExtensionResponse)
[email protected]05d478752009-04-08 23:38:16411 IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
[email protected]699ab0d2009-04-23 23:19:14412 IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
[email protected]0666aef2009-05-13 19:48:08413 IPC_MESSAGE_HANDLER(ViewMsg_EnableIntrinsicWidthChangedMode,
414 OnEnableIntrinsicWidthChangedMode)
[email protected]80d96fa2009-06-10 22:34:51415 IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
[email protected]634a6f92008-12-01 21:39:31416
initial.commit09911bf2008-07-26 23:55:29417 // Have the super handle all other messages.
418 IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))
419 IPC_END_MESSAGE_MAP()
420}
421
initial.commit09911bf2008-07-26 23:55:29422void RenderView::SendThumbnail() {
423 WebFrame* main_frame = webview()->GetMainFrame();
424 if (!main_frame)
425 return;
426
427 // get the URL for this page
428 GURL url(main_frame->GetURL());
429 if (url.is_empty())
430 return;
431
432 if (size_.IsEmpty())
433 return; // Don't create an empty thumbnail!
434
435 ThumbnailScore score;
436 SkBitmap thumbnail;
[email protected]8649fb32009-06-26 17:51:02437 if (!CaptureThumbnail(webview(), kThumbnailWidth, kThumbnailHeight,
[email protected]b6e4bec2008-11-12 01:17:15438 &thumbnail, &score))
439 return;
440
initial.commit09911bf2008-07-26 23:55:29441 // send the thumbnail message to the browser process
[email protected]674741932009-02-04 23:44:46442 Send(new ViewHostMsg_Thumbnail(routing_id_, url, score, thumbnail));
initial.commit09911bf2008-07-26 23:55:29443}
444
[email protected]068637222009-01-29 16:58:07445void RenderView::OnPrintPages() {
initial.commit09911bf2008-07-26 23:55:29446 DCHECK(webview());
[email protected]0fda7272009-06-26 15:49:33447 if (webview())
448 Print(webview()->GetMainFrame(), false);
initial.commit09911bf2008-07-26 23:55:29449}
450
[email protected]82270452009-06-19 15:58:01451void RenderView::OnPrintingDone(int document_cookie, bool success) {
452 // Ignoring document cookie here since only one print job can be outstanding
453 // per renderer and document_cookie is 0 when printing is successful.
454 DCHECK(print_helper_.get());
455 if (print_helper_.get() != NULL) {
456 print_helper_->DidFinishPrinting(success);
457 }
458}
459
initial.commit09911bf2008-07-26 23:55:29460void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) {
461 if (load_id != page_id_)
462 return; // this capture call is no longer relevant due to navigation
463 if (load_id == last_indexed_page_id_)
464 return; // we already indexed this page
465
466 if (!webview())
467 return;
468
469 WebFrame* main_frame = webview()->GetMainFrame();
470 if (!main_frame)
471 return;
472
473 // Don't index/capture pages that are in view source mode.
474 if (main_frame->GetInViewSourceMode())
475 return;
476
477 // Don't index/capture pages that failed to load. This only checks the top
478 // level frame so the thumbnail may contain a frame that failed to load.
479 WebDataSource* ds = main_frame->GetDataSource();
[email protected]726985e22009-06-18 21:09:28480 if (ds && ds->hasUnreachableURL())
initial.commit09911bf2008-07-26 23:55:29481 return;
482
483 if (!preliminary_capture)
484 last_indexed_page_id_ = load_id;
485
486 // get the URL for this page
487 GURL url(main_frame->GetURL());
488 if (url.is_empty())
489 return;
490
491 // full text
492 std::wstring contents;
493 CaptureText(main_frame, &contents);
494 if (contents.size()) {
495 // Send the text to the browser for indexing.
496 Send(new ViewHostMsg_PageContents(url, load_id, contents));
497 }
498
499 // thumbnail
500 SendThumbnail();
501}
502
503void RenderView::CaptureText(WebFrame* frame, std::wstring* contents) {
504 contents->clear();
505 if (!frame)
506 return;
507
[email protected]0faf0bd92008-09-09 20:53:27508 // Don't index any https pages. People generally don't want their bank
509 // accounts, etc. indexed on their computer, especially since some of these
510 // things are not marked cachable.
511 // TODO(brettw) we may want to consider more elaborate heuristics such as
512 // the cachability of the page. We may also want to consider subframes (this
513 // test will still index subframes if the subframe is SSL).
514 if (frame->GetURL().SchemeIsSecure())
515 return;
516
initial.commit09911bf2008-07-26 23:55:29517#ifdef TIME_TEXT_RETRIEVAL
518 double begin = time_util::GetHighResolutionTimeNow();
519#endif
520
521 // get the contents of the frame
522 frame->GetContentAsPlainText(kMaxIndexChars, contents);
523
524#ifdef TIME_TEXT_RETRIEVAL
525 double end = time_util::GetHighResolutionTimeNow();
526 char buf[128];
527 sprintf_s(buf, "%d chars retrieved for indexing in %gms\n",
528 contents.size(), (end - begin)*1000);
529 OutputDebugStringA(buf);
530#endif
531
532 // When the contents are clipped to the maximum, we don't want to have a
533 // partial word indexed at the end that might have been clipped. Therefore,
534 // terminate the string at the last space to ensure no words are clipped.
535 if (contents->size() == kMaxIndexChars) {
536 size_t last_space_index = contents->find_last_of(kWhitespaceWide);
537 if (last_space_index == std::wstring::npos)
538 return; // don't index if we got a huge block of text with no spaces
539 contents->resize(last_space_index);
540 }
541}
542
[email protected]8649fb32009-06-26 17:51:02543bool RenderView::CaptureThumbnail(WebView* view,
initial.commit09911bf2008-07-26 23:55:29544 int w,
545 int h,
546 SkBitmap* thumbnail,
547 ThumbnailScore* score) {
548#ifdef TIME_BITMAP_RETRIEVAL
549 double begin = time_util::GetHighResolutionTimeNow();
550#endif
551
[email protected]8649fb32009-06-26 17:51:02552 view->Layout();
553 const WebSize& size = view->GetSize();
[email protected]b6e4bec2008-11-12 01:17:15554
[email protected]8649fb32009-06-26 17:51:02555 skia::PlatformCanvas canvas;
556 if (!canvas.initialize(size.width, size.height, true))
557 return false;
558 view->Paint(&canvas, WebRect(0, 0, size.width, size.height));
559
560 skia::BitmapPlatformDevice& device =
561 static_cast<skia::BitmapPlatformDevice&>(canvas.getTopPlatformDevice());
562
563 const SkBitmap& src_bmp = device.accessBitmap(false);
initial.commit09911bf2008-07-26 23:55:29564
565 SkRect dest_rect;
566 dest_rect.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
567 float dest_aspect = dest_rect.width() / dest_rect.height();
568
569 // Get the src rect so that we can preserve the aspect ratio while filling
570 // the destination.
571 SkIRect src_rect;
572 if (src_bmp.width() < dest_rect.width() ||
573 src_bmp.height() < dest_rect.height()) {
574 // Source image is smaller: we clip the part of source image within the
575 // dest rect, and then stretch it to fill the dest rect. We don't respect
576 // the aspect ratio in this case.
577 src_rect.set(0, 0, static_cast<S16CPU>(dest_rect.width()),
578 static_cast<S16CPU>(dest_rect.height()));
579 score->good_clipping = false;
580 } else {
581 float src_aspect = static_cast<float>(src_bmp.width()) / src_bmp.height();
582 if (src_aspect > dest_aspect) {
583 // Wider than tall, clip horizontally: we center the smaller thumbnail in
584 // the wider screen.
585 S16CPU new_width = static_cast<S16CPU>(src_bmp.height() * dest_aspect);
586 S16CPU x_offset = (src_bmp.width() - new_width) / 2;
587 src_rect.set(x_offset, 0, new_width + x_offset, src_bmp.height());
588 score->good_clipping = false;
589 } else {
590 src_rect.set(0, 0, src_bmp.width(),
591 static_cast<S16CPU>(src_bmp.width() / dest_aspect));
592 score->good_clipping = true;
593 }
594 }
595
[email protected]8649fb32009-06-26 17:51:02596 score->at_top = (view->GetMainFrame()->ScrollOffset().height == 0);
initial.commit09911bf2008-07-26 23:55:29597
598 SkBitmap subset;
[email protected]8649fb32009-06-26 17:51:02599 device.accessBitmap(false).extractSubset(&subset, src_rect);
initial.commit09911bf2008-07-26 23:55:29600
601 // Resample the subset that we want to get it the right size.
[email protected]465b34b72008-12-12 20:19:14602 *thumbnail = skia::ImageOperations::Resize(
603 subset, skia::ImageOperations::RESIZE_LANCZOS3, w, h);
initial.commit09911bf2008-07-26 23:55:29604
605 score->boring_score = CalculateBoringScore(thumbnail);
606
607#ifdef TIME_BITMAP_RETRIEVAL
608 double end = time_util::GetHighResolutionTimeNow();
609 char buf[128];
610 sprintf_s(buf, "thumbnail in %gms\n", (end - begin) * 1000);
611 OutputDebugStringA(buf);
612#endif
[email protected]b6e4bec2008-11-12 01:17:15613 return true;
initial.commit09911bf2008-07-26 23:55:29614}
615
616double RenderView::CalculateBoringScore(SkBitmap* bitmap) {
617 int histogram[256] = {0};
618 color_utils::BuildLumaHistogram(bitmap, histogram);
619
620 int color_count = *std::max_element(histogram, histogram + 256);
621 int pixel_count = bitmap->width() * bitmap->height();
622 return static_cast<double>(color_count) / pixel_count;
623}
624
625void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {
626 if (!webview())
627 return;
628
[email protected]f8b6b6f2009-03-10 16:48:26629 renderer_logging::ScopedActiveRenderingURLSetter url_setter(params.url);
[email protected]f8b6b6f2009-03-10 16:48:26630
initial.commit09911bf2008-07-26 23:55:29631 AboutHandler::MaybeHandle(params.url);
632
633 bool is_reload = params.reload;
634
635 WebFrame* main_frame = webview()->GetMainFrame();
[email protected]ca948a22009-06-25 19:36:17636 if (is_reload && main_frame->GetCurrentHistoryItem().isNull()) {
initial.commit09911bf2008-07-26 23:55:29637 // We cannot reload if we do not have any history state. This happens, for
638 // example, when recovering from a crash. Our workaround here is a bit of
639 // a hack since it means that reload after a crashed tab does not cause an
640 // end-to-end cache validation.
641 is_reload = false;
642 }
643
[email protected]77f17a82009-05-21 04:42:54644 // A navigation resulting from loading a javascript URL should not be treated
645 // as a browser initiated event. Instead, we want it to look as if the page
646 // initiated any load resulting from JS execution.
647 if (!params.url.SchemeIs(chrome::kJavaScriptScheme)) {
[email protected]daa8c58e2009-06-15 17:21:10648 pending_navigation_state_.reset(NavigationState::CreateBrowserInitiated(
[email protected]77f17a82009-05-21 04:42:54649 params.page_id, params.transition, params.request_time));
650 }
initial.commit09911bf2008-07-26 23:55:29651
[email protected]04d3c6e2009-05-22 17:00:13652 // If we are reloading, then WebKit will use the history state of the current
653 // page, so we should just ignore any given history state. Otherwise, if we
654 // have history state, then we need to navigate to it, which corresponds to a
655 // back/forward navigation event.
[email protected]e6f546c32009-07-01 17:12:55656 if (is_reload) {
657 main_frame->Reload();
658 } else if (!params.state.empty()) {
[email protected]04d3c6e2009-05-22 17:00:13659 // We must know the page ID of the page we are navigating back to.
[email protected]f929f2f22009-06-12 16:56:58660 DCHECK_NE(params.page_id, -1);
[email protected]ca948a22009-06-25 19:36:17661 main_frame->LoadHistoryItem(
662 webkit_glue::HistoryItemFromString(params.state));
[email protected]04d3c6e2009-05-22 17:00:13663 } else {
664 // Navigate to the given URL.
[email protected]726985e22009-06-18 21:09:28665 WebURLRequest request(params.url);
initial.commit09911bf2008-07-26 23:55:29666
[email protected]e6f546c32009-07-01 17:12:55667 // A session history navigation should have been accompanied by state.
668 DCHECK_EQ(params.page_id, -1);
[email protected]04d3c6e2009-05-22 17:00:13669
[email protected]e6f546c32009-07-01 17:12:55670 if (main_frame->GetInViewSourceMode())
671 request.setCachePolicy(WebURLRequest::ReturnCacheDataElseLoad);
[email protected]04d3c6e2009-05-22 17:00:13672
[email protected]726985e22009-06-18 21:09:28673 if (params.referrer.is_valid()) {
674 request.setHTTPHeaderField(WebString::fromUTF8("Referer"),
675 WebString::fromUTF8(params.referrer.spec()));
676 }
[email protected]04d3c6e2009-05-22 17:00:13677
[email protected]726985e22009-06-18 21:09:28678 main_frame->LoadRequest(request);
[email protected]c0588052008-10-27 23:01:50679 }
680
[email protected]77f17a82009-05-21 04:42:54681 // In case LoadRequest failed before DidCreateDataSource was called.
682 pending_navigation_state_.reset();
initial.commit09911bf2008-07-26 23:55:29683}
684
685// Stop loading the current page
686void RenderView::OnStop() {
687 if (webview())
688 webview()->StopLoading();
689}
690
[email protected]e6f546c32009-07-01 17:12:55691void RenderView::OnLoadAlternateHTMLText(const std::string& html,
initial.commit09911bf2008-07-26 23:55:29692 bool new_navigation,
693 const GURL& display_url,
694 const std::string& security_info) {
695 if (!webview())
696 return;
697
[email protected]e6f546c32009-07-01 17:12:55698 pending_navigation_state_.reset(NavigationState::CreateBrowserInitiated(
699 new_navigation ? -1 : page_id_, PageTransition::LINK, Time::Now()));
700 pending_navigation_state_->set_security_info(security_info);
initial.commit09911bf2008-07-26 23:55:29701
[email protected]e6f546c32009-07-01 17:12:55702 webview()->GetMainFrame()->LoadHTMLString(html,
703 GURL(kUnreachableWebDataURL),
704 display_url,
705 !new_navigation);
706
707 pending_navigation_state_.reset();
initial.commit09911bf2008-07-26 23:55:29708}
709
710void RenderView::OnCopyImageAt(int x, int y) {
711 webview()->CopyImageAt(x, y);
712}
713
[email protected]68b1e922009-06-23 16:00:25714void RenderView::OnExecuteEditCommand(const std::string& name,
715 const std::string& value) {
716 if (!webview() || !webview()->GetFocusedFrame())
717 return;
718
[email protected]4b59ae602009-06-23 20:58:15719 webview()->GetFocusedFrame()->ExecuteEditCommandByName(name, value);
[email protected]68b1e922009-06-23 16:00:25720}
721
[email protected]b2abac72009-02-26 12:39:28722void RenderView::OnSetupDevToolsClient() {
[email protected]e4ac5df2009-03-17 15:33:11723 DCHECK(!devtools_client_.get());
724 devtools_client_.reset(new DevToolsClient(this));
[email protected]b2abac72009-02-26 12:39:28725}
726
initial.commit09911bf2008-07-26 23:55:29727void RenderView::OnStopFinding(bool clear_selection) {
728 WebView* view = webview();
729 if (!view)
730 return;
731
732 if (clear_selection)
733 view->GetFocusedFrame()->ClearSelection();
734
735 WebFrame* frame = view->GetMainFrame();
736 while (frame) {
[email protected]65134c432008-09-26 21:47:20737 frame->StopFinding(clear_selection);
initial.commit09911bf2008-07-26 23:55:29738 frame = view->GetNextFrameAfter(frame, false);
739 }
740}
741
742void RenderView::OnFindReplyAck() {
743 // Check if there is any queued up request waiting to be sent.
744 if (queued_find_reply_message_.get()) {
745 // Send the search result over to the browser process.
746 Send(queued_find_reply_message_.get());
747 queued_find_reply_message_.release();
748 }
749}
750
751void RenderView::OnUpdateTargetURLAck() {
752 // Check if there is a targeturl waiting to be sent.
753 if (target_url_status_ == TARGET_PENDING) {
754 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_,
755 pending_target_url_));
756 }
757
758 target_url_status_ = TARGET_NONE;
759}
760
761void RenderView::OnUndo() {
762 if (!webview())
763 return;
764
765 webview()->GetFocusedFrame()->Undo();
766}
767
768void RenderView::OnRedo() {
769 if (!webview())
770 return;
771
772 webview()->GetFocusedFrame()->Redo();
773}
774
775void RenderView::OnCut() {
776 if (!webview())
777 return;
778
779 webview()->GetFocusedFrame()->Cut();
780}
781
782void RenderView::OnCopy() {
783 if (!webview())
784 return;
785
786 webview()->GetFocusedFrame()->Copy();
787}
788
789void RenderView::OnPaste() {
790 if (!webview())
791 return;
792
793 webview()->GetFocusedFrame()->Paste();
794}
795
796void RenderView::OnReplace(const std::wstring& text) {
797 if (!webview())
798 return;
799
800 webview()->GetFocusedFrame()->Replace(text);
801}
802
[email protected]bbbd545c2008-12-15 20:18:04803void RenderView::OnToggleSpellCheck() {
804 if (!webview())
805 return;
806
807 webview()->GetFocusedFrame()->ToggleSpellCheck();
808}
809
initial.commit09911bf2008-07-26 23:55:29810void RenderView::OnDelete() {
811 if (!webview())
812 return;
813
814 webview()->GetFocusedFrame()->Delete();
815}
816
817void RenderView::OnSelectAll() {
818 if (!webview())
819 return;
820
821 webview()->GetFocusedFrame()->SelectAll();
822}
823
824void RenderView::OnSetInitialFocus(bool reverse) {
825 if (!webview())
826 return;
827 webview()->SetInitialFocus(reverse);
828}
829
830///////////////////////////////////////////////////////////////////////////////
831
832// Tell the embedding application that the URL of the active page has changed
833void RenderView::UpdateURL(WebFrame* frame) {
834 WebDataSource* ds = frame->GetDataSource();
835 DCHECK(ds);
836
[email protected]726985e22009-06-18 21:09:28837 const WebURLRequest& request = ds->request();
838 const WebURLRequest& original_request = ds->originalRequest();
839 const WebURLResponse& response = ds->response();
initial.commit09911bf2008-07-26 23:55:29840
[email protected]daa8c58e2009-06-15 17:21:10841 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
842 DCHECK(navigation_state);
initial.commit09911bf2008-07-26 23:55:29843
844 ViewHostMsg_FrameNavigate_Params params;
[email protected]726985e22009-06-18 21:09:28845 params.http_status_code = response.httpStatusCode();
initial.commit09911bf2008-07-26 23:55:29846 params.is_post = false;
847 params.page_id = page_id_;
[email protected]726985e22009-06-18 21:09:28848 params.is_content_filtered = response.isContentFiltered();
[email protected]e6f546c32009-07-01 17:12:55849 if (!navigation_state->security_info().empty()) {
initial.commit09911bf2008-07-26 23:55:29850 // SSL state specified in the request takes precedence over the one in the
851 // response.
852 // So far this is only intended for error pages that are not expected to be
853 // over ssl, so we should not get any clash.
[email protected]726985e22009-06-18 21:09:28854 DCHECK(response.securityInfo().isEmpty());
[email protected]e6f546c32009-07-01 17:12:55855 params.security_info = navigation_state->security_info();
initial.commit09911bf2008-07-26 23:55:29856 } else {
[email protected]726985e22009-06-18 21:09:28857 params.security_info = response.securityInfo();
initial.commit09911bf2008-07-26 23:55:29858 }
859
860 // Set the URL to be displayed in the browser UI to the user.
[email protected]726985e22009-06-18 21:09:28861 if (ds->hasUnreachableURL()) {
862 params.url = ds->unreachableURL();
initial.commit09911bf2008-07-26 23:55:29863 } else {
[email protected]726985e22009-06-18 21:09:28864 params.url = request.url();
initial.commit09911bf2008-07-26 23:55:29865 }
866
[email protected]726985e22009-06-18 21:09:28867 GetRedirectChain(ds, &params.redirects);
868 params.should_update_history = !ds->hasUnreachableURL();
initial.commit09911bf2008-07-26 23:55:29869
870 const SearchableFormData* searchable_form_data =
[email protected]daa8c58e2009-06-15 17:21:10871 navigation_state->searchable_form_data();
initial.commit09911bf2008-07-26 23:55:29872 if (searchable_form_data) {
873 params.searchable_form_url = searchable_form_data->url();
874 params.searchable_form_element_name = searchable_form_data->element_name();
875 params.searchable_form_encoding = searchable_form_data->encoding();
876 }
877
878 const PasswordForm* password_form_data =
[email protected]daa8c58e2009-06-15 17:21:10879 navigation_state->password_form_data();
initial.commit09911bf2008-07-26 23:55:29880 if (password_form_data)
881 params.password_form = *password_form_data;
882
883 params.gesture = navigation_gesture_;
884 navigation_gesture_ = NavigationGestureUnknown;
885
[email protected]77f17a82009-05-21 04:42:54886 if (!frame->GetParent()) {
initial.commit09911bf2008-07-26 23:55:29887 // Top-level navigation.
888
889 // Update contents MIME type for main frame.
[email protected]726985e22009-06-18 21:09:28890 params.contents_mime_type = UTF16ToUTF8(ds->response().mimeType());
initial.commit09911bf2008-07-26 23:55:29891
[email protected]daa8c58e2009-06-15 17:21:10892 params.transition = navigation_state->transition_type();
initial.commit09911bf2008-07-26 23:55:29893 if (!PageTransition::IsMainFrame(params.transition)) {
894 // If the main frame does a load, it should not be reported as a subframe
895 // navigation. This can occur in the following case:
896 // 1. You're on a site with frames.
897 // 2. You do a subframe navigation. This is stored with transition type
898 // MANUAL_SUBFRAME.
899 // 3. You navigate to some non-frame site, say, google.com.
900 // 4. You navigate back to the page from step 2. Since it was initially
901 // MANUAL_SUBFRAME, it will be that same transition type here.
902 // We don't want that, because any navigation that changes the toplevel
903 // frame should be tracked as a toplevel navigation (this allows us to
904 // update the URL bar, etc).
905 params.transition = PageTransition::LINK;
906 }
907
initial.commit09911bf2008-07-26 23:55:29908 // If we have a valid consumed client redirect source,
909 // the page contained a client redirect (meta refresh, document.loc...),
910 // so we set the referrer and transition to match.
911 if (completed_client_redirect_src_.is_valid()) {
[email protected]77e09a92008-08-01 18:11:04912 DCHECK(completed_client_redirect_src_ == params.redirects[0]);
initial.commit09911bf2008-07-26 23:55:29913 params.referrer = completed_client_redirect_src_;
914 params.transition = static_cast<PageTransition::Type>(
915 params.transition | PageTransition::CLIENT_REDIRECT);
916 } else {
917 // Bug 654101: the referrer will be empty on https->http transitions. It
918 // would be nice if we could get the real referrer from somewhere.
[email protected]726985e22009-06-18 21:09:28919 params.referrer = GURL(
920 original_request.httpHeaderField(WebString::fromUTF8("Referer")));
initial.commit09911bf2008-07-26 23:55:29921 }
922
[email protected]726985e22009-06-18 21:09:28923 string16 method = request.httpMethod();
924 if (EqualsASCII(method, "POST"))
initial.commit09911bf2008-07-26 23:55:29925 params.is_post = true;
926
927 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
928 } else {
929 // Subframe navigation: the type depends on whether this navigation
930 // generated a new session history entry. When they do generate a session
931 // history entry, it means the user initiated the navigation and we should
932 // mark it as such. This test checks if this is the first time UpdateURL
933 // has been called since WillNavigateToURL was called to initiate the load.
934 if (page_id_ > last_page_id_sent_to_browser_)
935 params.transition = PageTransition::MANUAL_SUBFRAME;
936 else
937 params.transition = PageTransition::AUTO_SUBFRAME;
938
initial.commit09911bf2008-07-26 23:55:29939 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
940 }
941
942 last_page_id_sent_to_browser_ =
943 std::max(last_page_id_sent_to_browser_, page_id_);
944
945 // If we end up reusing this WebRequest (for example, due to a #ref click),
[email protected]daa8c58e2009-06-15 17:21:10946 // we don't want the transition type to persist. Just clear it.
947 navigation_state->set_transition_type(PageTransition::LINK);
[email protected]266eb6f2008-09-30 23:56:50948
[email protected]6c8afae52009-01-22 02:24:57949#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:25950 if (web_accessibility_manager_.get()) {
[email protected]be645db2009-02-06 20:36:33951 // Clear accessibility info cache.
[email protected]6a983b42009-03-20 20:12:25952 web_accessibility_manager_->ClearAccObjMap(-1, true);
[email protected]266eb6f2008-09-30 23:56:50953 }
[email protected]6c8afae52009-01-22 02:24:57954#else
[email protected]7d926f92009-03-03 14:26:54955 // TODO(port): accessibility not yet implemented. See http://crbug.com/8288.
[email protected]6c8afae52009-01-22 02:24:57956#endif
initial.commit09911bf2008-07-26 23:55:29957}
958
959// Tell the embedding application that the title of the active page has changed
960void RenderView::UpdateTitle(WebFrame* frame, const std::wstring& title) {
961 // Ignore all but top level navigations...
[email protected]f0af6a72009-05-30 05:25:17962 if (webview()->GetMainFrame() == frame) {
963 Send(new ViewHostMsg_UpdateTitle(
964 routing_id_,
965 page_id_,
966 title.length() > chrome::kMaxTitleChars ?
967 title.substr(0, chrome::kMaxTitleChars) : title));
968 }
initial.commit09911bf2008-07-26 23:55:29969}
970
971void RenderView::UpdateEncoding(WebFrame* frame,
[email protected]e38f40152008-09-12 23:08:30972 const std::wstring& encoding_name) {
initial.commit09911bf2008-07-26 23:55:29973 // Only update main frame's encoding_name.
974 if (webview()->GetMainFrame() == frame &&
975 last_encoding_name_ != encoding_name) {
[email protected]e38f40152008-09-12 23:08:30976 // Save the encoding name for later comparing.
initial.commit09911bf2008-07-26 23:55:29977 last_encoding_name_ = encoding_name;
978
[email protected]e38f40152008-09-12 23:08:30979 Send(new ViewHostMsg_UpdateEncoding(routing_id_, last_encoding_name_));
initial.commit09911bf2008-07-26 23:55:29980 }
981}
982
[email protected]f4d34b52008-11-24 23:05:01983// Sends the previous session history state to the browser so it will be saved
984// before we navigate to a new page. This must be called *before* the page ID
985// has been updated so we know what it was.
initial.commit09911bf2008-07-26 23:55:29986void RenderView::UpdateSessionHistory(WebFrame* frame) {
987 // If we have a valid page ID at this point, then it corresponds to the page
988 // we are navigating away from. Otherwise, this is the first navigation, so
989 // there is no past session history to record.
990 if (page_id_ == -1)
991 return;
992
[email protected]ca948a22009-06-25 19:36:17993 const WebHistoryItem& item =
994 webview()->GetMainFrame()->GetPreviousHistoryItem();
995 if (item.isNull())
initial.commit09911bf2008-07-26 23:55:29996 return;
[email protected]ca948a22009-06-25 19:36:17997
998 Send(new ViewHostMsg_UpdateState(
999 routing_id_, page_id_, webkit_glue::HistoryItemToString(item)));
initial.commit09911bf2008-07-26 23:55:291000}
1001
1002///////////////////////////////////////////////////////////////////////////////
1003// WebViewDelegate
1004
[email protected]80d96fa2009-06-10 22:34:511005bool RenderView::CanAcceptLoadDrops() const {
1006 return renderer_preferences_.can_accept_load_drops;
1007}
1008
initial.commit09911bf2008-07-26 23:55:291009void RenderView::DidStartLoading(WebView* webview) {
1010 if (is_loading_) {
1011 DLOG(WARNING) << "DidStartLoading called while loading";
1012 return;
1013 }
1014
1015 is_loading_ = true;
1016 // Clear the pointer so that we can assign it only when there is an unknown
1017 // plugin on a page.
1018 first_default_plugin_ = NULL;
1019
[email protected]329581b2009-04-28 06:52:351020 Send(new ViewHostMsg_DidStartLoading(routing_id_));
initial.commit09911bf2008-07-26 23:55:291021}
1022
1023void RenderView::DidStopLoading(WebView* webview) {
1024 if (!is_loading_) {
1025 DLOG(WARNING) << "DidStopLoading called while not loading";
1026 return;
1027 }
1028
1029 is_loading_ = false;
1030
1031 // NOTE: For now we're doing the safest thing, and sending out notification
1032 // when done loading. This currently isn't an issue as the favicon is only
1033 // displayed when done loading. Ideally we would send notification when
1034 // finished parsing the head, but webkit doesn't support that yet.
1035 // The feed discovery code would also benefit from access to the head.
1036 GURL favicon_url(webview->GetMainFrame()->GetFavIconURL());
1037 if (!favicon_url.is_empty())
1038 Send(new ViewHostMsg_UpdateFavIconURL(routing_id_, page_id_, favicon_url));
1039
1040 AddGURLSearchProvider(webview->GetMainFrame()->GetOSDDURL(),
1041 true); // autodetected
1042
[email protected]329581b2009-04-28 06:52:351043 Send(new ViewHostMsg_DidStopLoading(routing_id_));
initial.commit09911bf2008-07-26 23:55:291044
1045 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1046 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo, page_id_,
1047 false),
1048 kDelayForCaptureMs);
1049
1050 // The page is loaded. Try to process the file we need to upload if any.
1051 ProcessPendingUpload();
1052
1053 // Since the page is done loading, we are sure we don't need to try
1054 // again.
1055 ResetPendingUpload();
1056}
1057
[email protected]77f17a82009-05-21 04:42:541058void RenderView::DidCreateDataSource(WebFrame* frame, WebDataSource* ds) {
[email protected]daa8c58e2009-06-15 17:21:101059 // The rest of RenderView assumes that a WebDataSource will always have a
1060 // non-null NavigationState.
1061 if (pending_navigation_state_.get()) {
[email protected]726985e22009-06-18 21:09:281062 ds->setExtraData(pending_navigation_state_.release());
[email protected]daa8c58e2009-06-15 17:21:101063 } else {
[email protected]726985e22009-06-18 21:09:281064 ds->setExtraData(NavigationState::CreateContentInitiated());
[email protected]daa8c58e2009-06-15 17:21:101065 }
[email protected]77f17a82009-05-21 04:42:541066}
1067
[email protected]a2f6bc112009-06-27 16:27:251068void RenderView::DidPaint() {
1069 WebFrame* main_frame = webview()->GetMainFrame();
1070
1071 if (main_frame->GetProvisionalDataSource()) {
1072 // If we have a provisional frame we are between the start
1073 // and commit stages of loading...ignore this paint.
1074 return;
1075 }
1076
1077 WebDataSource* ds = main_frame->GetDataSource();
1078 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
1079 // TODO(darin): It should not be possible for navigation_state to
1080 // be null here! But the UI test DownloadTest.IncognitoDownload
1081 // can cause it to happen.
[email protected]7a9b51f2009-06-29 21:28:291082 if (navigation_state) {
1083 Time now = Time::Now();
1084 if (navigation_state->first_paint_time().is_null()) {
1085 navigation_state->set_first_paint_time(now);
1086 }
1087 if (navigation_state->first_paint_after_load_time().is_null() &&
1088 !navigation_state->finish_load_time().is_null()) {
1089 navigation_state->set_first_paint_after_load_time(now);
1090 }
[email protected]a2f6bc112009-06-27 16:27:251091 }
1092}
1093
initial.commit09911bf2008-07-26 23:55:291094void RenderView::DidStartProvisionalLoadForFrame(
1095 WebView* webview,
1096 WebFrame* frame,
1097 NavigationGesture gesture) {
[email protected]ed3fb032009-06-16 19:50:561098 WebDataSource* ds = frame->GetProvisionalDataSource();
1099 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
1100
1101 navigation_state->set_start_load_time(Time::Now());
1102
1103 // Update the request time if WebKit has better knowledge of it.
1104 if (navigation_state->request_time().is_null()) {
[email protected]726985e22009-06-18 21:09:281105 double event_time = ds->triggeringEventTime();
[email protected]ed3fb032009-06-16 19:50:561106 if (event_time != 0.0)
1107 navigation_state->set_request_time(Time::FromDoubleT(event_time));
1108 }
1109
1110 bool is_top_most = !frame->GetParent();
1111 if (is_top_most) {
initial.commit09911bf2008-07-26 23:55:291112 navigation_gesture_ = gesture;
[email protected]266eb6f2008-09-30 23:56:501113
[email protected]77e09a92008-08-01 18:11:041114 // Make sure redirect tracking state is clear for the new load.
1115 completed_client_redirect_src_ = GURL();
1116 }
initial.commit09911bf2008-07-26 23:55:291117
1118 Send(new ViewHostMsg_DidStartProvisionalLoadForFrame(
[email protected]726985e22009-06-18 21:09:281119 routing_id_, is_top_most, ds->request().url()));
initial.commit09911bf2008-07-26 23:55:291120}
1121
1122bool RenderView::DidLoadResourceFromMemoryCache(WebView* webview,
[email protected]726985e22009-06-18 21:09:281123 const WebURLRequest& request,
1124 const WebURLResponse& response,
initial.commit09911bf2008-07-26 23:55:291125 WebFrame* frame) {
1126 // Let the browser know we loaded a resource from the memory cache. This
1127 // message is needed to display the correct SSL indicators.
1128 Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(routing_id_,
[email protected]726985e22009-06-18 21:09:281129 request.url(), frame->GetSecurityOrigin(),
[email protected]ffc45862009-03-17 06:11:081130 frame->GetTop()->GetSecurityOrigin(),
[email protected]726985e22009-06-18 21:09:281131 response.securityInfo()));
initial.commit09911bf2008-07-26 23:55:291132
1133 return false;
1134}
1135
1136void RenderView::DidReceiveProvisionalLoadServerRedirect(WebView* webview,
1137 WebFrame* frame) {
1138 if (frame == webview->GetMainFrame()) {
1139 // Received a redirect on the main frame.
1140 WebDataSource* data_source =
1141 webview->GetMainFrame()->GetProvisionalDataSource();
1142 if (!data_source) {
1143 // Should only be invoked when we have a data source.
1144 NOTREACHED();
1145 return;
1146 }
[email protected]726985e22009-06-18 21:09:281147 std::vector<GURL> redirects;
1148 GetRedirectChain(data_source, &redirects);
initial.commit09911bf2008-07-26 23:55:291149 if (redirects.size() >= 2) {
1150 Send(new ViewHostMsg_DidRedirectProvisionalLoad(
1151 routing_id_, page_id_, redirects[redirects.size() - 2],
1152 redirects[redirects.size() - 1]));
1153 }
1154 }
1155}
1156
1157void RenderView::DidFailProvisionalLoadWithError(WebView* webview,
[email protected]726985e22009-06-18 21:09:281158 const WebURLError& error,
initial.commit09911bf2008-07-26 23:55:291159 WebFrame* frame) {
1160 // Notify the browser that we failed a provisional load with an error.
1161 //
1162 // Note: It is important this notification occur before DidStopLoading so the
1163 // SSL manager can react to the provisional load failure before being
1164 // notified the load stopped.
1165 //
1166 WebDataSource* ds = frame->GetProvisionalDataSource();
1167 DCHECK(ds);
1168
[email protected]726985e22009-06-18 21:09:281169 const WebURLRequest& failed_request = ds->request();
initial.commit09911bf2008-07-26 23:55:291170
1171 bool show_repost_interstitial =
[email protected]726985e22009-06-18 21:09:281172 (error.reason == net::ERR_CACHE_MISS &&
1173 EqualsASCII(failed_request.httpMethod(), "POST"));
initial.commit09911bf2008-07-26 23:55:291174 Send(new ViewHostMsg_DidFailProvisionalLoadWithError(
[email protected]726985e22009-06-18 21:09:281175 routing_id_, !frame->GetParent(),
1176 error.reason, error.unreachableURL,
initial.commit09911bf2008-07-26 23:55:291177 show_repost_interstitial));
1178
initial.commit09911bf2008-07-26 23:55:291179 // Don't display an error page if this is simply a cancelled load. Aside
1180 // from being dumb, WebCore doesn't expect it and it will cause a crash.
[email protected]726985e22009-06-18 21:09:281181 if (error.reason == net::ERR_ABORTED)
initial.commit09911bf2008-07-26 23:55:291182 return;
1183
[email protected]546ddd172009-06-25 00:25:011184 // Make sure we never show errors in view source mode.
1185 frame->SetInViewSourceMode(false);
1186
initial.commit09911bf2008-07-26 23:55:291187 // If this is a failed back/forward/reload navigation, then we need to do a
1188 // 'replace' load. This is necessary to avoid messing up session history.
1189 // Otherwise, we do a normal load, which simulates a 'go' navigation as far
1190 // as session history is concerned.
[email protected]daa8c58e2009-06-15 17:21:101191 bool replace = !NavigationState::FromDataSource(ds)->is_new_navigation();
initial.commit09911bf2008-07-26 23:55:291192
[email protected]5df266ac2008-10-15 19:50:131193 // Use the alternate error page service if this is a DNS failure or
1194 // connection failure. ERR_CONNECTION_FAILED can be dropped once we no longer
1195 // use winhttp.
[email protected]726985e22009-06-18 21:09:281196 int ec = error.reason;
[email protected]5df266ac2008-10-15 19:50:131197 if (ec == net::ERR_NAME_NOT_RESOLVED ||
1198 ec == net::ERR_CONNECTION_FAILED ||
1199 ec == net::ERR_CONNECTION_REFUSED ||
1200 ec == net::ERR_ADDRESS_UNREACHABLE ||
1201 ec == net::ERR_TIMED_OUT) {
[email protected]726985e22009-06-18 21:09:281202 const GURL& failed_url = error.unreachableURL;
[email protected]5df266ac2008-10-15 19:50:131203 const GURL& error_page_url = GetAlternateErrorPageURL(failed_url,
1204 ec == net::ERR_NAME_NOT_RESOLVED ? WebViewDelegate::DNS_ERROR
1205 : WebViewDelegate::CONNECTION_ERROR);
1206 if (error_page_url.is_valid()) {
1207 // Ask the WebFrame to fetch the alternate error page for us.
[email protected]726985e22009-06-18 21:09:281208 frame->LoadAlternateHTMLErrorPage(failed_request, error, error_page_url,
[email protected]5df266ac2008-10-15 19:50:131209 replace, GURL(kUnreachableWebDataURL));
1210 return;
1211 }
initial.commit09911bf2008-07-26 23:55:291212 }
[email protected]5df266ac2008-10-15 19:50:131213
[email protected]be645db2009-02-06 20:36:331214 // Fallback to a local error page.
[email protected]726985e22009-06-18 21:09:281215 LoadNavigationErrorPage(frame, failed_request, error, std::string(),
[email protected]5df266ac2008-10-15 19:50:131216 replace);
initial.commit09911bf2008-07-26 23:55:291217}
1218
1219void RenderView::LoadNavigationErrorPage(WebFrame* frame,
[email protected]726985e22009-06-18 21:09:281220 const WebURLRequest& failed_request,
1221 const WebURLError& error,
initial.commit09911bf2008-07-26 23:55:291222 const std::string& html,
1223 bool replace) {
[email protected]726985e22009-06-18 21:09:281224 GURL failed_url = error.unreachableURL;
initial.commit09911bf2008-07-26 23:55:291225
1226 std::string alt_html;
1227 if (html.empty()) {
1228 // Use a local error page.
1229 int resource_id;
1230 DictionaryValue error_strings;
[email protected]726985e22009-06-18 21:09:281231 if (error.reason == net::ERR_CACHE_MISS &&
1232 EqualsASCII(failed_request.httpMethod(), "POST")) {
initial.commit09911bf2008-07-26 23:55:291233 GetFormRepostErrorValues(failed_url, &error_strings);
1234 resource_id = IDR_ERROR_NO_DETAILS_HTML;
1235 } else {
1236 GetLocalizedErrorValues(error, &error_strings);
1237 resource_id = IDR_NET_ERROR_HTML;
1238 }
[email protected]8e50b602009-03-03 22:59:431239 error_strings.SetString(L"textdirection",
1240 (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) ?
1241 L"rtl" : L"ltr");
initial.commit09911bf2008-07-26 23:55:291242
1243 alt_html = GetAltHTMLForTemplate(error_strings, resource_id);
1244 } else {
1245 alt_html = html;
1246 }
1247
[email protected]e6f546c32009-07-01 17:12:551248 frame->LoadHTMLString(alt_html,
1249 GURL(kUnreachableWebDataURL),
1250 failed_url,
1251 replace);
initial.commit09911bf2008-07-26 23:55:291252}
1253
1254void RenderView::DidCommitLoadForFrame(WebView *webview, WebFrame* frame,
1255 bool is_new_navigation) {
[email protected]daa8c58e2009-06-15 17:21:101256 NavigationState* navigation_state =
1257 NavigationState::FromDataSource(frame->GetDataSource());
initial.commit09911bf2008-07-26 23:55:291258
[email protected]a2f6bc112009-06-27 16:27:251259 navigation_state->set_commit_load_time(Time::Now());
initial.commit09911bf2008-07-26 23:55:291260 if (is_new_navigation) {
1261 // When we perform a new navigation, we need to update the previous session
1262 // history entry with state for the page we are leaving.
1263 UpdateSessionHistory(frame);
1264
1265 // We bump our Page ID to correspond with the new session history entry.
1266 page_id_ = next_page_id_++;
1267
1268 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1269 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo,
1270 page_id_, true),
1271 kDelayForForcedCaptureMs);
1272 } else {
[email protected]77f17a82009-05-21 04:42:541273 // Inspect the navigation_state on the main frame (set in our Navigate
1274 // method) to see if the navigation corresponds to a session history
1275 // navigation... Note: |frame| may or may not be the toplevel frame, but
1276 // for the case of capturing session history, the first committed frame
1277 // suffices. We keep track of whether we've seen this commit before so
1278 // that only capture session history once per navigation.
[email protected]f4d34b52008-11-24 23:05:011279 //
1280 // Note that we need to check if the page ID changed. In the case of a
1281 // reload, the page ID doesn't change, and UpdateSessionHistory gets the
1282 // previous URL and the current page ID, which would be wrong.
[email protected]daa8c58e2009-06-15 17:21:101283 if (!navigation_state->is_new_navigation() &&
1284 !navigation_state->request_committed() &&
[email protected]77f17a82009-05-21 04:42:541285 page_id_ != navigation_state->pending_page_id()) {
initial.commit09911bf2008-07-26 23:55:291286 // This is a successful session history navigation!
1287 UpdateSessionHistory(frame);
[email protected]77f17a82009-05-21 04:42:541288 page_id_ = navigation_state->pending_page_id();
initial.commit09911bf2008-07-26 23:55:291289 }
1290 }
1291
1292 // Remember that we've already processed this request, so we don't update
1293 // the session history again. We do this regardless of whether this is
1294 // a session history navigation, because if we attempted a session history
1295 // navigation without valid HistoryItem state, WebCore will think it is a
1296 // new navigation.
[email protected]daa8c58e2009-06-15 17:21:101297 navigation_state->set_request_committed(true);
initial.commit09911bf2008-07-26 23:55:291298
1299 UpdateURL(frame);
1300
1301 // If this committed load was initiated by a client redirect, we're
1302 // at the last stop now, so clear it.
1303 completed_client_redirect_src_ = GURL();
1304
1305 // Check whether we have new encoding name.
1306 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
1307}
1308
1309void RenderView::DidReceiveTitle(WebView* webview,
1310 const std::wstring& title,
1311 WebFrame* frame) {
1312 UpdateTitle(frame, title);
1313
1314 // Also check whether we have new encoding name.
1315 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
1316}
1317
1318void RenderView::DidFinishLoadForFrame(WebView* webview, WebFrame* frame) {
[email protected]a2f6bc112009-06-27 16:27:251319 WebDataSource* ds = frame->GetDataSource();
1320 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
[email protected]e695fbd62009-06-30 16:31:541321 // TODO(darin): It should not be possible for navigation_state to be null
[email protected]00c2ecb2009-06-29 23:36:031322 // here!
1323 if (navigation_state)
1324 navigation_state->set_finish_load_time(Time::Now());
initial.commit09911bf2008-07-26 23:55:291325}
1326
1327void RenderView::DidFailLoadWithError(WebView* webview,
[email protected]726985e22009-06-18 21:09:281328 const WebURLError& error,
initial.commit09911bf2008-07-26 23:55:291329 WebFrame* frame) {
[email protected]546ddd172009-06-25 00:25:011330 // Currently this function is empty. When you implement something here and it
1331 // will display any error messages in HTML, please make sure to call
1332 // frame->SetInViewSourceMode(false) not to show them in view source mode.
initial.commit09911bf2008-07-26 23:55:291333}
1334
1335void RenderView::DidFinishDocumentLoadForFrame(WebView* webview,
1336 WebFrame* frame) {
[email protected]a2f6bc112009-06-27 16:27:251337 WebDataSource* ds = frame->GetDataSource();
1338 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
[email protected]e695fbd62009-06-30 16:31:541339 // TODO(darin): It should not be possible for navigation_state to be null
[email protected]00c2ecb2009-06-29 23:36:031340 // here!
1341 if (navigation_state)
1342 navigation_state->set_finish_document_load_time(Time::Now());
[email protected]a2f6bc112009-06-27 16:27:251343
[email protected]09b8f82f2009-06-16 20:22:111344 Send(new ViewHostMsg_DocumentLoadedInFrame(routing_id_));
1345
[email protected]daa8c58e2009-06-15 17:21:101346 // The document has now been fully loaded. Scan for password forms to be
1347 // sent up to the browser.
1348 SendPasswordForms(frame);
1349
initial.commit09911bf2008-07-26 23:55:291350 // Check whether we have new encoding name.
1351 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
[email protected]1e0f70402008-10-16 23:57:471352
[email protected]8930d472009-02-21 08:05:281353 if (RenderThread::current()) // Will be NULL during unit tests.
1354 RenderThread::current()->user_script_slave()->InjectScripts(
[email protected]0afe8272009-02-14 04:15:161355 frame, UserScript::DOCUMENT_END);
initial.commit09911bf2008-07-26 23:55:291356}
1357
1358void RenderView::DidHandleOnloadEventsForFrame(WebView* webview,
1359 WebFrame* frame) {
1360}
1361
1362void RenderView::DidChangeLocationWithinPageForFrame(WebView* webview,
1363 WebFrame* frame,
1364 bool is_new_navigation) {
[email protected]77f17a82009-05-21 04:42:541365 // If this was a reference fragment navigation that we initiated, then we
1366 // could end up having a non-null pending navigation state. We just need to
1367 // update the ExtraData on the datasource so that others who read the
1368 // ExtraData will get the new NavigationState. Similarly, if we did not
[email protected]daa8c58e2009-06-15 17:21:101369 // initiate this navigation, then we need to take care to reset any pre-
1370 // existing navigation state to a content-initiated navigation state.
1371 // DidCreateDataSource conveniently takes care of this for us.
1372 DidCreateDataSource(frame, frame->GetDataSource());
[email protected]77f17a82009-05-21 04:42:541373
initial.commit09911bf2008-07-26 23:55:291374 DidCommitLoadForFrame(webview, frame, is_new_navigation);
[email protected]77f17a82009-05-21 04:42:541375
[email protected]9d806f52009-03-12 22:50:541376 const string16& title =
[email protected]726985e22009-06-18 21:09:281377 webview->GetMainFrame()->GetDataSource()->pageTitle();
[email protected]9d806f52009-03-12 22:50:541378 UpdateTitle(frame, UTF16ToWideHack(title));
initial.commit09911bf2008-07-26 23:55:291379}
1380
initial.commit09911bf2008-07-26 23:55:291381void RenderView::DidCompleteClientRedirect(WebView* webview,
1382 WebFrame* frame,
1383 const GURL& source) {
1384 if (webview->GetMainFrame() == frame)
1385 completed_client_redirect_src_ = source;
1386}
1387
[email protected]7a9b51f2009-06-29 21:28:291388void RenderView::WillCloseFrame(WebView* webview, WebFrame* frame) {
1389 if (!frame->GetParent()) {
1390 const GURL& url = frame->GetURL();
1391 if (url.SchemeIs("http") || url.SchemeIs("https"))
1392 DumpLoadHistograms();
1393 }
1394}
1395
[email protected]daa8c58e2009-06-15 17:21:101396void RenderView::WillSubmitForm(WebView* webview, WebFrame* frame,
1397 const WebForm& form) {
1398 NavigationState* navigation_state =
1399 NavigationState::FromDataSource(frame->GetProvisionalDataSource());
1400
1401 if (navigation_state->transition_type() == PageTransition::LINK)
1402 navigation_state->set_transition_type(PageTransition::FORM_SUBMIT);
1403
1404 // Save these to be processed when the ensuing navigation is committed.
1405 navigation_state->set_searchable_form_data(
1406 SearchableFormData::Create(form));
1407 navigation_state->set_password_form_data(
1408 PasswordFormDomManager::CreatePasswordForm(form));
1409
1410 if (form.isAutoCompleteEnabled()) {
1411 scoped_ptr<AutofillForm> autofill_form(AutofillForm::Create(form));
1412 if (autofill_form.get())
1413 Send(new ViewHostMsg_AutofillFormSubmitted(routing_id_, *autofill_form));
1414 }
1415}
1416
[email protected]5b35a6b2009-03-16 19:58:081417void RenderView::WillSendRequest(WebView* webview,
1418 uint32 identifier,
[email protected]726985e22009-06-18 21:09:281419 WebURLRequest* request) {
1420 request->setRequestorID(routing_id_);
[email protected]5b35a6b2009-03-16 19:58:081421}
1422
initial.commit09911bf2008-07-26 23:55:291423void RenderView::BindDOMAutomationController(WebFrame* webframe) {
1424 dom_automation_controller_.set_message_sender(this);
1425 dom_automation_controller_.set_routing_id(routing_id_);
1426 dom_automation_controller_.BindToJavascript(webframe,
1427 L"domAutomationController");
1428}
1429
1430void RenderView::WindowObjectCleared(WebFrame* webframe) {
[email protected]81e63782009-02-27 19:35:091431 if (BindingsPolicy::is_dom_automation_enabled(enabled_bindings_))
initial.commit09911bf2008-07-26 23:55:291432 BindDOMAutomationController(webframe);
[email protected]81e63782009-02-27 19:35:091433 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_)) {
initial.commit09911bf2008-07-26 23:55:291434 dom_ui_bindings_.set_message_sender(this);
1435 dom_ui_bindings_.set_routing_id(routing_id_);
1436 dom_ui_bindings_.BindToJavascript(webframe, L"chrome");
1437 }
[email protected]81e63782009-02-27 19:35:091438 if (BindingsPolicy::is_external_host_enabled(enabled_bindings_)) {
[email protected]18cb2572008-08-21 20:34:451439 external_host_bindings_.set_message_sender(this);
1440 external_host_bindings_.set_routing_id(routing_id_);
1441 external_host_bindings_.BindToJavascript(webframe, L"externalHost");
1442 }
initial.commit09911bf2008-07-26 23:55:291443}
1444
[email protected]0afe8272009-02-14 04:15:161445void RenderView::DocumentElementAvailable(WebFrame* frame) {
[email protected]4b8323b2009-04-17 18:45:441446 // TODO(mpcomplete): remove this before Chrome extensions ship.
1447 // HACK. This is a temporary workaround to allow cross-origin XHR for Chrome
1448 // extensions. It grants full access to every origin, when we really want
1449 // to be able to restrict them more specifically.
[email protected]d959ce22009-04-15 21:03:421450 if (frame->GetURL().SchemeIs(chrome::kExtensionScheme))
[email protected]4b8323b2009-04-17 18:45:441451 frame->GrantUniversalAccess();
[email protected]d959ce22009-04-15 21:03:421452
[email protected]8930d472009-02-21 08:05:281453 if (RenderThread::current()) // Will be NULL during unit tests.
1454 RenderThread::current()->user_script_slave()->InjectScripts(
[email protected]0afe8272009-02-14 04:15:161455 frame, UserScript::DOCUMENT_START);
1456}
1457
[email protected]f816c012009-06-26 21:48:321458void RenderView::DidCreateScriptContext(WebFrame* webframe) {
1459 EventBindings::HandleContextCreated(webframe);
1460}
1461
1462void RenderView::DidDestroyScriptContext(WebFrame* webframe) {
1463 EventBindings::HandleContextDestroyed(webframe);
1464}
1465
initial.commit09911bf2008-07-26 23:55:291466WindowOpenDisposition RenderView::DispositionForNavigationAction(
1467 WebView* webview,
1468 WebFrame* frame,
[email protected]726985e22009-06-18 21:09:281469 const WebURLRequest& request,
initial.commit09911bf2008-07-26 23:55:291470 WebNavigationType type,
1471 WindowOpenDisposition disposition,
1472 bool is_redirect) {
[email protected]daa8c58e2009-06-15 17:21:101473 // A content initiated navigation may have originated from a link-click,
1474 // script, drag-n-drop operation, etc.
[email protected]77f17a82009-05-21 04:42:541475 bool is_content_initiated =
[email protected]daa8c58e2009-06-15 17:21:101476 NavigationState::FromDataSource(frame->GetProvisionalDataSource())->
1477 is_content_initiated();
[email protected]77f17a82009-05-21 04:42:541478
initial.commit09911bf2008-07-26 23:55:291479 // Webkit is asking whether to navigate to a new URL.
1480 // This is fine normally, except if we're showing UI from one security
1481 // context and they're trying to navigate to a different context.
[email protected]726985e22009-06-18 21:09:281482 const GURL& url = request.url();
[email protected]77f17a82009-05-21 04:42:541483
initial.commit09911bf2008-07-26 23:55:291484 // We only care about navigations that are within the current tab (as opposed
1485 // to, for example, opening a new window).
1486 // But we sometimes navigate to about:blank to clear a tab, and we want to
1487 // still allow that.
[email protected]77f17a82009-05-21 04:42:541488 if (disposition == CURRENT_TAB && is_content_initiated &&
1489 frame->GetParent() == NULL && !url.SchemeIs(chrome::kAboutScheme)) {
1490 // When we received such unsolicited navigations, we sometimes want to
1491 // punt them up to the browser to handle.
1492 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_) ||
[email protected]1e5f53a2009-06-15 23:48:041493 BindingsPolicy::is_extension_enabled(enabled_bindings_) ||
[email protected]77f17a82009-05-21 04:42:541494 frame->GetInViewSourceMode() ||
1495 url.SchemeIs(chrome::kViewSourceScheme)) {
1496 OpenURL(webview, url, GURL(), disposition);
1497 return IGNORE_ACTION; // Suppress the load here.
initial.commit09911bf2008-07-26 23:55:291498 }
1499 }
1500
1501 // Detect when a page is "forking" a new tab that can be safely rendered in
1502 // its own process. This is done by sites like Gmail that try to open links
1503 // in new windows without script connections back to the original page. We
1504 // treat such cases as browser navigations (in which we will create a new
1505 // renderer for a cross-site navigation), rather than WebKit navigations.
1506 //
1507 // We use the following heuristic to decide whether to fork a new page in its
1508 // own process:
1509 // The parent page must open a new tab to about:blank, set the new tab's
1510 // window.opener to null, and then redirect the tab to a cross-site URL using
1511 // JavaScript.
1512 bool is_fork =
1513 // Must start from a tab showing about:blank, which is later redirected.
[email protected]6aad4bd2009-02-26 22:55:171514 frame->GetURL() == GURL("about:blank") &&
initial.commit09911bf2008-07-26 23:55:291515 // Must be the first real navigation of the tab.
1516 GetHistoryBackListCount() < 1 &&
1517 GetHistoryForwardListCount() < 1 &&
1518 // The parent page must have set the child's window.opener to null before
1519 // redirecting to the desired URL.
1520 frame->GetOpener() == NULL &&
1521 // Must be a top-level frame.
1522 frame->GetParent() == NULL &&
[email protected]77f17a82009-05-21 04:42:541523 // Must not have issued the request from this page.
1524 is_content_initiated &&
initial.commit09911bf2008-07-26 23:55:291525 // Must be targeted at the current tab.
1526 disposition == CURRENT_TAB &&
1527 // Must be a JavaScript navigation, which appears as "other".
[email protected]726985e22009-06-18 21:09:281528 type == WebKit::WebNavigationTypeOther;
initial.commit09911bf2008-07-26 23:55:291529 if (is_fork) {
1530 // Open the URL via the browser, not via WebKit.
[email protected]c0588052008-10-27 23:01:501531 OpenURL(webview, url, GURL(), disposition);
initial.commit09911bf2008-07-26 23:55:291532 return IGNORE_ACTION;
1533 }
1534
1535 return disposition;
1536}
1537
[email protected]a455d3812009-03-05 20:18:071538void RenderView::RunJavaScriptAlert(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291539 const std::wstring& message) {
[email protected]478ff2ed2009-04-21 23:49:181540 RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptAlert,
initial.commit09911bf2008-07-26 23:55:291541 message,
1542 std::wstring(),
[email protected]a455d3812009-03-05 20:18:071543 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291544 NULL);
1545}
1546
[email protected]a455d3812009-03-05 20:18:071547bool RenderView::RunJavaScriptConfirm(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291548 const std::wstring& message) {
[email protected]478ff2ed2009-04-21 23:49:181549 return RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptConfirm,
initial.commit09911bf2008-07-26 23:55:291550 message,
1551 std::wstring(),
[email protected]a455d3812009-03-05 20:18:071552 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291553 NULL);
1554}
1555
[email protected]a455d3812009-03-05 20:18:071556bool RenderView::RunJavaScriptPrompt(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291557 const std::wstring& message,
1558 const std::wstring& default_value,
1559 std::wstring* result) {
[email protected]478ff2ed2009-04-21 23:49:181560 return RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptPrompt,
initial.commit09911bf2008-07-26 23:55:291561 message,
1562 default_value,
[email protected]a455d3812009-03-05 20:18:071563 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291564 result);
1565}
1566
1567bool RenderView::RunJavaScriptMessage(int type,
1568 const std::wstring& message,
1569 const std::wstring& default_value,
[email protected]a455d3812009-03-05 20:18:071570 const GURL& frame_url,
initial.commit09911bf2008-07-26 23:55:291571 std::wstring* result) {
1572 bool success = false;
1573 std::wstring result_temp;
1574 if (!result)
1575 result = &result_temp;
1576 IPC::SyncMessage* msg = new ViewHostMsg_RunJavaScriptMessage(
[email protected]a455d3812009-03-05 20:18:071577 routing_id_, message, default_value, frame_url, type, &success, result);
initial.commit09911bf2008-07-26 23:55:291578
[email protected]1c4947f2009-01-15 22:25:111579 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291580 Send(msg);
1581
1582 return success;
1583}
1584
1585void RenderView::AddGURLSearchProvider(const GURL& osd_url, bool autodetected) {
1586 if (!osd_url.is_empty())
1587 Send(new ViewHostMsg_PageHasOSDD(routing_id_, page_id_, osd_url,
1588 autodetected));
1589}
1590
[email protected]a455d3812009-03-05 20:18:071591bool RenderView::RunBeforeUnloadConfirm(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291592 const std::wstring& message) {
1593 bool success = false;
1594 // This is an ignored return value, but is included so we can accept the same
1595 // response as RunJavaScriptMessage.
1596 std::wstring ignored_result;
1597 IPC::SyncMessage* msg = new ViewHostMsg_RunBeforeUnloadConfirm(
[email protected]a455d3812009-03-05 20:18:071598 routing_id_, webframe->GetURL(), message, &success, &ignored_result);
initial.commit09911bf2008-07-26 23:55:291599
[email protected]1c4947f2009-01-15 22:25:111600 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291601 Send(msg);
1602
1603 return success;
1604}
1605
[email protected]0ebf3872008-11-07 21:35:031606void RenderView::QueryFormFieldAutofill(const std::wstring& field_name,
1607 const std::wstring& text,
1608 int64 node_id) {
1609 static int message_id_counter = 0;
1610 form_field_autofill_request_id_ = message_id_counter++;
1611 Send(new ViewHostMsg_QueryFormFieldAutofill(routing_id_,
1612 field_name, text,
1613 node_id,
1614 form_field_autofill_request_id_));
1615}
1616
[email protected]4d2b6fb2009-03-20 22:28:171617void RenderView::RemoveStoredAutofillEntry(const std::wstring& name,
1618 const std::wstring& value) {
1619 Send(new ViewHostMsg_RemoveAutofillEntry(routing_id_, name, value));
1620}
1621
[email protected]0ebf3872008-11-07 21:35:031622void RenderView::OnReceivedAutofillSuggestions(
1623 int64 node_id,
1624 int request_id,
[email protected]8d0f15c2008-11-11 01:01:091625 const std::vector<std::wstring>& suggestions,
[email protected]0ebf3872008-11-07 21:35:031626 int default_suggestion_index) {
1627 if (!webview() || request_id != form_field_autofill_request_id_)
1628 return;
1629
1630 webview()->AutofillSuggestionsForNode(node_id, suggestions,
1631 default_suggestion_index);
1632}
1633
[email protected]2c4410d2009-05-06 23:46:221634void RenderView::OnPopupNotificationVisibilityChanged(bool visible) {
[email protected]634a6f92008-12-01 21:39:311635 popup_notification_visible_ = visible;
1636}
1637
initial.commit09911bf2008-07-26 23:55:291638void RenderView::ShowModalHTMLDialog(const GURL& url, int width, int height,
1639 const std::string& json_arguments,
1640 std::string* json_retval) {
1641 IPC::SyncMessage* msg = new ViewHostMsg_ShowModalHTMLDialog(
1642 routing_id_, url, width, height, json_arguments, json_retval);
1643
[email protected]1c4947f2009-01-15 22:25:111644 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291645 Send(msg);
1646}
1647
1648uint32 RenderView::GetCPBrowsingContext() {
1649 uint32 context = 0;
1650 Send(new ViewHostMsg_GetCPBrowsingContext(&context));
1651 return context;
1652}
1653
1654// Tell the browser to display a destination link.
1655void RenderView::UpdateTargetURL(WebView* webview, const GURL& url) {
1656 if (url != target_url_) {
1657 if (target_url_status_ == TARGET_INFLIGHT ||
1658 target_url_status_ == TARGET_PENDING) {
1659 // If we have a request in-flight, save the URL to be sent when we
1660 // receive an ACK to the in-flight request. We can happily overwrite
1661 // any existing pending sends.
1662 pending_target_url_ = url;
1663 target_url_status_ = TARGET_PENDING;
1664 } else {
1665 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_, url));
1666 target_url_ = url;
1667 target_url_status_ = TARGET_INFLIGHT;
1668 }
1669 }
1670}
1671
[email protected]b62d1a8c2009-01-13 23:54:571672void RenderView::RunFileChooser(bool multi_select,
[email protected]b949f1112009-04-12 20:03:081673 const string16& title,
1674 const FilePath& default_filename,
initial.commit09911bf2008-07-26 23:55:291675 WebFileChooserCallback* file_chooser) {
1676 if (file_chooser_.get()) {
1677 // TODO(brettw): bug 1235154: This should be a synchronous message to deal
1678 // with the fact that web pages can programatically trigger this. With the
1679 // asnychronous messages, we can get an additional call when one is pending,
1680 // which this test is for. For now, we just ignore the additional file
1681 // chooser request. WebKit doesn't do anything to expect the callback, so
1682 // we can just ignore calling it.
1683 delete file_chooser;
1684 return;
1685 }
1686 file_chooser_.reset(file_chooser);
[email protected]b62d1a8c2009-01-13 23:54:571687 Send(new ViewHostMsg_RunFileChooser(routing_id_, multi_select, title,
[email protected]b949f1112009-04-12 20:03:081688 default_filename));
initial.commit09911bf2008-07-26 23:55:291689}
1690
1691void RenderView::AddMessageToConsole(WebView* webview,
1692 const std::wstring& message,
1693 unsigned int line_no,
1694 const std::wstring& source_id) {
1695 Send(new ViewHostMsg_AddMessageToConsole(routing_id_, message,
1696 static_cast<int32>(line_no),
1697 source_id));
1698}
1699
1700void RenderView::AddSearchProvider(const std::string& url) {
1701 AddGURLSearchProvider(GURL(url),
1702 false); // not autodetected
1703}
1704
[email protected]c88a70fe2009-05-05 20:00:221705WebView* RenderView::CreateWebView(WebView* webview,
1706 bool user_gesture,
1707 const GURL& creator_url) {
[email protected]0aa55312008-10-17 21:53:081708 // Check to make sure we aren't overloading on popups.
1709 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups)
1710 return NULL;
1711
[email protected]634a6f92008-12-01 21:39:311712 // This window can't be closed from a window.close() call until we receive a
1713 // message from the Browser process explicitly allowing it.
1714 popup_notification_visible_ = true;
1715
initial.commit09911bf2008-07-26 23:55:291716 int32 routing_id = MSG_ROUTING_NONE;
[email protected]6c8afae52009-01-22 02:24:571717
[email protected]18bcc3c2009-01-27 21:39:151718 ModalDialogEvent modal_dialog_event;
[email protected]6c8afae52009-01-22 02:24:571719 render_thread_->Send(
[email protected]15787f8f2008-10-17 15:29:031720 new ViewHostMsg_CreateWindow(routing_id_, user_gesture, &routing_id,
1721 &modal_dialog_event));
initial.commit09911bf2008-07-26 23:55:291722 if (routing_id == MSG_ROUTING_NONE) {
initial.commit09911bf2008-07-26 23:55:291723 return NULL;
1724 }
1725
1726 // The WebView holds a reference to this new RenderView
[email protected]80d96fa2009-06-10 22:34:511727 const WebPreferences& web_prefs = webview->GetPreferences();
[email protected]6c8afae52009-01-22 02:24:571728 base::WaitableEvent* waitable_event = new base::WaitableEvent
1729#if defined(OS_WIN)
[email protected]18bcc3c2009-01-27 21:39:151730 (modal_dialog_event.event);
[email protected]6c8afae52009-01-22 02:24:571731#else
1732 (true, false);
1733#endif
[email protected]81a34412009-01-05 19:17:241734 RenderView* view = RenderView::Create(render_thread_,
[email protected]1c4947f2009-01-15 22:25:111735 NULL, waitable_event, routing_id_,
[email protected]80d96fa2009-06-10 22:34:511736 renderer_preferences_, web_prefs,
1737 shared_popup_counter_, routing_id);
[email protected]ed4bf2d2009-05-05 00:10:061738 view->opened_by_user_gesture_ = user_gesture;
[email protected]c88a70fe2009-05-05 20:00:221739 view->creator_url_ = creator_url;
initial.commit09911bf2008-07-26 23:55:291740
1741 // Copy over the alternate error page URL so we can have alt error pages in
1742 // the new render view (we don't need the browser to send the URL back down).
1743 view->alternate_error_page_url_ = alternate_error_page_url_;
1744
1745 return view->webview();
1746}
1747
[email protected]0ebf3872008-11-07 21:35:031748WebWidget* RenderView::CreatePopupWidget(WebView* webview,
[email protected]cfd727f2009-01-09 20:21:111749 bool activatable) {
[email protected]8085dbc82008-09-26 22:53:441750 RenderWidget* widget = RenderWidget::Create(routing_id_,
[email protected]81a34412009-01-05 19:17:241751 render_thread_,
[email protected]cfd727f2009-01-09 20:21:111752 activatable);
initial.commit09911bf2008-07-26 23:55:291753 return widget->webwidget();
1754}
1755
1756WebPluginDelegate* RenderView::CreatePluginDelegate(
1757 WebView* webview,
1758 const GURL& url,
1759 const std::string& mime_type,
1760 const std::string& clsid,
1761 std::string* actual_mime_type) {
[email protected]ffeba6d2009-04-27 20:43:261762#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]6273e2e72009-04-17 00:13:551763 if (!PluginChannelHost::IsListening())
1764 return NULL;
1765
[email protected]9dd9e8382009-06-05 18:23:211766 GURL policy_url;
1767 if (webview->GetMainFrame())
1768 policy_url = webview->GetMainFrame()->GetURL();
1769
[email protected]f5cdaff2009-05-19 21:01:471770 FilePath path;
1771 render_thread_->Send(
[email protected]9dd9e8382009-06-05 18:23:211772 new ViewHostMsg_GetPluginPath(url, policy_url, mime_type, clsid, &path,
[email protected]f5cdaff2009-05-19 21:01:471773 actual_mime_type));
1774 if (path.value().empty())
1775 return NULL;
1776
1777 std::string mime_type_to_use;
1778 if (!actual_mime_type->empty())
1779 mime_type_to_use = *actual_mime_type;
1780 else
1781 mime_type_to_use = mime_type;
1782
[email protected]ffeba6d2009-04-27 20:43:261783#if !defined(OS_LINUX) // In-proc plugins aren't supported on Linux.
[email protected]88a1fb47a2009-03-13 00:18:061784 if (RenderProcess::current()->in_process_plugins()) {
[email protected]b94d3322009-02-12 19:49:041785 return WebPluginDelegate::Create(path,
1786 mime_type_to_use,
1787 gfx::NativeViewFromId(host_window_));
initial.commit09911bf2008-07-26 23:55:291788 }
[email protected]ffeba6d2009-04-27 20:43:261789#endif
initial.commit09911bf2008-07-26 23:55:291790
1791 WebPluginDelegateProxy* proxy =
[email protected]f5cdaff2009-05-19 21:01:471792 WebPluginDelegateProxy::Create(url, mime_type_to_use, clsid, this);
initial.commit09911bf2008-07-26 23:55:291793 if (!proxy)
1794 return NULL;
1795
initial.commit09911bf2008-07-26 23:55:291796 plugin_delegates_.push_back(proxy);
1797
1798 return proxy;
[email protected]6c8afae52009-01-22 02:24:571799#else
[email protected]157e5d22009-04-23 18:43:351800 // TODO(port): Plugins currently not supported
1801 NOTIMPLEMENTED();
1802 return NULL;
[email protected]6c8afae52009-01-22 02:24:571803#endif
initial.commit09911bf2008-07-26 23:55:291804}
1805
[email protected]4e6be3f2009-05-07 02:24:441806WebKit::WebMediaPlayer* RenderView::CreateWebMediaPlayer(
1807 WebKit::WebMediaPlayerClient* client) {
[email protected]add51772009-06-11 18:25:171808 scoped_refptr<media::FilterFactoryCollection> factory =
1809 new media::FilterFactoryCollection();
1810 // Add in any custom filter factories first.
1811 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
1812 if (!cmd_line->HasSwitch(switches::kDisableAudio)) {
1813 // Add the chrome specific audio renderer.
1814 factory->AddFactory(
1815 AudioRendererImpl::CreateFactory(audio_message_filter()));
1816 }
[email protected]8380c092009-06-25 17:45:511817
1818 // TODO(hclam): obtain the following parameters from |client|.
1819 webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory =
1820 new webkit_glue::MediaResourceLoaderBridgeFactory(
1821 GURL::EmptyGURL(), // referrer
1822 "null", // frame origin
1823 "null", // main_frame_origin
1824 base::GetCurrentProcId(),
1825 WebAppCacheContext::kNoAppCacheContextId,
1826 routing_id());
1827
[email protected]add51772009-06-11 18:25:171828 if (!cmd_line->HasSwitch(switches::kSimpleDataSource)) {
1829 // Add the chrome specific media data source.
[email protected]70ab61c92009-06-16 19:29:391830 factory->AddFactory(
1831 BufferedDataSource::CreateFactory(MessageLoop::current(),
[email protected]8380c092009-06-25 17:45:511832 bridge_factory));
1833 } else {
1834 factory->AddFactory(
1835 webkit_glue::SimpleDataSource::CreateFactory(MessageLoop::current(),
1836 bridge_factory));
[email protected]add51772009-06-11 18:25:171837 }
1838 return new webkit_glue::WebMediaPlayerImpl(client, factory);
[email protected]ec9212f2008-12-18 21:40:361839}
1840
initial.commit09911bf2008-07-26 23:55:291841void RenderView::OnMissingPluginStatus(WebPluginDelegate* delegate,
1842 int status) {
[email protected]6c8afae52009-01-22 02:24:571843#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291844 if (first_default_plugin_ == NULL) {
1845 // Show the InfoBar for the first available plugin.
1846 if (status == default_plugin::MISSING_PLUGIN_AVAILABLE) {
1847 first_default_plugin_ = delegate;
1848 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1849 }
1850 } else {
1851 // Closes the InfoBar if user clicks on the plugin (instead of the InfoBar)
1852 // to start the download/install.
1853 if (status == default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD) {
1854 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1855 }
1856 }
[email protected]6c8afae52009-01-22 02:24:571857#else
1858 // TODO(port): plugins current not supported
1859 NOTIMPLEMENTED();
1860#endif
initial.commit09911bf2008-07-26 23:55:291861}
1862
[email protected]eb47a132009-03-04 00:39:561863WebWorker* RenderView::CreateWebWorker(WebWorkerClient* client) {
1864#if defined(OS_WIN)
[email protected]ec775ef2009-05-01 21:20:471865 return new WebWorkerProxy(client, RenderThread::current(), routing_id_);
[email protected]eb47a132009-03-04 00:39:561866#else
1867 // TODO(port): out of process workers
1868 NOTIMPLEMENTED();
1869 return NULL;
1870#endif
1871}
1872
initial.commit09911bf2008-07-26 23:55:291873void RenderView::OpenURL(WebView* webview, const GURL& url,
[email protected]c0588052008-10-27 23:01:501874 const GURL& referrer,
initial.commit09911bf2008-07-26 23:55:291875 WindowOpenDisposition disposition) {
[email protected]c0588052008-10-27 23:01:501876 Send(new ViewHostMsg_OpenURL(routing_id_, url, referrer, disposition));
initial.commit09911bf2008-07-26 23:55:291877}
1878
[email protected]1d522202009-04-04 01:56:421879void RenderView::DidContentsSizeChange(WebWidget* webwidget,
1880 int new_width,
1881 int new_height) {
[email protected]0666aef2009-05-13 19:48:081882 // We don't always want to send the change messages over IPC, only if we've
1883 // be put in that mode by getting a |ViewMsg_EnableIntrinsicWidthChangedMode|
1884 // message.
1885 // TODO(rafaelw): Figure out where the best place to set this for extensions
1886 // is. It isn't clean to test for ExtensionView by examining the
1887 // enabled_bindings. This needs to be generalized as it becomes clear what
1888 // extension toolbars need.
1889 if (BindingsPolicy::is_extension_enabled(enabled_bindings_) ||
1890 send_preferred_width_changes_) {
1891 // WebCore likes to tell us things have changed even when they haven't, so
1892 // cache the width and only send the IPC message when we're sure the
1893 // width is different.
[email protected]1d522202009-04-04 01:56:421894 int width = webview()->GetMainFrame()->GetContentsPreferredWidth();
[email protected]0666aef2009-05-13 19:48:081895 if (width != preferred_width_) {
1896 Send(new ViewHostMsg_DidContentsPreferredWidthChange(routing_id_, width));
1897 preferred_width_ = width;
1898 }
[email protected]1d522202009-04-04 01:56:421899 }
1900}
1901
initial.commit09911bf2008-07-26 23:55:291902// We are supposed to get a single call to Show for a newly created RenderView
1903// that was created via RenderView::CreateWebView. So, we wait until this
1904// point to dispatch the ShowView message.
1905//
1906// This method provides us with the information about how to display the newly
1907// created RenderView (i.e., as a constrained popup or as a new tab).
1908//
1909void RenderView::Show(WebWidget* webwidget, WindowOpenDisposition disposition) {
1910 DCHECK(!did_show_) << "received extraneous Show call";
1911 DCHECK(opener_id_ != MSG_ROUTING_NONE);
1912
1913 if (did_show_)
1914 return;
1915 did_show_ = true;
1916
1917 // NOTE: initial_pos_ may still have its default values at this point, but
1918 // that's okay. It'll be ignored if disposition is not NEW_POPUP, or the
1919 // browser process will impose a default position otherwise.
[email protected]35f7d212009-04-29 21:19:271920 Send(new ViewHostMsg_ShowView(opener_id_, routing_id_, disposition,
[email protected]c88a70fe2009-05-05 20:00:221921 initial_pos_, opened_by_user_gesture_, creator_url_));
[email protected]2533ce12009-05-09 00:02:241922 SetPendingWindowRect(initial_pos_);
initial.commit09911bf2008-07-26 23:55:291923}
1924
[email protected]634a6f92008-12-01 21:39:311925void RenderView::CloseWidgetSoon(WebWidget* webwidget) {
[email protected]2c4410d2009-05-06 23:46:221926 if (!popup_notification_visible_)
[email protected]634a6f92008-12-01 21:39:311927 RenderWidget::CloseWidgetSoon(webwidget);
1928}
1929
initial.commit09911bf2008-07-26 23:55:291930void RenderView::RunModal(WebWidget* webwidget) {
1931 DCHECK(did_show_) << "should already have shown the view";
1932
1933 IPC::SyncMessage* msg = new ViewHostMsg_RunModal(routing_id_);
1934
[email protected]1c4947f2009-01-15 22:25:111935 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291936 Send(msg);
1937}
1938
1939void RenderView::SyncNavigationState() {
1940 if (!webview())
1941 return;
1942
[email protected]ca948a22009-06-25 19:36:171943 const WebHistoryItem& item =
1944 webview()->GetMainFrame()->GetCurrentHistoryItem();
1945 if (item.isNull())
initial.commit09911bf2008-07-26 23:55:291946 return;
[email protected]ca948a22009-06-25 19:36:171947
1948 Send(new ViewHostMsg_UpdateState(
1949 routing_id_, page_id_, webkit_glue::HistoryItemToString(item)));
initial.commit09911bf2008-07-26 23:55:291950}
1951
1952void RenderView::ShowContextMenu(WebView* webview,
[email protected]124646932009-01-28 18:39:021953 ContextNode node,
initial.commit09911bf2008-07-26 23:55:291954 int x,
1955 int y,
1956 const GURL& link_url,
1957 const GURL& image_url,
1958 const GURL& page_url,
1959 const GURL& frame_url,
1960 const std::wstring& selection_text,
1961 const std::wstring& misspelled_word,
[email protected]6aa376b2008-09-23 18:49:521962 int edit_flags,
[email protected]c9825a42009-05-01 22:51:501963 const std::string& security_info,
1964 const std::string& frame_charset) {
[email protected]e09ba552009-02-05 03:26:291965 ContextMenuParams params;
[email protected]124646932009-01-28 18:39:021966 params.node = node;
initial.commit09911bf2008-07-26 23:55:291967 params.x = x;
1968 params.y = y;
1969 params.image_url = image_url;
1970 params.link_url = link_url;
[email protected]e6c79812009-04-22 22:31:421971 params.unfiltered_link_url = link_url;
initial.commit09911bf2008-07-26 23:55:291972 params.page_url = page_url;
1973 params.frame_url = frame_url;
1974 params.selection_text = selection_text;
1975 params.misspelled_word = misspelled_word;
[email protected]be645db2009-02-06 20:36:331976 params.spellcheck_enabled =
[email protected]bbbd545c2008-12-15 20:18:041977 webview->GetFocusedFrame()->SpellCheckEnabled();
initial.commit09911bf2008-07-26 23:55:291978 params.edit_flags = edit_flags;
[email protected]6aa376b2008-09-23 18:49:521979 params.security_info = security_info;
[email protected]c9825a42009-05-01 22:51:501980 params.frame_charset = frame_charset;
initial.commit09911bf2008-07-26 23:55:291981 Send(new ViewHostMsg_ContextMenu(routing_id_, params));
1982}
1983
[email protected]e80c73b2009-04-07 23:24:581984void RenderView::StartDragging(WebView* webview,
1985 const WebDragData& drag_data) {
1986 Send(new ViewHostMsg_StartDragging(routing_id_, WebDropData(drag_data)));
initial.commit09911bf2008-07-26 23:55:291987}
1988
1989void RenderView::TakeFocus(WebView* webview, bool reverse) {
1990 Send(new ViewHostMsg_TakeFocus(routing_id_, reverse));
1991}
1992
1993void RenderView::DidDownloadImage(int id,
1994 const GURL& image_url,
1995 bool errored,
1996 const SkBitmap& image) {
1997 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, errored,
1998 image));
1999}
2000
2001
2002void RenderView::OnDownloadImage(int id,
2003 const GURL& image_url,
2004 int image_size) {
[email protected]f11ca0732009-04-11 00:09:342005 bool data_image_failed = false;
2006 if (image_url.SchemeIs("data")) {
2007 SkBitmap data_image = ImageFromDataUrl(image_url);
2008 data_image_failed = data_image.empty();
2009 if (!data_image_failed) {
2010 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, false,
2011 data_image));
2012 }
2013 }
2014
2015 if (data_image_failed || !webview()->DownloadImage(id, image_url, image_size))
initial.commit09911bf2008-07-26 23:55:292016 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, true,
2017 SkBitmap()));
2018}
2019
[email protected]f11ca0732009-04-11 00:09:342020SkBitmap RenderView::ImageFromDataUrl(const GURL& url) const {
2021 std::string mime_type, char_set, data;
2022 if (net::DataURL::Parse(url, &mime_type, &char_set, &data) && !data.empty()) {
2023 // Decode the favicon using WebKit's image decoder.
2024 webkit_glue::ImageDecoder decoder(gfx::Size(kFavIconSize, kFavIconSize));
2025 const unsigned char* src_data =
2026 reinterpret_cast<const unsigned char*>(&data[0]);
2027
2028 return decoder.Decode(src_data, data.size());
2029 }
2030 return SkBitmap();
2031}
2032
initial.commit09911bf2008-07-26 23:55:292033void RenderView::OnGetApplicationInfo(int page_id) {
2034 webkit_glue::WebApplicationInfo app_info;
2035 if (page_id == page_id_)
2036 webkit_glue::GetApplicationInfo(webview(), &app_info);
2037
2038 // Prune out any data URLs in the set of icons. The browser process expects
2039 // any icon with a data URL to have originated from a favicon. We don't want
2040 // to decode arbitrary data URLs in the browser process. See
2041 // http://b/issue?id=1162972
2042 for (size_t i = 0; i < app_info.icons.size(); ++i) {
[email protected]6de74452009-02-25 18:04:592043 if (app_info.icons[i].url.SchemeIs(chrome::kDataScheme)) {
initial.commit09911bf2008-07-26 23:55:292044 app_info.icons.erase(app_info.icons.begin() + i);
2045 --i;
2046 }
2047 }
2048
2049 Send(new ViewHostMsg_DidGetApplicationInfo(routing_id_, page_id, app_info));
2050}
2051
2052GURL RenderView::GetAlternateErrorPageURL(const GURL& failedURL,
2053 ErrorPageType error_type) {
2054 if (failedURL.SchemeIsSecure()) {
2055 // If the URL that failed was secure, then the embedding web page was not
2056 // expecting a network attacker to be able to manipulate its contents. As
2057 // we fetch alternate error pages over HTTP, we would be allowing a network
2058 // attacker to manipulate the contents of the response if we tried to use
2059 // the link doctor here.
2060 return GURL::EmptyGURL();
2061 }
2062
2063 // Grab the base URL from the browser process.
2064 if (!alternate_error_page_url_.is_valid())
2065 return GURL::EmptyGURL();
2066
2067 // Strip query params from the failed URL.
2068 GURL::Replacements remove_params;
2069 remove_params.ClearUsername();
2070 remove_params.ClearPassword();
2071 remove_params.ClearQuery();
2072 remove_params.ClearRef();
2073 const GURL url_to_send = failedURL.ReplaceComponents(remove_params);
2074
2075 // Construct the query params to send to link doctor.
2076 std::string params(alternate_error_page_url_.query());
2077 params.append("&url=");
2078 params.append(EscapeQueryParamValue(url_to_send.spec()));
2079 params.append("&sourceid=chrome");
2080 params.append("&error=");
2081 switch (error_type) {
2082 case DNS_ERROR:
2083 params.append("dnserror");
2084 break;
2085
2086 case HTTP_404:
2087 params.append("http404");
2088 break;
2089
[email protected]5df266ac2008-10-15 19:50:132090 case CONNECTION_ERROR:
[email protected]e1f934b2009-01-26 20:41:332091 params.append("connectionfailure");
[email protected]5df266ac2008-10-15 19:50:132092 break;
2093
initial.commit09911bf2008-07-26 23:55:292094 default:
2095 NOTREACHED() << "unknown ErrorPageType";
2096 }
2097
2098 // OK, build the final url to return.
2099 GURL::Replacements link_doctor_params;
2100 link_doctor_params.SetQueryStr(params);
2101 GURL url = alternate_error_page_url_.ReplaceComponents(link_doctor_params);
2102 return url;
2103}
2104
[email protected]7ea066a2009-04-06 20:21:592105void RenderView::OnFind(int request_id,
2106 const string16& search_text,
2107 const WebKit::WebFindOptions& options) {
initial.commit09911bf2008-07-26 23:55:292108 WebFrame* main_frame = webview()->GetMainFrame();
2109 WebFrame* frame_after_main = webview()->GetNextFrameAfter(main_frame, true);
2110 WebFrame* focused_frame = webview()->GetFocusedFrame();
2111 WebFrame* search_frame = focused_frame; // start searching focused frame.
2112
2113 bool multi_frame = (frame_after_main != main_frame);
2114
2115 // If we have multiple frames, we don't want to wrap the search within the
2116 // frame, so we check here if we only have main_frame in the chain.
2117 bool wrap_within_frame = !multi_frame;
2118
[email protected]b3f2b912009-04-09 16:18:522119 WebRect selection_rect;
initial.commit09911bf2008-07-26 23:55:292120 bool result = false;
2121
2122 do {
[email protected]7ea066a2009-04-06 20:21:592123 result = search_frame->Find(
2124 request_id, search_text, options, wrap_within_frame, &selection_rect);
initial.commit09911bf2008-07-26 23:55:292125
2126 if (!result) {
2127 // don't leave text selected as you move to the next frame.
2128 search_frame->ClearSelection();
2129
2130 // Find the next frame, but skip the invisible ones.
2131 do {
2132 // What is the next frame to search? (we might be going backwards). Note
2133 // that we specify wrap=true so that search_frame never becomes NULL.
[email protected]7ea066a2009-04-06 20:21:592134 search_frame = options.forward ?
initial.commit09911bf2008-07-26 23:55:292135 webview()->GetNextFrameAfter(search_frame, true) :
2136 webview()->GetPreviousFrameBefore(search_frame, true);
2137 } while (!search_frame->Visible() && search_frame != focused_frame);
2138
[email protected]884db412008-11-24 23:46:502139 // Make sure selection doesn't affect the search operation in new frame.
initial.commit09911bf2008-07-26 23:55:292140 search_frame->ClearSelection();
2141
2142 // If we have multiple frames and we have wrapped back around to the
2143 // focused frame, we need to search it once more allowing wrap within
2144 // the frame, otherwise it will report 'no match' if the focused frame has
2145 // reported matches, but no frames after the focused_frame contain a
2146 // match for the search word(s).
2147 if (multi_frame && search_frame == focused_frame) {
[email protected]7ea066a2009-04-06 20:21:592148 result = search_frame->Find(
2149 request_id, search_text, options, true, // Force wrapping.
2150 &selection_rect);
initial.commit09911bf2008-07-26 23:55:292151 }
2152 }
2153
2154 // TODO(jcampan): http://b/issue?id=1157486 Remove StoreForFocus call once
2155 // we have the fix for 792423.
2156 search_frame->GetView()->StoreFocusForFrame(search_frame);
2157 webview()->SetFocusedFrame(search_frame);
2158 } while (!result && search_frame != focused_frame);
2159
2160 // Make sure we don't leave any frame focused or the focus won't be restored
2161 // properly in WebViewImpl::SetFocus(). Note that we are talking here about
2162 // focused on the SelectionController, not FocusController.
2163 // webview()->GetFocusedFrame() will still return the last focused frame (as
2164 // it queries the FocusController).
2165 // TODO(jcampan): http://b/issue?id=1157486 Remove next line once we have the
2166 // fix for 792423.
2167 webview()->SetFocusedFrame(NULL);
2168
[email protected]7ea066a2009-04-06 20:21:592169 if (options.findNext) {
[email protected]4f3dc372009-02-24 00:10:292170 // Force the main_frame to report the actual count.
[email protected]7ea066a2009-04-06 20:21:592171 main_frame->IncreaseMatchCount(0, request_id);
[email protected]4f3dc372009-02-24 00:10:292172 } else {
2173 // If nothing is found, set result to "0 of 0", otherwise, set it to
2174 // "-1 of 1" to indicate that we found at least one item, but we don't know
2175 // yet what is active.
2176 int ordinal = result ? -1 : 0; // -1 here means, we might know more later.
2177 int match_count = result ? 1 : 0; // 1 here means possibly more coming.
initial.commit09911bf2008-07-26 23:55:292178
[email protected]4f3dc372009-02-24 00:10:292179 // If we find no matches then this will be our last status update.
2180 // Otherwise the scoping effort will send more results.
2181 bool final_status_update = !result;
initial.commit09911bf2008-07-26 23:55:292182
[email protected]4f3dc372009-02-24 00:10:292183 // Send the search result over to the browser process.
[email protected]4f999132009-03-31 18:08:402184 Send(new ViewHostMsg_Find_Reply(routing_id_,
[email protected]7ea066a2009-04-06 20:21:592185 request_id,
[email protected]4f3dc372009-02-24 00:10:292186 match_count,
2187 selection_rect,
2188 ordinal,
2189 final_status_update));
initial.commit09911bf2008-07-26 23:55:292190
initial.commit09911bf2008-07-26 23:55:292191 // Scoping effort begins, starting with the mainframe.
2192 search_frame = main_frame;
2193
2194 main_frame->ResetMatchCount();
2195
2196 do {
2197 // Cancel all old scoping requests before starting a new one.
2198 search_frame->CancelPendingScopingEffort();
2199
2200 // We don't start another scoping effort unless at least one match has
2201 // been found.
2202 if (result) {
2203 // Start new scoping request. If the scoping function determines that it
2204 // needs to scope, it will defer until later.
[email protected]7ea066a2009-04-06 20:21:592205 search_frame->ScopeStringMatches(request_id,
2206 search_text,
2207 options,
initial.commit09911bf2008-07-26 23:55:292208 true); // reset the tickmarks
2209 }
2210
2211 // Iterate to the next frame. The frame will not necessarily scope, for
2212 // example if it is not visible.
2213 search_frame = webview()->GetNextFrameAfter(search_frame, true);
2214 } while (search_frame != main_frame);
2215 }
2216}
2217
2218void RenderView::ReportFindInPageMatchCount(int count, int request_id,
2219 bool final_update) {
2220 // If we have a message that has been queued up, then we should just replace
2221 // it. The ACK from the browser will make sure it gets sent when the browser
2222 // wants it.
2223 if (queued_find_reply_message_.get()) {
2224 IPC::Message* msg = new ViewHostMsg_Find_Reply(
2225 routing_id_,
2226 request_id,
2227 count,
[email protected]b3f2b912009-04-09 16:18:522228 gfx::Rect(),
initial.commit09911bf2008-07-26 23:55:292229 -1, // Don't update active match ordinal.
2230 final_update);
2231 queued_find_reply_message_.reset(msg);
2232 } else {
2233 // Send the search result over to the browser process.
2234 Send(new ViewHostMsg_Find_Reply(
2235 routing_id_,
2236 request_id,
2237 count,
[email protected]b3f2b912009-04-09 16:18:522238 gfx::Rect(),
initial.commit09911bf2008-07-26 23:55:292239 -1, // // Don't update active match ordinal.
2240 final_update));
2241 }
2242}
2243
2244void RenderView::ReportFindInPageSelection(int request_id,
2245 int active_match_ordinal,
[email protected]b3f2b912009-04-09 16:18:522246 const WebRect& selection_rect) {
initial.commit09911bf2008-07-26 23:55:292247 // Send the search result over to the browser process.
2248 Send(new ViewHostMsg_Find_Reply(routing_id_,
2249 request_id,
2250 -1,
2251 selection_rect,
2252 active_match_ordinal,
2253 false));
2254}
2255
[email protected]ed4bf2d2009-05-05 00:10:062256bool RenderView::WasOpenedByUserGesture() const {
initial.commit09911bf2008-07-26 23:55:292257 return opened_by_user_gesture_;
2258}
2259
[email protected]7f40fc5b2009-06-12 19:23:082260void RenderView::SpellCheck(const std::wstring& word, int* misspell_location,
2261 int* misspell_length) {
2262 Send(new ViewHostMsg_SpellCheck(routing_id_, word, misspell_location,
2263 misspell_length));
initial.commit09911bf2008-07-26 23:55:292264}
2265
[email protected]26ea6c42009-06-10 22:32:212266std::wstring RenderView::GetAutoCorrectWord(
2267 const std::wstring& misspelled_word) {
2268 std::wstring autocorrect_word;
[email protected]eda2b5a2009-05-12 19:30:212269 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2270 if (command_line.HasSwitch(switches::kAutoSpellCorrect)) {
2271 Send(new ViewHostMsg_GetAutoCorrectWord(routing_id_, misspelled_word,
2272 &autocorrect_word));
2273 }
[email protected]26ea6c42009-06-10 22:32:212274
2275 return autocorrect_word;
[email protected]eda2b5a2009-05-12 19:30:212276}
2277
initial.commit09911bf2008-07-26 23:55:292278void RenderView::SetInputMethodState(bool enabled) {
2279 // Save the updated IME status and mark the input focus has been updated.
2280 // The IME status is to be sent to a browser process next time when
2281 // the input caret is rendered.
[email protected]9f23f592008-11-17 08:36:342282 if (!ime_control_busy_) {
2283 ime_control_updated_ = true;
2284 ime_control_new_state_ = enabled;
2285 }
initial.commit09911bf2008-07-26 23:55:292286}
2287
2288void RenderView::ScriptedPrint(WebFrame* frame) {
[email protected]0fda7272009-06-26 15:49:332289 Print(frame, true);
initial.commit09911bf2008-07-26 23:55:292290}
2291
initial.commit09911bf2008-07-26 23:55:292292void RenderView::UserMetricsRecordAction(const std::wstring& action) {
2293 Send(new ViewHostMsg_UserMetricsRecordAction(routing_id_, action));
2294}
2295
2296void RenderView::DnsPrefetch(const std::vector<std::string>& host_names) {
2297 Send(new ViewHostMsg_DnsPrefetch(host_names));
2298}
2299
[email protected]630e26b2008-10-14 22:55:172300void RenderView::OnZoom(int function) {
2301 static const bool kZoomIsTextOnly = false;
2302 switch (function) {
2303 case PageZoom::SMALLER:
2304 webview()->ZoomOut(kZoomIsTextOnly);
initial.commit09911bf2008-07-26 23:55:292305 break;
[email protected]630e26b2008-10-14 22:55:172306 case PageZoom::STANDARD:
2307 webview()->ResetZoom();
initial.commit09911bf2008-07-26 23:55:292308 break;
[email protected]630e26b2008-10-14 22:55:172309 case PageZoom::LARGER:
2310 webview()->ZoomIn(kZoomIsTextOnly);
initial.commit09911bf2008-07-26 23:55:292311 break;
2312 default:
2313 NOTREACHED();
2314 }
2315}
2316
[email protected]ea8c7452009-04-02 20:47:062317void RenderView::OnInsertText(const string16& text) {
[email protected]5f9e0b82009-05-08 22:13:392318 WebFrame* frame = webview()->GetFocusedFrame();
2319 if (!frame)
2320 return;
2321 WebTextInput* text_input = frame->GetTextInput();
[email protected]00d7e622009-04-21 23:06:052322 if (text_input)
[email protected]7be0e172009-05-14 01:05:272323 text_input->InsertText(text);
[email protected]ea8c7452009-04-02 20:47:062324}
2325
[email protected]e38f40152008-09-12 23:08:302326void RenderView::OnSetPageEncoding(const std::wstring& encoding_name) {
initial.commit09911bf2008-07-26 23:55:292327 webview()->SetPageEncoding(encoding_name);
2328}
2329
[email protected]f6e59a62009-05-13 21:12:032330void RenderView::NavigateBackForwardSoon(int offset) {
[email protected]f46aff62008-10-16 07:58:052331 history_back_list_count_ += offset;
2332 history_forward_list_count_ -= offset;
2333
initial.commit09911bf2008-07-26 23:55:292334 Send(new ViewHostMsg_GoToEntryAtOffset(routing_id_, offset));
2335}
2336
2337int RenderView::GetHistoryBackListCount() {
2338 return history_back_list_count_;
2339}
2340
2341int RenderView::GetHistoryForwardListCount() {
2342 return history_forward_list_count_;
2343}
2344
2345void RenderView::OnNavStateChanged(WebView* webview) {
[email protected]81a34412009-01-05 19:17:242346 if (!nav_state_sync_timer_.IsRunning()) {
2347 nav_state_sync_timer_.Start(
2348 TimeDelta::FromSeconds(delay_seconds_for_form_state_sync_), this,
2349 &RenderView::SyncNavigationState);
2350 }
initial.commit09911bf2008-07-26 23:55:292351}
2352
2353void RenderView::SetTooltipText(WebView* webview,
2354 const std::wstring& tooltip_text) {
2355 Send(new ViewHostMsg_SetTooltipText(routing_id_, tooltip_text));
2356}
2357
[email protected]2e417c82009-04-02 22:30:262358void RenderView::DidChangeSelection(bool is_empty_selection) {
2359#if defined(OS_LINUX)
[email protected]d5d7b8002009-05-18 21:20:542360 // TODO(estade): investigate incremental updates to the selection so that we
2361 // don't send the entire selection over IPC every time.
[email protected]2e417c82009-04-02 22:30:262362 if (!is_empty_selection) {
[email protected]d5d7b8002009-05-18 21:20:542363 // Sometimes we get repeated DidChangeSelection calls from webkit when
2364 // the selection hasn't actually changed. We don't want to report these
2365 // because it will cause us to continually claim the X clipboard.
2366 const std::string& this_selection =
2367 webview()->GetFocusedFrame()->GetSelection(false);
2368 if (this_selection == last_selection_)
2369 return;
2370
[email protected]dbadbcc2009-04-09 00:57:102371 Send(new ViewHostMsg_SelectionChanged(routing_id_,
[email protected]d5d7b8002009-05-18 21:20:542372 this_selection));
2373 last_selection_ = this_selection;
[email protected]4f61a022009-06-25 23:49:012374 } else {
2375 last_selection_.clear();
[email protected]2e417c82009-04-02 22:30:262376 }
2377#endif
2378}
2379
initial.commit09911bf2008-07-26 23:55:292380void RenderView::DownloadUrl(const GURL& url, const GURL& referrer) {
2381 Send(new ViewHostMsg_DownloadUrl(routing_id_, url, referrer));
2382}
2383
[email protected]0df30122009-06-03 12:13:082384void RenderView::UpdateInspectorSettings(const std::wstring& raw_settings) {
2385 Send(new ViewHostMsg_UpdateInspectorSettings(routing_id_, raw_settings));
2386}
2387
[email protected]611cad42009-03-16 18:51:342388WebDevToolsAgentDelegate* RenderView::GetWebDevToolsAgentDelegate() {
[email protected]b75b7d072009-04-06 13:47:002389 return devtools_agent_.get();
[email protected]611cad42009-03-16 18:51:342390}
2391
[email protected]ea8c7452009-04-02 20:47:062392void RenderView::PasteFromSelectionClipboard() {
2393 Send(new ViewHostMsg_PasteFromSelectionClipboard(routing_id_));
2394}
2395
initial.commit09911bf2008-07-26 23:55:292396WebFrame* RenderView::GetChildFrame(const std::wstring& frame_xpath) const {
2397 WebFrame* web_frame;
2398 if (frame_xpath.empty()) {
2399 web_frame = webview()->GetMainFrame();
2400 } else {
2401 web_frame = webview()->GetMainFrame()->GetChildFrame(frame_xpath);
2402 }
2403
2404 return web_frame;
2405}
2406
[email protected]f29acf52008-11-03 20:08:332407void RenderView::EvaluateScript(const std::wstring& frame_xpath,
2408 const std::wstring& script) {
initial.commit09911bf2008-07-26 23:55:292409 WebFrame* web_frame = GetChildFrame(frame_xpath);
2410 if (!web_frame)
2411 return;
2412
[email protected]4f999132009-03-31 18:08:402413 web_frame->ExecuteScript(WebScriptSource(WideToUTF16Hack(script)));
initial.commit09911bf2008-07-26 23:55:292414}
2415
[email protected]1810e132009-03-24 23:35:482416void RenderView::InsertCSS(const std::wstring& frame_xpath,
2417 const std::string& css) {
2418 WebFrame* web_frame = GetChildFrame(frame_xpath);
2419 if (!web_frame)
2420 return;
2421
2422 web_frame->InsertCSSStyles(css);
2423}
2424
initial.commit09911bf2008-07-26 23:55:292425void RenderView::OnScriptEvalRequest(const std::wstring& frame_xpath,
2426 const std::wstring& jscript) {
[email protected]f29acf52008-11-03 20:08:332427 EvaluateScript(frame_xpath, jscript);
initial.commit09911bf2008-07-26 23:55:292428}
2429
[email protected]1810e132009-03-24 23:35:482430void RenderView::OnCSSInsertRequest(const std::wstring& frame_xpath,
2431 const std::string& css) {
2432 InsertCSS(frame_xpath, css);
[email protected]ae461542009-06-19 19:03:412433
2434 // Notify RenderViewHost that css has been inserted into the frame.
2435 Send(new ViewHostMsg_OnCSSInserted(routing_id_));
[email protected]1810e132009-03-24 23:35:482436}
2437
[email protected]7ea066a2009-04-06 20:21:592438void RenderView::OnAddMessageToConsole(
2439 const string16& frame_xpath,
2440 const string16& message,
2441 const WebConsoleMessage::Level& level) {
2442 WebFrame* web_frame = GetChildFrame(UTF16ToWideHack(frame_xpath));
[email protected]0dea3ea2009-03-31 23:30:592443 if (web_frame)
[email protected]7ea066a2009-04-06 20:21:592444 web_frame->AddMessageToConsole(WebConsoleMessage(level, message));
initial.commit09911bf2008-07-26 23:55:292445}
2446
[email protected]81e63782009-02-27 19:35:092447void RenderView::OnAllowBindings(int enabled_bindings_flags) {
2448 enabled_bindings_ |= enabled_bindings_flags;
initial.commit09911bf2008-07-26 23:55:292449}
2450
2451void RenderView::OnSetDOMUIProperty(const std::string& name,
2452 const std::string& value) {
[email protected]81e63782009-02-27 19:35:092453 DCHECK(BindingsPolicy::is_dom_ui_enabled(enabled_bindings_));
initial.commit09911bf2008-07-26 23:55:292454 dom_ui_bindings_.SetProperty(name, value);
2455}
2456
2457void RenderView::OnReservePageIDRange(int size_of_range) {
2458 next_page_id_ += size_of_range + 1;
2459}
2460
[email protected]e80c73b2009-04-07 23:24:582461void RenderView::OnDragSourceEndedOrMoved(const gfx::Point& client_point,
2462 const gfx::Point& screen_point,
initial.commit09911bf2008-07-26 23:55:292463 bool ended) {
2464 if (ended)
[email protected]e80c73b2009-04-07 23:24:582465 webview()->DragSourceEndedAt(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292466 else
[email protected]e80c73b2009-04-07 23:24:582467 webview()->DragSourceMovedTo(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292468}
2469
2470void RenderView::OnDragSourceSystemDragEnded() {
2471 webview()->DragSourceSystemDragEnded();
2472}
2473
2474void RenderView::OnUploadFileRequest(const ViewMsg_UploadFile_Params& p) {
2475 webkit_glue::FileUploadData* f = new webkit_glue::FileUploadData;
2476 f->file_path = p.file_path;
2477 f->form_name = p.form;
2478 f->file_name = p.file;
2479 f->submit_name = p.submit;
2480
2481 // Build the other form values map.
2482 if (!p.other_values.empty()) {
2483 std::vector<std::wstring> e;
2484 std::vector<std::wstring> kvp;
2485 std::vector<std::wstring>::iterator i;
2486
2487 SplitString(p.other_values, L'\n', &e);
2488 for (i = e.begin(); i != e.end(); ++i) {
2489 SplitString(*i, L'=', &kvp);
2490 if (kvp.size() == 2)
2491 f->other_form_values[kvp[0]] = kvp[1];
2492 kvp.clear();
2493 }
2494 }
2495
2496 pending_upload_data_.reset(f);
2497 ProcessPendingUpload();
2498}
2499
2500void RenderView::ProcessPendingUpload() {
2501 webkit_glue::FileUploadData* f = pending_upload_data_.get();
2502 if (f && webview() && webkit_glue::FillFormToUploadFile(webview(), *f))
2503 ResetPendingUpload();
2504}
2505
2506void RenderView::ResetPendingUpload() {
2507 pending_upload_data_.reset();
2508}
2509
2510void RenderView::OnFormFill(const FormData& form) {
2511 webkit_glue::FillForm(this->webview(), form);
2512}
2513
2514void RenderView::OnFillPasswordForm(
[email protected]daa8c58e2009-06-15 17:21:102515 const webkit_glue::PasswordFormDomManager::FillData& form_data) {
initial.commit09911bf2008-07-26 23:55:292516 webkit_glue::FillPasswordForm(this->webview(), form_data);
2517}
2518
2519void RenderView::OnDragTargetDragEnter(const WebDropData& drop_data,
[email protected]e80c73b2009-04-07 23:24:582520 const gfx::Point& client_point,
2521 const gfx::Point& screen_point) {
2522 bool is_drop_target = webview()->DragTargetDragEnter(
2523 drop_data.ToDragData(),
2524 drop_data.identity,
2525 client_point,
2526 screen_point);
initial.commit09911bf2008-07-26 23:55:292527
2528 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target));
2529}
2530
[email protected]e80c73b2009-04-07 23:24:582531void RenderView::OnDragTargetDragOver(const gfx::Point& client_point,
2532 const gfx::Point& screen_point) {
2533 bool is_drop_target =
2534 webview()->DragTargetDragOver(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292535
2536 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target));
2537}
2538
2539void RenderView::OnDragTargetDragLeave() {
2540 webview()->DragTargetDragLeave();
2541}
2542
[email protected]e80c73b2009-04-07 23:24:582543void RenderView::OnDragTargetDrop(const gfx::Point& client_point,
2544 const gfx::Point& screen_point) {
2545 webview()->DragTargetDrop(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292546}
2547
2548void RenderView::OnUpdateWebPreferences(const WebPreferences& prefs) {
2549 webview()->SetPreferences(prefs);
2550}
2551
2552void RenderView::OnSetAltErrorPageURL(const GURL& url) {
2553 alternate_error_page_url_ = url;
2554}
2555
initial.commit09911bf2008-07-26 23:55:292556void RenderView::OnInstallMissingPlugin() {
2557 // This could happen when the first default plugin is deleted.
2558 if (first_default_plugin_ == NULL)
2559 return;
2560 first_default_plugin_->InstallMissingPlugin();
2561}
2562
[email protected]b62d1a8c2009-01-13 23:54:572563void RenderView::OnFileChooserResponse(
[email protected]561abe62009-04-06 18:08:342564 const std::vector<FilePath>& file_names) {
[email protected]8029f5672009-03-20 22:33:362565 // This could happen if we navigated to a different page before the user
2566 // closed the chooser.
2567 if (!file_chooser_.get())
2568 return;
2569
[email protected]b62d1a8c2009-01-13 23:54:572570 file_chooser_->OnFileChoose(file_names);
initial.commit09911bf2008-07-26 23:55:292571 file_chooser_.reset();
2572}
2573
2574void RenderView::OnEnableViewSourceMode() {
2575 if (!webview())
2576 return;
2577 WebFrame* main_frame = webview()->GetMainFrame();
2578 if (!main_frame)
2579 return;
2580
2581 main_frame->SetInViewSourceMode(true);
2582}
2583
[email protected]0666aef2009-05-13 19:48:082584void RenderView::OnEnableIntrinsicWidthChangedMode() {
2585 send_preferred_width_changes_ = true;
2586}
2587
[email protected]80d96fa2009-06-10 22:34:512588void RenderView::OnSetRendererPrefs(const RendererPreferences& renderer_prefs) {
2589 renderer_preferences_ = renderer_prefs;
2590}
2591
initial.commit09911bf2008-07-26 23:55:292592void RenderView::OnUpdateBackForwardListCount(int back_list_count,
2593 int forward_list_count) {
2594 history_back_list_count_ = back_list_count;
2595 history_forward_list_count_ = forward_list_count;
2596}
2597
[email protected]266eb6f2008-09-30 23:56:502598void RenderView::OnGetAccessibilityInfo(
[email protected]6a983b42009-03-20 20:12:252599 const webkit_glue::WebAccessibility::InParams& in_params,
2600 webkit_glue::WebAccessibility::OutParams* out_params) {
[email protected]6c8afae52009-01-22 02:24:572601#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:252602 if (!web_accessibility_manager_.get()) {
2603 web_accessibility_manager_.reset(
2604 webkit_glue::WebAccessibilityManager::Create());
2605 }
[email protected]266eb6f2008-09-30 23:56:502606
[email protected]6a983b42009-03-20 20:12:252607 if (!web_accessibility_manager_->GetAccObjInfo(webview(), in_params,
2608 out_params)) {
[email protected]266eb6f2008-09-30 23:56:502609 return;
2610 }
[email protected]6c8afae52009-01-22 02:24:572611#else // defined(OS_WIN)
2612 // TODO(port): accessibility not yet implemented
2613 NOTIMPLEMENTED();
2614#endif
[email protected]266eb6f2008-09-30 23:56:502615}
2616
[email protected]6a983b42009-03-20 20:12:252617void RenderView::OnClearAccessibilityInfo(int acc_obj_id, bool clear_all) {
[email protected]6c8afae52009-01-22 02:24:572618#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:252619 if (!web_accessibility_manager_.get()) {
[email protected]266eb6f2008-09-30 23:56:502620 // If accessibility is not activated, ignore clearing message.
2621 return;
2622 }
[email protected]e846d0d2009-05-20 00:53:062623
[email protected]6a983b42009-03-20 20:12:252624 if (!web_accessibility_manager_->ClearAccObjMap(acc_obj_id, clear_all))
[email protected]266eb6f2008-09-30 23:56:502625 return;
[email protected]e846d0d2009-05-20 00:53:062626
[email protected]6c8afae52009-01-22 02:24:572627#else // defined(OS_WIN)
2628 // TODO(port): accessibility not yet implemented
2629 NOTIMPLEMENTED();
2630#endif
[email protected]266eb6f2008-09-30 23:56:502631}
2632
initial.commit09911bf2008-07-26 23:55:292633void RenderView::OnGetAllSavableResourceLinksForCurrentPage(
2634 const GURL& page_url) {
2635 // Prepare list to storage all savable resource links.
2636 std::vector<GURL> resources_list;
2637 std::vector<GURL> referrers_list;
2638 std::vector<GURL> frames_list;
2639 webkit_glue::SavableResourcesResult result(&resources_list,
2640 &referrers_list,
2641 &frames_list);
2642
2643 if (!webkit_glue::GetAllSavableResourceLinksForCurrentPage(webview(),
2644 page_url,
2645 &result)) {
2646 // If something is wrong when collecting all savable resource links,
2647 // send empty list to embedder(browser) to tell it failed.
2648 referrers_list.clear();
2649 resources_list.clear();
2650 frames_list.clear();
2651 }
2652
2653 // Send result of all savable resource links to embedder.
2654 Send(new ViewHostMsg_SendCurrentPageAllSavableResourceLinks(routing_id_,
2655 resources_list,
2656 referrers_list,
2657 frames_list));
2658}
2659
2660void RenderView::OnGetSerializedHtmlDataForCurrentPageWithLocalLinks(
[email protected]f6b48532009-02-12 01:56:322661 const std::vector<GURL>& links,
[email protected]fde6714d12009-02-18 22:39:312662 const std::vector<FilePath>& local_paths,
2663 const FilePath& local_directory_name) {
initial.commit09911bf2008-07-26 23:55:292664 webkit_glue::DomSerializer dom_serializer(webview()->GetMainFrame(),
2665 true,
2666 this,
2667 links,
2668 local_paths,
2669 local_directory_name);
2670 dom_serializer.SerializeDom();
2671}
2672
2673void RenderView::DidSerializeDataForFrame(const GURL& frame_url,
2674 const std::string& data, PageSavingSerializationStatus status) {
2675 Send(new ViewHostMsg_SendSerializedHtmlData(routing_id_,
2676 frame_url, data, static_cast<int32>(status)));
2677}
2678
[email protected]04b4a6c2008-08-02 00:44:472679void RenderView::OnMsgShouldClose() {
initial.commit09911bf2008-07-26 23:55:292680 bool should_close = webview()->ShouldClose();
[email protected]04b4a6c2008-08-02 00:44:472681 Send(new ViewHostMsg_ShouldClose_ACK(routing_id_, should_close));
initial.commit09911bf2008-07-26 23:55:292682}
2683
2684void RenderView::OnClosePage(int new_render_process_host_id,
[email protected]04b4a6c2008-08-02 00:44:472685 int new_request_id) {
initial.commit09911bf2008-07-26 23:55:292686 // TODO(creis): We'd rather use webview()->Close() here, but that currently
2687 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs
2688 // in the onunload handler from appearing. For now, we're bypassing that and
2689 // calling the FrameLoader's CloseURL method directly. This should be
2690 // revisited to avoid having two ways to close a page. Having a single way
2691 // to close that can run onunload is also useful for fixing
2692 // http://b/issue?id=753080.
2693 WebFrame* main_frame = webview()->GetMainFrame();
[email protected]7a9b51f2009-06-29 21:28:292694 if (main_frame) {
2695 const GURL& url = main_frame->GetURL();
2696 // TODO(davemoore) this code should be removed once WillCloseFrame() gets
2697 // called when a page is destroyed. DumpLoadHistograms() is safe to call
2698 // multiple times for the same frame, but it will simplify things.
2699 if (url.SchemeIs("http") || url.SchemeIs("https"))
2700 DumpLoadHistograms();
initial.commit09911bf2008-07-26 23:55:292701 main_frame->ClosePage();
[email protected]7a9b51f2009-06-29 21:28:292702 }
initial.commit09911bf2008-07-26 23:55:292703
2704 Send(new ViewHostMsg_ClosePage_ACK(routing_id_,
2705 new_render_process_host_id,
[email protected]04b4a6c2008-08-02 00:44:472706 new_request_id));
initial.commit09911bf2008-07-26 23:55:292707}
2708
2709void RenderView::OnThemeChanged() {
[email protected]6c8afae52009-01-22 02:24:572710#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292711 gfx::NativeTheme::instance()->CloseHandles();
2712 gfx::Rect view_rect(0, 0, size_.width(), size_.height());
2713 DidInvalidateRect(webwidget_, view_rect);
[email protected]6c8afae52009-01-22 02:24:572714#else // defined(OS_WIN)
2715 // TODO(port): we don't support theming on non-Windows platforms yet
2716 NOTIMPLEMENTED();
2717#endif
initial.commit09911bf2008-07-26 23:55:292718}
2719
[email protected]f46aff62008-10-16 07:58:052720void RenderView::DidAddHistoryItem() {
[email protected]f8901082008-10-31 23:34:032721 // We don't want to update the history length for the start page
2722 // navigation.
2723 WebFrame* main_frame = webview()->GetMainFrame();
2724 DCHECK(main_frame != NULL);
2725
2726 WebDataSource* ds = main_frame->GetDataSource();
2727 DCHECK(ds != NULL);
2728
[email protected]daa8c58e2009-06-15 17:21:102729 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
2730 if (navigation_state->transition_type() == PageTransition::START_PAGE)
[email protected]f8901082008-10-31 23:34:032731 return;
2732
[email protected]f46aff62008-10-16 07:58:052733 history_back_list_count_++;
2734 history_forward_list_count_ = 0;
2735}
2736
[email protected]28790922009-03-09 19:48:372737void RenderView::OnMessageFromExternalHost(const std::string& message,
2738 const std::string& origin,
2739 const std::string& target) {
[email protected]3ac14a052008-08-15 21:22:152740 if (message.empty())
2741 return;
2742
[email protected]28790922009-03-09 19:48:372743 external_host_bindings_.ForwardMessageFromExternalHost(message, origin,
2744 target);
[email protected]3ac14a052008-08-15 21:22:152745}
2746
[email protected]0aa55312008-10-17 21:53:082747void RenderView::OnDisassociateFromPopupCount() {
2748 if (decrement_shared_popup_at_destruction_)
2749 shared_popup_counter_->data--;
2750 shared_popup_counter_ = new SharedRenderViewCounter(0);
2751 decrement_shared_popup_at_destruction_ = false;
2752}
2753
initial.commit09911bf2008-07-26 23:55:292754std::string RenderView::GetAltHTMLForTemplate(
2755 const DictionaryValue& error_strings, int template_resource_id) const {
2756 const StringPiece template_html(
2757 ResourceBundle::GetSharedInstance().GetRawDataResource(
2758 template_resource_id));
2759
2760 if (template_html.empty()) {
2761 NOTREACHED() << "unable to load template. ID: " << template_resource_id;
2762 return "";
2763 }
2764 // "t" is the id of the templates root node.
2765 return jstemplate_builder::GetTemplateHtml(
2766 template_html, &error_strings, "t");
2767}
[email protected]0e79b9e2009-02-13 04:20:482768
2769MessageLoop* RenderView::GetMessageLoopForIO() {
2770 // Assume that we have only one RenderThread in the process and the owner loop
2771 // of RenderThread is an IO message loop.
[email protected]8930d472009-02-21 08:05:282772 if (RenderThread::current())
2773 return RenderThread::current()->owner_loop();
[email protected]0e79b9e2009-02-13 04:20:482774 return NULL;
2775}
[email protected]6f56d482009-02-20 05:02:562776
[email protected]30f75e62009-02-25 22:01:002777void RenderView::OnMoveOrResizeStarted() {
2778 if (webview())
2779 webview()->HideAutofillPopup();
2780}
2781
[email protected]30f75e62009-02-25 22:01:002782void RenderView::OnResize(const gfx::Size& new_size,
2783 const gfx::Rect& resizer_rect) {
2784 if (webview())
2785 webview()->HideAutofillPopup();
2786 RenderWidget::OnResize(new_size, resizer_rect);
2787}
[email protected]0aa477bd2009-03-23 22:21:432788
[email protected]05d478752009-04-08 23:38:162789void RenderView::OnClearFocusedNode() {
2790 if (webview())
2791 webview()->ClearFocusedNode();
2792}
2793
[email protected]699ab0d2009-04-23 23:19:142794void RenderView::OnSetBackground(const SkBitmap& background) {
2795 if (webview())
2796 webview()->SetIsTransparent(!background.empty());
2797
2798 SetBackground(background);
2799}
2800
[email protected]309d7a282009-03-24 09:18:272801void RenderView::SendExtensionRequest(const std::string& name,
2802 const std::string& args,
[email protected]c6619182009-05-12 14:59:322803 int request_id,
[email protected]2f25d7b92009-06-10 00:06:472804 bool has_callback) {
[email protected]c6619182009-05-12 14:59:322805 Send(new ViewHostMsg_ExtensionRequest(routing_id_, name, args, request_id,
[email protected]2f25d7b92009-06-10 00:06:472806 has_callback));
[email protected]309d7a282009-03-24 09:18:272807}
2808
[email protected]c6619182009-05-12 14:59:322809void RenderView::OnExtensionResponse(int request_id,
2810 bool success,
2811 const std::string& response,
2812 const std::string& error) {
[email protected]4083f052009-06-30 19:52:092813 EventBindings::HandleResponse(request_id, success, response, error);
[email protected]309d7a282009-03-24 09:18:272814}
[email protected]c20210e62009-04-03 21:39:262815
[email protected]e7e4f3c2009-04-21 15:24:082816// Dump all load time histograms.
[email protected]c20210e62009-04-03 21:39:262817//
[email protected]7a9b51f2009-06-29 21:28:292818// There are 13 histograms measuring various times.
[email protected]c20210e62009-04-03 21:39:262819// The time points we keep are
2820// request: time document was requested by user
2821// start: time load of document started
[email protected]a2f6bc112009-06-27 16:27:252822// commit: time load of document started
[email protected]7a9b51f2009-06-29 21:28:292823// finish_document: main document loaded, before onload()
[email protected]c20210e62009-04-03 21:39:262824// finish: after onload() and all resources are loaded
[email protected]7a9b51f2009-06-29 21:28:292825// first_paint: first paint performed
2826// first_paint_after_load: first paint performed after load is finished
2827// begin: request if it was user requested, start otherwise
2828//
[email protected]c20210e62009-04-03 21:39:262829// The times that we histogram are
[email protected]a2f6bc112009-06-27 16:27:252830// request->start,
[email protected]7a9b51f2009-06-29 21:28:292831// start->commit,
2832// commit->finish_document,
2833// finish_document->finish,
2834// begin->commit,
2835// begin->finishDoc,
2836// begin->finish,
2837// begin->first_paint,
2838// begin->first_paint_after_load
2839// commit->finishDoc,
2840// commit->first_paint,
2841// commit->first_paint_after_load,
2842// finish->first_paint_after_load,
[email protected]c20210e62009-04-03 21:39:262843//
[email protected]e7e4f3c2009-04-21 15:24:082844// It's possible for the request time not to be set, if a client
2845// redirect had been done (the user never requested the page)
2846// Also, it's possible to load a page without ever laying it out
[email protected]7a9b51f2009-06-29 21:28:292847// so first_paint and first_paint_after_load can be 0.
[email protected]c20210e62009-04-03 21:39:262848void RenderView::DumpLoadHistograms() const {
2849 WebFrame* main_frame = webview()->GetMainFrame();
[email protected]ed3fb032009-06-16 19:50:562850 NavigationState* navigation_state =
2851 NavigationState::FromDataSource(main_frame->GetDataSource());
[email protected]7a9b51f2009-06-29 21:28:292852 Time finish = navigation_state->finish_load_time();
[email protected]ed3fb032009-06-16 19:50:562853
[email protected]7a9b51f2009-06-29 21:28:292854 // If we've already dumped or we haven't finished loading, do nothing.
2855 if (navigation_state->load_histograms_recorded() || finish.is_null())
2856 return;
[email protected]ed3fb032009-06-16 19:50:562857
[email protected]7a9b51f2009-06-29 21:28:292858 Time request = navigation_state->request_time();
2859 Time start = navigation_state->start_load_time();
2860 Time commit = navigation_state->commit_load_time();
2861 Time finish_doc = navigation_state->finish_document_load_time();
2862 Time first_paint = navigation_state->first_paint_time();
2863 Time first_paint_after_load =
2864 navigation_state->first_paint_after_load_time();
[email protected]c20210e62009-04-03 21:39:262865
[email protected]7a9b51f2009-06-29 21:28:292866 Time begin;
2867 // Client side redirects will have no request time.
2868 if (request.is_null()) {
2869 begin = start;
2870 } else {
2871 begin = request;
2872 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer4.RequestToStart", start - request);
[email protected]e7e4f3c2009-04-21 15:24:082873 }
[email protected]7a9b51f2009-06-29 21:28:292874 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer4.StartToCommit", commit - start);
2875 UMA_HISTOGRAM_MEDIUM_TIMES(
2876 "Renderer4.CommitToFinishDoc", finish_doc - commit);
2877 UMA_HISTOGRAM_MEDIUM_TIMES(
2878 "Renderer4.FinishDocToFinish", finish - finish_doc);
2879
2880 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer4.BeginToCommit", commit - begin);
2881 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer4.BeginToFinishDoc", finish_doc - begin);
[email protected]e695fbd62009-06-30 16:31:542882
2883 static const TimeDelta kBeginToFinishMin(TimeDelta::FromMilliseconds(10));
2884 static const TimeDelta kBeginToFinishMax(TimeDelta::FromMinutes(10));
2885 static const size_t kBeginToFinishBucketCount(100);
2886
2887 UMA_HISTOGRAM_CUSTOM_TIMES("Renderer4.BeginToFinish",
2888 finish - begin, kBeginToFinishMin,
2889 kBeginToFinishMax, kBeginToFinishBucketCount);
2890
[email protected]36285b52009-06-30 19:10:002891 static bool use_dns_histogram(FieldTrialList::Find("DnsImpact") &&
2892 !FieldTrialList::Find("DnsImpact")->group_name().empty());
2893 if (use_dns_histogram)
2894 UMA_HISTOGRAM_CUSTOM_TIMES(
2895 FieldTrial::MakeName("Renderer4.BeginToFinish", "DnsImpact").data(),
2896 finish - begin, kBeginToFinishMin,
2897 kBeginToFinishMax, kBeginToFinishBucketCount);
[email protected]e695fbd62009-06-30 16:31:542898
[email protected]36285b52009-06-30 19:10:002899 static bool use_sdch_histogram(FieldTrialList::Find("GlobalSdch") &&
2900 !FieldTrialList::Find("GlobalSdch")->group_name().empty());
2901 if (use_sdch_histogram)
2902 UMA_HISTOGRAM_CUSTOM_TIMES(
2903 FieldTrial::MakeName("Renderer4.BeginToFinish", "GlobalSdch").data(),
2904 finish - begin, kBeginToFinishMin,
2905 kBeginToFinishMax, kBeginToFinishBucketCount);
[email protected]7a9b51f2009-06-29 21:28:292906
2907 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer4.CommitToFinish", finish - commit);
2908
2909 if (!first_paint.is_null()) {
2910 UMA_HISTOGRAM_MEDIUM_TIMES(
2911 "Renderer4.BeginToFirstPaint", first_paint - begin);
2912 UMA_HISTOGRAM_MEDIUM_TIMES(
2913 "Renderer4.CommitToFirstPaint", first_paint - commit);
[email protected]c20210e62009-04-03 21:39:262914 }
[email protected]7a9b51f2009-06-29 21:28:292915
2916 if (!first_paint_after_load.is_null()) {
2917 UMA_HISTOGRAM_MEDIUM_TIMES(
2918 "Renderer4.BeginToFirstPaintAfterLoad", first_paint_after_load - begin);
2919 UMA_HISTOGRAM_MEDIUM_TIMES(
2920 "Renderer4.CommitToFirstPaintAfterLoad",
2921 first_paint_after_load - commit);
2922 UMA_HISTOGRAM_MEDIUM_TIMES(
2923 "Renderer4.FinishToFirstPaintAfterLoad",
2924 first_paint_after_load - finish);
2925 }
2926
2927 navigation_state->set_load_histograms_recorded(true);
[email protected]c20210e62009-04-03 21:39:262928}
[email protected]e846d0d2009-05-20 00:53:062929
2930void RenderView::FocusAccessibilityObject(
2931 WebCore::AccessibilityObject* acc_obj) {
2932#if defined(OS_WIN)
2933 if (!web_accessibility_manager_.get()) {
2934 web_accessibility_manager_.reset(
2935 webkit_glue::WebAccessibilityManager::Create());
2936 }
2937
2938 // Retrieve the accessibility object id of the AccessibilityObject.
2939 int acc_obj_id = web_accessibility_manager_->FocusAccObj(acc_obj);
2940
2941 // If id is valid, alert the browser side that an accessibility focus change
2942 // occurred.
2943 if (acc_obj_id >= 0)
2944 Send(new ViewHostMsg_AccessibilityFocusChange(routing_id_, acc_obj_id));
2945
2946#else // defined(OS_WIN)
2947 // TODO(port): accessibility not yet implemented
2948 NOTIMPLEMENTED();
2949#endif
2950}
[email protected]daa8c58e2009-06-15 17:21:102951
2952void RenderView::SendPasswordForms(WebFrame* frame) {
2953 std::vector<WebForm> forms;
2954 frame->GetForms(&forms);
2955
2956 std::vector<PasswordForm> password_forms;
2957 for (size_t i = 0; i < forms.size(); ++i) {
2958 const WebForm& form = forms[i];
2959
2960 // Respect autocomplete=off.
2961 if (form.isAutoCompleteEnabled()) {
2962 scoped_ptr<PasswordForm> password_form(
2963 PasswordFormDomManager::CreatePasswordForm(form));
2964 if (password_form.get())
2965 password_forms.push_back(*password_form);
2966 }
2967 }
2968
2969 if (!password_forms.empty())
2970 Send(new ViewHostMsg_PasswordFormsSeen(routing_id_, password_forms));
2971}
[email protected]0fda7272009-06-26 15:49:332972
2973void RenderView::Print(WebFrame* frame, bool script_initiated) {
2974 DCHECK(frame);
2975 if (print_helper_.get() == NULL) {
2976 print_helper_.reset(new PrintWebViewHelper(this));
2977 }
2978 print_helper_->Print(frame, script_initiated);
2979}