blob: 051b8d6f0d422ac7dd51634d249d7e423812b091 [file] [log] [blame]
[email protected]05d478752009-04-08 23:38:161// Copyright (c) 2009 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/renderer/render_view.h"
6
7#include <algorithm>
8#include <string>
9#include <vector>
10
[email protected]91e81ae2009-05-08 22:14:3811#include "app/gfx/color_utils.h"
[email protected]37126212009-05-06 02:23:3112#include "app/gfx/favicon_size.h"
[email protected]a92b8642009-05-05 23:38:5613#include "app/l10n_util.h"
[email protected]37126212009-05-06 02:23:3114#include "app/message_box_flags.h"
[email protected]9929da92009-05-05 02:05:1115#include "app/resource_bundle.h"
initial.commit09911bf2008-07-26 23:55:2916#include "base/command_line.h"
[email protected]bb063b72009-03-27 23:18:5017#include "base/compiler_specific.h"
[email protected]4646f292009-05-20 03:49:0518#include "base/field_trial.h"
initial.commit09911bf2008-07-26 23:55:2919#include "base/gfx/png_encoder.h"
[email protected]18bcc3c2009-01-27 21:39:1520#include "base/gfx/native_widget_types.h"
[email protected]8380c092009-06-25 17:45:5121#include "base/process_util.h"
initial.commit09911bf2008-07-26 23:55:2922#include "base/string_piece.h"
23#include "base/string_util.h"
[email protected]6c8afae52009-01-22 02:24:5724#include "build/build_config.h"
[email protected]81e63782009-02-27 19:35:0925#include "chrome/common/bindings_policy.h"
initial.commit09911bf2008-07-26 23:55:2926#include "chrome/common/chrome_switches.h"
[email protected]f0af6a72009-05-30 05:25:1727#include "chrome/common/chrome_constants.h"
initial.commit09911bf2008-07-26 23:55:2928#include "chrome/common/jstemplate_builder.h"
[email protected]630e26b2008-10-14 22:55:1729#include "chrome/common/page_zoom.h"
[email protected]e09ba552009-02-05 03:26:2930#include "chrome/common/render_messages.h"
[email protected]9b6f40e2009-06-11 15:54:2631#include "chrome/common/renderer_preferences.h"
initial.commit09911bf2008-07-26 23:55:2932#include "chrome/common/thumbnail_score.h"
[email protected]6de74452009-02-25 18:04:5933#include "chrome/common/url_constants.h"
initial.commit09911bf2008-07-26 23:55:2934#include "chrome/renderer/about_handler.h"
[email protected]5fb88962009-04-16 19:03:2535#include "chrome/renderer/audio_message_filter.h"
[email protected]e4ac5df2009-03-17 15:33:1136#include "chrome/renderer/devtools_agent.h"
37#include "chrome/renderer/devtools_client.h"
[email protected]309d7a282009-03-24 09:18:2738#include "chrome/renderer/extensions/extension_process_bindings.h"
initial.commit09911bf2008-07-26 23:55:2939#include "chrome/renderer/localized_error.h"
[email protected]6f56d482009-02-20 05:02:5640#include "chrome/renderer/media/audio_renderer_impl.h"
[email protected]add51772009-06-11 18:25:1741#include "chrome/renderer/media/buffered_data_source.h"
[email protected]ed3fb032009-06-16 19:50:5642#include "chrome/renderer/navigation_state.h"
[email protected]d81c1e52009-06-03 22:09:5043#include "chrome/renderer/print_web_view_helper.h"
[email protected]39008c02009-02-11 23:59:2544#include "chrome/renderer/render_process.h"
[email protected]fcf19542009-03-30 21:24:0745#include "chrome/renderer/renderer_logging.h"
[email protected]0938d3c2009-01-09 20:37:3546#include "chrome/renderer/user_script_slave.h"
initial.commit09911bf2008-07-26 23:55:2947#include "chrome/renderer/visitedlink_slave.h"
[email protected]ba4b17f2009-02-11 21:32:2948#include "chrome/renderer/webplugin_delegate_proxy.h"
[email protected]eb47a132009-03-04 00:39:5649#include "chrome/renderer/webworker_proxy.h"
[email protected]34ac8f32009-02-22 23:03:2750#include "grit/generated_resources.h"
51#include "grit/renderer_resources.h"
[email protected]f11ca0732009-04-11 00:09:3452#include "net/base/data_url.h"
initial.commit09911bf2008-07-26 23:55:2953#include "net/base/escape.h"
54#include "net/base/net_errors.h"
[email protected]c399a8a2008-11-22 19:38:0055#include "skia/ext/bitmap_platform_device.h"
[email protected]83c9e6552008-12-03 16:22:1056#include "skia/ext/image_operations.h"
[email protected]726985e22009-06-18 21:09:2857#include "webkit/api/public/WebDataSource.h"
[email protected]afdcf5c2009-05-10 20:30:4158#include "webkit/api/public/WebDragData.h"
[email protected]daa8c58e2009-06-15 17:21:1059#include "webkit/api/public/WebForm.h"
[email protected]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]726985e22009-06-18 21:09:28103using WebKit::WebDataSource;
[email protected]e80c73b2009-04-07 23:24:58104using WebKit::WebDragData;
[email protected]daa8c58e2009-06-15 17:21:10105using WebKit::WebForm;
[email protected]ca948a22009-06-25 19:36:17106using WebKit::WebHistoryItem;
[email protected]726985e22009-06-18 21:09:28107using WebKit::WebNavigationType;
[email protected]b3f2b912009-04-09 16:18:52108using WebKit::WebRect;
[email protected]4f999132009-03-31 18:08:40109using WebKit::WebScriptSource;
[email protected]8649fb32009-06-26 17:51:02110using WebKit::WebSize;
[email protected]726985e22009-06-18 21:09:28111using WebKit::WebString;
112using WebKit::WebURL;
113using WebKit::WebURLError;
114using WebKit::WebURLRequest;
115using WebKit::WebURLResponse;
[email protected]27ba8532009-04-24 20:22:43116using WebKit::WebWorker;
117using WebKit::WebWorkerClient;
[email protected]726985e22009-06-18 21:09:28118using WebKit::WebVector;
[email protected]e1acf6f2008-10-27 20:43:33119
initial.commit09911bf2008-07-26 23:55:29120//-----------------------------------------------------------------------------
121
122// define to write the time necessary for thumbnail/DOM text retrieval,
123// respectively, into the system debug log
124// #define TIME_BITMAP_RETRIEVAL
125// #define TIME_TEXT_RETRIEVAL
126
127// maximum number of characters in the document to index, any text beyond this
128// point will be clipped
[email protected]6c8afae52009-01-22 02:24:57129static const size_t kMaxIndexChars = 65535;
initial.commit09911bf2008-07-26 23:55:29130
131// Size of the thumbnails that we'll generate
132static const int kThumbnailWidth = 196;
133static const int kThumbnailHeight = 136;
134
135// Delay in milliseconds that we'll wait before capturing the page contents
136// and thumbnail.
137static const int kDelayForCaptureMs = 500;
138
139// Typically, we capture the page data once the page is loaded.
140// Sometimes, the page never finishes to load, preventing the page capture
141// To workaround this problem, we always perform a capture after the following
142// delay.
143static const int kDelayForForcedCaptureMs = 6000;
144
[email protected]81a34412009-01-05 19:17:24145// The default value for RenderView.delay_seconds_for_form_state_sync_, see
146// that variable for more.
147const int kDefaultDelaySecondsForFormStateSync = 5;
initial.commit09911bf2008-07-26 23:55:29148
149// The next available page ID to use. This ensures that the page IDs are
150// globally unique in the renderer.
151static int32 next_page_id_ = 1;
152
[email protected]0aa55312008-10-17 21:53:08153// The maximum number of popups that can be spawned from one page.
154static const int kMaximumNumberOfUnacknowledgedPopups = 25;
155
initial.commit09911bf2008-07-26 23:55:29156static const char* const kUnreachableWebDataURL =
[email protected]60e448982009-05-06 04:21:16157 "chrome://chromewebdata/";
initial.commit09911bf2008-07-26 23:55:29158
[email protected]50b691c2008-10-31 19:08:35159static const char* const kBackForwardNavigationScheme = "history";
160
[email protected]726985e22009-06-18 21:09:28161static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
162 WebVector<WebURL> urls;
163 ds->redirectChain(urls);
164 result->reserve(urls.size());
165 for (size_t i = 0; i < urls.size(); ++i)
166 result->push_back(urls[i]);
167}
168
initial.commit09911bf2008-07-26 23:55:29169///////////////////////////////////////////////////////////////////////////////
170
[email protected]81a34412009-01-05 19:17:24171RenderView::RenderView(RenderThreadBase* render_thread)
172 : RenderWidget(render_thread, true),
[email protected]81e63782009-02-27 19:35:09173 enabled_bindings_(0),
[email protected]e75cb49e2009-01-05 23:13:21174 target_url_status_(TARGET_NONE),
[email protected]81a34412009-01-05 19:17:24175 is_loading_(false),
[email protected]e75cb49e2009-01-05 23:13:21176 navigation_gesture_(NavigationGestureUnknown),
[email protected]81a34412009-01-05 19:17:24177 page_id_(-1),
178 last_page_id_sent_to_browser_(-1),
179 last_indexed_page_id_(-1),
[email protected]81a34412009-01-05 19:17:24180 opened_by_user_gesture_(true),
[email protected]bb063b72009-03-27 23:18:50181 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
[email protected]81a34412009-01-05 19:17:24182 first_default_plugin_(NULL),
[email protected]e4ac5df2009-03-17 15:33:11183 devtools_agent_(NULL),
184 devtools_client_(NULL),
[email protected]81a34412009-01-05 19:17:24185 history_back_list_count_(0),
186 history_forward_list_count_(0),
[email protected]81a34412009-01-05 19:17:24187 has_unload_listener_(false),
188 decrement_shared_popup_at_destruction_(false),
[email protected]81a34412009-01-05 19:17:24189 form_field_autofill_request_id_(0),
190 popup_notification_visible_(false),
[email protected]0666aef2009-05-13 19:48:08191 delay_seconds_for_form_state_sync_(kDefaultDelaySecondsForFormStateSync),
192 preferred_width_(0),
[email protected]9b6f40e2009-06-11 15:54:26193 send_preferred_width_changes_(false) {
initial.commit09911bf2008-07-26 23:55:29194}
195
196RenderView::~RenderView() {
[email protected]0aa55312008-10-17 21:53:08197 if (decrement_shared_popup_at_destruction_)
198 shared_popup_counter_->data--;
199
initial.commit09911bf2008-07-26 23:55:29200 // Clear any back-pointers that might still be held by plugins.
201 PluginDelegateList::iterator it = plugin_delegates_.begin();
202 while (it != plugin_delegates_.end()) {
203 (*it)->DropRenderView();
204 it = plugin_delegates_.erase(it);
205 }
206
[email protected]5fb88962009-04-16 19:03:25207 render_thread_->RemoveFilter(audio_message_filter_);
initial.commit09911bf2008-07-26 23:55:29208}
209
210/*static*/
[email protected]0aa55312008-10-17 21:53:08211RenderView* RenderView::Create(
[email protected]81a34412009-01-05 19:17:24212 RenderThreadBase* render_thread,
[email protected]18bcc3c2009-01-27 21:39:15213 gfx::NativeViewId parent_hwnd,
[email protected]1c4947f2009-01-15 22:25:11214 base::WaitableEvent* modal_dialog_event,
[email protected]0aa55312008-10-17 21:53:08215 int32 opener_id,
[email protected]80d96fa2009-06-10 22:34:51216 const RendererPreferences& renderer_prefs,
[email protected]0aa55312008-10-17 21:53:08217 const WebPreferences& webkit_prefs,
218 SharedRenderViewCounter* counter,
219 int32 routing_id) {
initial.commit09911bf2008-07-26 23:55:29220 DCHECK(routing_id != MSG_ROUTING_NONE);
[email protected]81a34412009-01-05 19:17:24221 scoped_refptr<RenderView> view = new RenderView(render_thread);
initial.commit09911bf2008-07-26 23:55:29222 view->Init(parent_hwnd,
223 modal_dialog_event,
224 opener_id,
[email protected]80d96fa2009-06-10 22:34:51225 renderer_prefs,
initial.commit09911bf2008-07-26 23:55:29226 webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08227 counter,
initial.commit09911bf2008-07-26 23:55:29228 routing_id); // adds reference
229 return view;
230}
231
232/*static*/
233void RenderView::SetNextPageID(int32 next_page_id) {
234 // This method should only be called during process startup, and the given
235 // page id had better not exceed our current next page id!
[email protected]4646f292009-05-20 03:49:05236 DCHECK_EQ(next_page_id_, 1);
initial.commit09911bf2008-07-26 23:55:29237 DCHECK(next_page_id >= next_page_id_);
238 next_page_id_ = next_page_id;
239}
240
241void RenderView::PluginDestroyed(WebPluginDelegateProxy* proxy) {
242 PluginDelegateList::iterator it =
243 std::find(plugin_delegates_.begin(), plugin_delegates_.end(), proxy);
244 DCHECK(it != plugin_delegates_.end());
245 plugin_delegates_.erase(it);
246 // If the plugin is deleted, we need to clear our reference in case user
247 // clicks the info bar to install. Unfortunately we are getting
248 // PluginDestroyed in single process mode. However, that is not a huge
249 // concern.
250 if (proxy == first_default_plugin_)
251 first_default_plugin_ = NULL;
252}
253
[email protected]690a99c2009-01-06 16:48:45254void RenderView::PluginCrashed(const FilePath& plugin_path) {
initial.commit09911bf2008-07-26 23:55:29255 Send(new ViewHostMsg_CrashedPlugin(routing_id_, plugin_path));
256}
257
258
259void RenderView::JSOutOfMemory() {
260 Send(new ViewHostMsg_JSOutOfMemory(routing_id_));
261}
262
[email protected]18bcc3c2009-01-27 21:39:15263void RenderView::Init(gfx::NativeViewId parent_hwnd,
[email protected]1c4947f2009-01-15 22:25:11264 base::WaitableEvent* modal_dialog_event,
initial.commit09911bf2008-07-26 23:55:29265 int32 opener_id,
[email protected]80d96fa2009-06-10 22:34:51266 const RendererPreferences& renderer_prefs,
initial.commit09911bf2008-07-26 23:55:29267 const WebPreferences& webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08268 SharedRenderViewCounter* counter,
initial.commit09911bf2008-07-26 23:55:29269 int32 routing_id) {
270 DCHECK(!webview());
271
272 if (opener_id != MSG_ROUTING_NONE)
273 opener_id_ = opener_id;
274
[email protected]0aa55312008-10-17 21:53:08275 if (counter) {
276 shared_popup_counter_ = counter;
277 shared_popup_counter_->data++;
278 decrement_shared_popup_at_destruction_ = true;
279 } else {
280 shared_popup_counter_ = new SharedRenderViewCounter(0);
281 decrement_shared_popup_at_destruction_ = false;
282 }
283
[email protected]80d96fa2009-06-10 22:34:51284 OnSetRendererPrefs(renderer_prefs);
285
[email protected]58bfc6b2009-06-24 09:45:02286 devtools_agent_.reset(new DevToolsAgent(routing_id, this));
[email protected]9b9d7282009-04-08 14:13:04287
[email protected]c5b3b5e2009-02-13 06:41:11288 webwidget_ = WebView::Create(this, webkit_prefs);
initial.commit09911bf2008-07-26 23:55:29289
[email protected]2e417c82009-04-02 22:30:26290#if defined(OS_LINUX)
291 // We have to enable ourselves as the editor delegate on linux so we can copy
292 // text selections to the X clipboard.
293 webview()->SetUseEditorDelegate(true);
294#endif
295
initial.commit09911bf2008-07-26 23:55:29296 // Don't let WebCore keep a B/F list - we have our own.
297 // We let it keep 1 entry because FrameLoader::goToItem expects an item in the
298 // backForwardList, which is used only in ASSERTs.
299 webview()->SetBackForwardListSize(1);
300
301 routing_id_ = routing_id;
[email protected]81a34412009-01-05 19:17:24302 render_thread_->AddRoute(routing_id_, this);
initial.commit09911bf2008-07-26 23:55:29303 // Take a reference on behalf of the RenderThread. This will be balanced
304 // when we receive ViewMsg_Close.
305 AddRef();
306
307 // If this is a popup, we must wait for the CreatingNew_ACK message before
308 // completing initialization. Otherwise, we can finish it now.
309 if (opener_id == MSG_ROUTING_NONE) {
310 did_show_ = true;
311 CompleteInit(parent_hwnd);
312 }
313
314 host_window_ = parent_hwnd;
[email protected]1c4947f2009-01-15 22:25:11315 modal_dialog_event_.reset(modal_dialog_event);
initial.commit09911bf2008-07-26 23:55:29316
[email protected]58bfc6b2009-06-24 09:45:02317 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]81e63782009-02-27 19:35:09318 if (command_line.HasSwitch(switches::kDomAutomationController))
319 enabled_bindings_ |= BindingsPolicy::DOM_AUTOMATION;
initial.commit09911bf2008-07-26 23:55:29320
[email protected]5fb88962009-04-16 19:03:25321 audio_message_filter_ = new AudioMessageFilter(routing_id_);
322 render_thread_->AddFilter(audio_message_filter_);
initial.commit09911bf2008-07-26 23:55:29323}
324
325void RenderView::OnMessageReceived(const IPC::Message& message) {
[email protected]f8b6b6f2009-03-10 16:48:26326 WebFrame* main_frame = webview() ? webview()->GetMainFrame() : NULL;
327 renderer_logging::ScopedActiveRenderingURLSetter url_setter(
328 main_frame ? main_frame->GetURL() : GURL());
[email protected]f8b6b6f2009-03-10 16:48:26329
[email protected]b2abac72009-02-26 12:39:28330 // If this is developer tools renderer intercept tools messages first.
[email protected]e4ac5df2009-03-17 15:33:11331 if (devtools_client_.get() && devtools_client_->OnMessageReceived(message))
[email protected]b2abac72009-02-26 12:39:28332 return;
[email protected]b4b967e2009-04-22 11:33:05333 if (devtools_agent_.get() && devtools_agent_->OnMessageReceived(message))
334 return;
[email protected]b2abac72009-02-26 12:39:28335
initial.commit09911bf2008-07-26 23:55:29336 IPC_BEGIN_MESSAGE_MAP(RenderView, message)
initial.commit09911bf2008-07-26 23:55:29337 IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)
initial.commit09911bf2008-07-26 23:55:29338 IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)
[email protected]82270452009-06-19 15:58:01339 IPC_MESSAGE_HANDLER(ViewMsg_PrintingDone, OnPrintingDone)
initial.commit09911bf2008-07-26 23:55:29340 IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
341 IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
342 IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText)
343 IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
344 IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)
345 IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)
346 IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)
347 IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)
348 IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)
349 IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)
[email protected]bbbd545c2008-12-15 20:18:04350 IPC_MESSAGE_HANDLER(ViewMsg_ToggleSpellCheck, OnToggleSpellCheck)
initial.commit09911bf2008-07-26 23:55:29351 IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)
352 IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)
353 IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
[email protected]4b59ae602009-06-23 20:58:15354 IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand)
initial.commit09911bf2008-07-26 23:55:29355 IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
[email protected]630e26b2008-10-14 22:55:17356 IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
[email protected]ea8c7452009-04-02 20:47:06357 IPC_MESSAGE_HANDLER(ViewMsg_InsertText, OnInsertText)
initial.commit09911bf2008-07-26 23:55:29358 IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
[email protected]b2abac72009-02-26 12:39:28359 IPC_MESSAGE_HANDLER(ViewMsg_SetupDevToolsClient, OnSetupDevToolsClient)
initial.commit09911bf2008-07-26 23:55:29360 IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)
361 IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
[email protected]1810e132009-03-24 23:35:48362 IPC_MESSAGE_HANDLER(ViewMsg_CSSInsertRequest, OnCSSInsertRequest)
initial.commit09911bf2008-07-26 23:55:29363 IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)
initial.commit09911bf2008-07-26 23:55:29364 IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)
365 IPC_MESSAGE_HANDLER(ViewMsg_UploadFile, OnUploadFileRequest)
366 IPC_MESSAGE_HANDLER(ViewMsg_FormFill, OnFormFill)
367 IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)
368 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)
369 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)
370 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)
371 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)
[email protected]18cb2572008-08-21 20:34:45372 IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)
initial.commit09911bf2008-07-26 23:55:29373 IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)
[email protected]266eb6f2008-09-30 23:56:50374 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved,
375 OnDragSourceEndedOrMoved)
initial.commit09911bf2008-07-26 23:55:29376 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,
377 OnDragSourceSystemDragEnded)
378 IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)
379 IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)
380 IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)
381 IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
382 IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)
383 IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)
384 IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
385 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)
386 IPC_MESSAGE_HANDLER(ViewMsg_UpdateBackForwardListCount,
387 OnUpdateBackForwardListCount)
388 IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,
389 OnGetAllSavableResourceLinksForCurrentPage)
[email protected]f09c7182009-03-10 12:54:04390 IPC_MESSAGE_HANDLER(
391 ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,
392 OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)
initial.commit09911bf2008-07-26 23:55:29393 IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)
[email protected]266eb6f2008-09-30 23:56:50394 IPC_MESSAGE_HANDLER(ViewMsg_GetAccessibilityInfo, OnGetAccessibilityInfo)
395 IPC_MESSAGE_HANDLER(ViewMsg_ClearAccessibilityInfo,
396 OnClearAccessibilityInfo)
initial.commit09911bf2008-07-26 23:55:29397 IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose)
398 IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
399 IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)
[email protected]18cb2572008-08-21 20:34:45400 IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,
401 OnMessageFromExternalHost)
[email protected]0aa55312008-10-17 21:53:08402 IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
403 OnDisassociateFromPopupCount)
[email protected]0ebf3872008-11-07 21:35:03404 IPC_MESSAGE_HANDLER(ViewMsg_AutofillSuggestions,
405 OnReceivedAutofillSuggestions)
[email protected]2c4410d2009-05-06 23:46:22406 IPC_MESSAGE_HANDLER(ViewMsg_PopupNotificationVisibilityChanged,
407 OnPopupNotificationVisibilityChanged)
[email protected]30f75e62009-02-25 22:01:00408 IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
[email protected]309d7a282009-03-24 09:18:27409 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionResponse, OnExtensionResponse)
[email protected]05d478752009-04-08 23:38:16410 IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
[email protected]699ab0d2009-04-23 23:19:14411 IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
[email protected]0666aef2009-05-13 19:48:08412 IPC_MESSAGE_HANDLER(ViewMsg_EnableIntrinsicWidthChangedMode,
413 OnEnableIntrinsicWidthChangedMode)
[email protected]80d96fa2009-06-10 22:34:51414 IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
[email protected]634a6f92008-12-01 21:39:31415
initial.commit09911bf2008-07-26 23:55:29416 // Have the super handle all other messages.
417 IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))
418 IPC_END_MESSAGE_MAP()
419}
420
initial.commit09911bf2008-07-26 23:55:29421void RenderView::SendThumbnail() {
422 WebFrame* main_frame = webview()->GetMainFrame();
423 if (!main_frame)
424 return;
425
426 // get the URL for this page
427 GURL url(main_frame->GetURL());
428 if (url.is_empty())
429 return;
430
431 if (size_.IsEmpty())
432 return; // Don't create an empty thumbnail!
433
434 ThumbnailScore score;
435 SkBitmap thumbnail;
[email protected]8649fb32009-06-26 17:51:02436 if (!CaptureThumbnail(webview(), kThumbnailWidth, kThumbnailHeight,
[email protected]b6e4bec2008-11-12 01:17:15437 &thumbnail, &score))
438 return;
439
initial.commit09911bf2008-07-26 23:55:29440 // send the thumbnail message to the browser process
[email protected]674741932009-02-04 23:44:46441 Send(new ViewHostMsg_Thumbnail(routing_id_, url, score, thumbnail));
initial.commit09911bf2008-07-26 23:55:29442}
443
[email protected]068637222009-01-29 16:58:07444void RenderView::OnPrintPages() {
initial.commit09911bf2008-07-26 23:55:29445 DCHECK(webview());
[email protected]0fda7272009-06-26 15:49:33446 if (webview())
447 Print(webview()->GetMainFrame(), false);
initial.commit09911bf2008-07-26 23:55:29448}
449
[email protected]82270452009-06-19 15:58:01450void RenderView::OnPrintingDone(int document_cookie, bool success) {
451 // Ignoring document cookie here since only one print job can be outstanding
452 // per renderer and document_cookie is 0 when printing is successful.
453 DCHECK(print_helper_.get());
454 if (print_helper_.get() != NULL) {
455 print_helper_->DidFinishPrinting(success);
456 }
457}
458
initial.commit09911bf2008-07-26 23:55:29459void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) {
460 if (load_id != page_id_)
461 return; // this capture call is no longer relevant due to navigation
462 if (load_id == last_indexed_page_id_)
463 return; // we already indexed this page
464
465 if (!webview())
466 return;
467
468 WebFrame* main_frame = webview()->GetMainFrame();
469 if (!main_frame)
470 return;
471
472 // Don't index/capture pages that are in view source mode.
473 if (main_frame->GetInViewSourceMode())
474 return;
475
476 // Don't index/capture pages that failed to load. This only checks the top
477 // level frame so the thumbnail may contain a frame that failed to load.
478 WebDataSource* ds = main_frame->GetDataSource();
[email protected]726985e22009-06-18 21:09:28479 if (ds && ds->hasUnreachableURL())
initial.commit09911bf2008-07-26 23:55:29480 return;
481
482 if (!preliminary_capture)
483 last_indexed_page_id_ = load_id;
484
485 // get the URL for this page
486 GURL url(main_frame->GetURL());
487 if (url.is_empty())
488 return;
489
490 // full text
491 std::wstring contents;
492 CaptureText(main_frame, &contents);
493 if (contents.size()) {
494 // Send the text to the browser for indexing.
495 Send(new ViewHostMsg_PageContents(url, load_id, contents));
496 }
497
498 // thumbnail
499 SendThumbnail();
500}
501
502void RenderView::CaptureText(WebFrame* frame, std::wstring* contents) {
503 contents->clear();
504 if (!frame)
505 return;
506
[email protected]0faf0bd92008-09-09 20:53:27507 // Don't index any https pages. People generally don't want their bank
508 // accounts, etc. indexed on their computer, especially since some of these
509 // things are not marked cachable.
510 // TODO(brettw) we may want to consider more elaborate heuristics such as
511 // the cachability of the page. We may also want to consider subframes (this
512 // test will still index subframes if the subframe is SSL).
513 if (frame->GetURL().SchemeIsSecure())
514 return;
515
initial.commit09911bf2008-07-26 23:55:29516#ifdef TIME_TEXT_RETRIEVAL
517 double begin = time_util::GetHighResolutionTimeNow();
518#endif
519
520 // get the contents of the frame
521 frame->GetContentAsPlainText(kMaxIndexChars, contents);
522
523#ifdef TIME_TEXT_RETRIEVAL
524 double end = time_util::GetHighResolutionTimeNow();
525 char buf[128];
526 sprintf_s(buf, "%d chars retrieved for indexing in %gms\n",
527 contents.size(), (end - begin)*1000);
528 OutputDebugStringA(buf);
529#endif
530
531 // When the contents are clipped to the maximum, we don't want to have a
532 // partial word indexed at the end that might have been clipped. Therefore,
533 // terminate the string at the last space to ensure no words are clipped.
534 if (contents->size() == kMaxIndexChars) {
535 size_t last_space_index = contents->find_last_of(kWhitespaceWide);
536 if (last_space_index == std::wstring::npos)
537 return; // don't index if we got a huge block of text with no spaces
538 contents->resize(last_space_index);
539 }
540}
541
[email protected]8649fb32009-06-26 17:51:02542bool RenderView::CaptureThumbnail(WebView* view,
initial.commit09911bf2008-07-26 23:55:29543 int w,
544 int h,
545 SkBitmap* thumbnail,
546 ThumbnailScore* score) {
547#ifdef TIME_BITMAP_RETRIEVAL
548 double begin = time_util::GetHighResolutionTimeNow();
549#endif
550
[email protected]8649fb32009-06-26 17:51:02551 view->Layout();
552 const WebSize& size = view->GetSize();
[email protected]b6e4bec2008-11-12 01:17:15553
[email protected]8649fb32009-06-26 17:51:02554 skia::PlatformCanvas canvas;
555 if (!canvas.initialize(size.width, size.height, true))
556 return false;
557 view->Paint(&canvas, WebRect(0, 0, size.width, size.height));
558
559 skia::BitmapPlatformDevice& device =
560 static_cast<skia::BitmapPlatformDevice&>(canvas.getTopPlatformDevice());
561
562 const SkBitmap& src_bmp = device.accessBitmap(false);
initial.commit09911bf2008-07-26 23:55:29563
564 SkRect dest_rect;
565 dest_rect.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
566 float dest_aspect = dest_rect.width() / dest_rect.height();
567
568 // Get the src rect so that we can preserve the aspect ratio while filling
569 // the destination.
570 SkIRect src_rect;
571 if (src_bmp.width() < dest_rect.width() ||
572 src_bmp.height() < dest_rect.height()) {
573 // Source image is smaller: we clip the part of source image within the
574 // dest rect, and then stretch it to fill the dest rect. We don't respect
575 // the aspect ratio in this case.
576 src_rect.set(0, 0, static_cast<S16CPU>(dest_rect.width()),
577 static_cast<S16CPU>(dest_rect.height()));
578 score->good_clipping = false;
579 } else {
580 float src_aspect = static_cast<float>(src_bmp.width()) / src_bmp.height();
581 if (src_aspect > dest_aspect) {
582 // Wider than tall, clip horizontally: we center the smaller thumbnail in
583 // the wider screen.
584 S16CPU new_width = static_cast<S16CPU>(src_bmp.height() * dest_aspect);
585 S16CPU x_offset = (src_bmp.width() - new_width) / 2;
586 src_rect.set(x_offset, 0, new_width + x_offset, src_bmp.height());
587 score->good_clipping = false;
588 } else {
589 src_rect.set(0, 0, src_bmp.width(),
590 static_cast<S16CPU>(src_bmp.width() / dest_aspect));
591 score->good_clipping = true;
592 }
593 }
594
[email protected]8649fb32009-06-26 17:51:02595 score->at_top = (view->GetMainFrame()->ScrollOffset().height == 0);
initial.commit09911bf2008-07-26 23:55:29596
597 SkBitmap subset;
[email protected]8649fb32009-06-26 17:51:02598 device.accessBitmap(false).extractSubset(&subset, src_rect);
initial.commit09911bf2008-07-26 23:55:29599
600 // Resample the subset that we want to get it the right size.
[email protected]465b34b72008-12-12 20:19:14601 *thumbnail = skia::ImageOperations::Resize(
602 subset, skia::ImageOperations::RESIZE_LANCZOS3, w, h);
initial.commit09911bf2008-07-26 23:55:29603
604 score->boring_score = CalculateBoringScore(thumbnail);
605
606#ifdef TIME_BITMAP_RETRIEVAL
607 double end = time_util::GetHighResolutionTimeNow();
608 char buf[128];
609 sprintf_s(buf, "thumbnail in %gms\n", (end - begin) * 1000);
610 OutputDebugStringA(buf);
611#endif
[email protected]b6e4bec2008-11-12 01:17:15612 return true;
initial.commit09911bf2008-07-26 23:55:29613}
614
615double RenderView::CalculateBoringScore(SkBitmap* bitmap) {
616 int histogram[256] = {0};
617 color_utils::BuildLumaHistogram(bitmap, histogram);
618
619 int color_count = *std::max_element(histogram, histogram + 256);
620 int pixel_count = bitmap->width() * bitmap->height();
621 return static_cast<double>(color_count) / pixel_count;
622}
623
624void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {
625 if (!webview())
626 return;
627
[email protected]f8b6b6f2009-03-10 16:48:26628 renderer_logging::ScopedActiveRenderingURLSetter url_setter(params.url);
[email protected]f8b6b6f2009-03-10 16:48:26629
initial.commit09911bf2008-07-26 23:55:29630 AboutHandler::MaybeHandle(params.url);
631
632 bool is_reload = params.reload;
633
634 WebFrame* main_frame = webview()->GetMainFrame();
[email protected]ca948a22009-06-25 19:36:17635 if (is_reload && main_frame->GetCurrentHistoryItem().isNull()) {
initial.commit09911bf2008-07-26 23:55:29636 // We cannot reload if we do not have any history state. This happens, for
637 // example, when recovering from a crash. Our workaround here is a bit of
638 // a hack since it means that reload after a crashed tab does not cause an
639 // end-to-end cache validation.
640 is_reload = false;
641 }
642
[email protected]77f17a82009-05-21 04:42:54643 // A navigation resulting from loading a javascript URL should not be treated
644 // as a browser initiated event. Instead, we want it to look as if the page
645 // initiated any load resulting from JS execution.
646 if (!params.url.SchemeIs(chrome::kJavaScriptScheme)) {
[email protected]daa8c58e2009-06-15 17:21:10647 pending_navigation_state_.reset(NavigationState::CreateBrowserInitiated(
[email protected]77f17a82009-05-21 04:42:54648 params.page_id, params.transition, params.request_time));
649 }
initial.commit09911bf2008-07-26 23:55:29650
[email protected]04d3c6e2009-05-22 17:00:13651 // If we are reloading, then WebKit will use the history state of the current
652 // page, so we should just ignore any given history state. Otherwise, if we
653 // have history state, then we need to navigate to it, which corresponds to a
654 // back/forward navigation event.
655 if (!is_reload && !params.state.empty()) {
656 // We must know the page ID of the page we are navigating back to.
[email protected]f929f2f22009-06-12 16:56:58657 DCHECK_NE(params.page_id, -1);
[email protected]ca948a22009-06-25 19:36:17658 main_frame->LoadHistoryItem(
659 webkit_glue::HistoryItemFromString(params.state));
[email protected]04d3c6e2009-05-22 17:00:13660 } else {
661 // Navigate to the given URL.
[email protected]726985e22009-06-18 21:09:28662 WebURLRequest request(params.url);
initial.commit09911bf2008-07-26 23:55:29663
[email protected]04d3c6e2009-05-22 17:00:13664 // TODO(darin): WebFrame should just have a Reload method.
665
[email protected]726985e22009-06-18 21:09:28666 WebURLRequest::CachePolicy cache_policy;
[email protected]04d3c6e2009-05-22 17:00:13667 if (is_reload) {
[email protected]726985e22009-06-18 21:09:28668 cache_policy = WebURLRequest::ReloadIgnoringCacheData;
[email protected]04d3c6e2009-05-22 17:00:13669 } else {
670 // A session history navigation should have been accompanied by state.
[email protected]f929f2f22009-06-12 16:56:58671 DCHECK_EQ(params.page_id, -1);
[email protected]04d3c6e2009-05-22 17:00:13672 if (main_frame->GetInViewSourceMode()) {
[email protected]726985e22009-06-18 21:09:28673 cache_policy = WebURLRequest::ReturnCacheDataElseLoad;
[email protected]04d3c6e2009-05-22 17:00:13674 } else {
[email protected]726985e22009-06-18 21:09:28675 cache_policy = WebURLRequest::UseProtocolCachePolicy;
[email protected]04d3c6e2009-05-22 17:00:13676 }
677 }
[email protected]726985e22009-06-18 21:09:28678 request.setCachePolicy(cache_policy);
[email protected]04d3c6e2009-05-22 17:00:13679
[email protected]726985e22009-06-18 21:09:28680 if (params.referrer.is_valid()) {
681 request.setHTTPHeaderField(WebString::fromUTF8("Referer"),
682 WebString::fromUTF8(params.referrer.spec()));
683 }
[email protected]04d3c6e2009-05-22 17:00:13684
[email protected]726985e22009-06-18 21:09:28685 main_frame->LoadRequest(request);
[email protected]c0588052008-10-27 23:01:50686 }
687
[email protected]77f17a82009-05-21 04:42:54688 // In case LoadRequest failed before DidCreateDataSource was called.
689 pending_navigation_state_.reset();
initial.commit09911bf2008-07-26 23:55:29690}
691
692// Stop loading the current page
693void RenderView::OnStop() {
694 if (webview())
695 webview()->StopLoading();
696}
697
698void RenderView::OnLoadAlternateHTMLText(const std::string& html_contents,
699 bool new_navigation,
700 const GURL& display_url,
701 const std::string& security_info) {
702 if (!webview())
703 return;
704
[email protected]726985e22009-06-18 21:09:28705 WebURLRequest request;
706 request.initialize();
707 request.setURL(GURL(kUnreachableWebDataURL));
708 request.setSecurityInfo(security_info);
initial.commit09911bf2008-07-26 23:55:29709
[email protected]726985e22009-06-18 21:09:28710 webview()->GetMainFrame()->LoadAlternateHTMLString(request,
initial.commit09911bf2008-07-26 23:55:29711 html_contents,
712 display_url,
713 !new_navigation);
714}
715
716void RenderView::OnCopyImageAt(int x, int y) {
717 webview()->CopyImageAt(x, y);
718}
719
[email protected]68b1e922009-06-23 16:00:25720void RenderView::OnExecuteEditCommand(const std::string& name,
721 const std::string& value) {
722 if (!webview() || !webview()->GetFocusedFrame())
723 return;
724
[email protected]4b59ae602009-06-23 20:58:15725 webview()->GetFocusedFrame()->ExecuteEditCommandByName(name, value);
[email protected]68b1e922009-06-23 16:00:25726}
727
[email protected]b2abac72009-02-26 12:39:28728void RenderView::OnSetupDevToolsClient() {
[email protected]e4ac5df2009-03-17 15:33:11729 DCHECK(!devtools_client_.get());
730 devtools_client_.reset(new DevToolsClient(this));
[email protected]b2abac72009-02-26 12:39:28731}
732
initial.commit09911bf2008-07-26 23:55:29733void RenderView::OnStopFinding(bool clear_selection) {
734 WebView* view = webview();
735 if (!view)
736 return;
737
738 if (clear_selection)
739 view->GetFocusedFrame()->ClearSelection();
740
741 WebFrame* frame = view->GetMainFrame();
742 while (frame) {
[email protected]65134c432008-09-26 21:47:20743 frame->StopFinding(clear_selection);
initial.commit09911bf2008-07-26 23:55:29744 frame = view->GetNextFrameAfter(frame, false);
745 }
746}
747
748void RenderView::OnFindReplyAck() {
749 // Check if there is any queued up request waiting to be sent.
750 if (queued_find_reply_message_.get()) {
751 // Send the search result over to the browser process.
752 Send(queued_find_reply_message_.get());
753 queued_find_reply_message_.release();
754 }
755}
756
757void RenderView::OnUpdateTargetURLAck() {
758 // Check if there is a targeturl waiting to be sent.
759 if (target_url_status_ == TARGET_PENDING) {
760 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_,
761 pending_target_url_));
762 }
763
764 target_url_status_ = TARGET_NONE;
765}
766
767void RenderView::OnUndo() {
768 if (!webview())
769 return;
770
771 webview()->GetFocusedFrame()->Undo();
772}
773
774void RenderView::OnRedo() {
775 if (!webview())
776 return;
777
778 webview()->GetFocusedFrame()->Redo();
779}
780
781void RenderView::OnCut() {
782 if (!webview())
783 return;
784
785 webview()->GetFocusedFrame()->Cut();
786}
787
788void RenderView::OnCopy() {
789 if (!webview())
790 return;
791
792 webview()->GetFocusedFrame()->Copy();
793}
794
795void RenderView::OnPaste() {
796 if (!webview())
797 return;
798
799 webview()->GetFocusedFrame()->Paste();
800}
801
802void RenderView::OnReplace(const std::wstring& text) {
803 if (!webview())
804 return;
805
806 webview()->GetFocusedFrame()->Replace(text);
807}
808
[email protected]bbbd545c2008-12-15 20:18:04809void RenderView::OnToggleSpellCheck() {
810 if (!webview())
811 return;
812
813 webview()->GetFocusedFrame()->ToggleSpellCheck();
814}
815
initial.commit09911bf2008-07-26 23:55:29816void RenderView::OnDelete() {
817 if (!webview())
818 return;
819
820 webview()->GetFocusedFrame()->Delete();
821}
822
823void RenderView::OnSelectAll() {
824 if (!webview())
825 return;
826
827 webview()->GetFocusedFrame()->SelectAll();
828}
829
830void RenderView::OnSetInitialFocus(bool reverse) {
831 if (!webview())
832 return;
833 webview()->SetInitialFocus(reverse);
834}
835
836///////////////////////////////////////////////////////////////////////////////
837
838// Tell the embedding application that the URL of the active page has changed
839void RenderView::UpdateURL(WebFrame* frame) {
840 WebDataSource* ds = frame->GetDataSource();
841 DCHECK(ds);
842
[email protected]726985e22009-06-18 21:09:28843 const WebURLRequest& request = ds->request();
844 const WebURLRequest& original_request = ds->originalRequest();
845 const WebURLResponse& response = ds->response();
initial.commit09911bf2008-07-26 23:55:29846
[email protected]daa8c58e2009-06-15 17:21:10847 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
848 DCHECK(navigation_state);
initial.commit09911bf2008-07-26 23:55:29849
850 ViewHostMsg_FrameNavigate_Params params;
[email protected]726985e22009-06-18 21:09:28851 params.http_status_code = response.httpStatusCode();
initial.commit09911bf2008-07-26 23:55:29852 params.is_post = false;
853 params.page_id = page_id_;
[email protected]726985e22009-06-18 21:09:28854 params.is_content_filtered = response.isContentFiltered();
855 if (!request.securityInfo().isEmpty()) {
initial.commit09911bf2008-07-26 23:55:29856 // SSL state specified in the request takes precedence over the one in the
857 // response.
858 // So far this is only intended for error pages that are not expected to be
859 // over ssl, so we should not get any clash.
[email protected]726985e22009-06-18 21:09:28860 DCHECK(response.securityInfo().isEmpty());
861 params.security_info = request.securityInfo();
initial.commit09911bf2008-07-26 23:55:29862 } else {
[email protected]726985e22009-06-18 21:09:28863 params.security_info = response.securityInfo();
initial.commit09911bf2008-07-26 23:55:29864 }
865
866 // Set the URL to be displayed in the browser UI to the user.
[email protected]726985e22009-06-18 21:09:28867 if (ds->hasUnreachableURL()) {
868 params.url = ds->unreachableURL();
initial.commit09911bf2008-07-26 23:55:29869 } else {
[email protected]726985e22009-06-18 21:09:28870 params.url = request.url();
initial.commit09911bf2008-07-26 23:55:29871 }
872
[email protected]726985e22009-06-18 21:09:28873 GetRedirectChain(ds, &params.redirects);
874 params.should_update_history = !ds->hasUnreachableURL();
initial.commit09911bf2008-07-26 23:55:29875
876 const SearchableFormData* searchable_form_data =
[email protected]daa8c58e2009-06-15 17:21:10877 navigation_state->searchable_form_data();
initial.commit09911bf2008-07-26 23:55:29878 if (searchable_form_data) {
879 params.searchable_form_url = searchable_form_data->url();
880 params.searchable_form_element_name = searchable_form_data->element_name();
881 params.searchable_form_encoding = searchable_form_data->encoding();
882 }
883
884 const PasswordForm* password_form_data =
[email protected]daa8c58e2009-06-15 17:21:10885 navigation_state->password_form_data();
initial.commit09911bf2008-07-26 23:55:29886 if (password_form_data)
887 params.password_form = *password_form_data;
888
889 params.gesture = navigation_gesture_;
890 navigation_gesture_ = NavigationGestureUnknown;
891
[email protected]77f17a82009-05-21 04:42:54892 if (!frame->GetParent()) {
initial.commit09911bf2008-07-26 23:55:29893 // Top-level navigation.
894
895 // Update contents MIME type for main frame.
[email protected]726985e22009-06-18 21:09:28896 params.contents_mime_type = UTF16ToUTF8(ds->response().mimeType());
initial.commit09911bf2008-07-26 23:55:29897
[email protected]daa8c58e2009-06-15 17:21:10898 params.transition = navigation_state->transition_type();
initial.commit09911bf2008-07-26 23:55:29899 if (!PageTransition::IsMainFrame(params.transition)) {
900 // If the main frame does a load, it should not be reported as a subframe
901 // navigation. This can occur in the following case:
902 // 1. You're on a site with frames.
903 // 2. You do a subframe navigation. This is stored with transition type
904 // MANUAL_SUBFRAME.
905 // 3. You navigate to some non-frame site, say, google.com.
906 // 4. You navigate back to the page from step 2. Since it was initially
907 // MANUAL_SUBFRAME, it will be that same transition type here.
908 // We don't want that, because any navigation that changes the toplevel
909 // frame should be tracked as a toplevel navigation (this allows us to
910 // update the URL bar, etc).
911 params.transition = PageTransition::LINK;
912 }
913
initial.commit09911bf2008-07-26 23:55:29914 // If we have a valid consumed client redirect source,
915 // the page contained a client redirect (meta refresh, document.loc...),
916 // so we set the referrer and transition to match.
917 if (completed_client_redirect_src_.is_valid()) {
[email protected]77e09a92008-08-01 18:11:04918 DCHECK(completed_client_redirect_src_ == params.redirects[0]);
initial.commit09911bf2008-07-26 23:55:29919 params.referrer = completed_client_redirect_src_;
920 params.transition = static_cast<PageTransition::Type>(
921 params.transition | PageTransition::CLIENT_REDIRECT);
922 } else {
923 // Bug 654101: the referrer will be empty on https->http transitions. It
924 // would be nice if we could get the real referrer from somewhere.
[email protected]726985e22009-06-18 21:09:28925 params.referrer = GURL(
926 original_request.httpHeaderField(WebString::fromUTF8("Referer")));
initial.commit09911bf2008-07-26 23:55:29927 }
928
[email protected]726985e22009-06-18 21:09:28929 string16 method = request.httpMethod();
930 if (EqualsASCII(method, "POST"))
initial.commit09911bf2008-07-26 23:55:29931 params.is_post = true;
932
933 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
934 } else {
935 // Subframe navigation: the type depends on whether this navigation
936 // generated a new session history entry. When they do generate a session
937 // history entry, it means the user initiated the navigation and we should
938 // mark it as such. This test checks if this is the first time UpdateURL
939 // has been called since WillNavigateToURL was called to initiate the load.
940 if (page_id_ > last_page_id_sent_to_browser_)
941 params.transition = PageTransition::MANUAL_SUBFRAME;
942 else
943 params.transition = PageTransition::AUTO_SUBFRAME;
944
initial.commit09911bf2008-07-26 23:55:29945 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
946 }
947
948 last_page_id_sent_to_browser_ =
949 std::max(last_page_id_sent_to_browser_, page_id_);
950
951 // If we end up reusing this WebRequest (for example, due to a #ref click),
[email protected]daa8c58e2009-06-15 17:21:10952 // we don't want the transition type to persist. Just clear it.
953 navigation_state->set_transition_type(PageTransition::LINK);
[email protected]266eb6f2008-09-30 23:56:50954
[email protected]6c8afae52009-01-22 02:24:57955#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:25956 if (web_accessibility_manager_.get()) {
[email protected]be645db2009-02-06 20:36:33957 // Clear accessibility info cache.
[email protected]6a983b42009-03-20 20:12:25958 web_accessibility_manager_->ClearAccObjMap(-1, true);
[email protected]266eb6f2008-09-30 23:56:50959 }
[email protected]6c8afae52009-01-22 02:24:57960#else
[email protected]7d926f92009-03-03 14:26:54961 // TODO(port): accessibility not yet implemented. See http://crbug.com/8288.
[email protected]6c8afae52009-01-22 02:24:57962#endif
initial.commit09911bf2008-07-26 23:55:29963}
964
965// Tell the embedding application that the title of the active page has changed
966void RenderView::UpdateTitle(WebFrame* frame, const std::wstring& title) {
967 // Ignore all but top level navigations...
[email protected]f0af6a72009-05-30 05:25:17968 if (webview()->GetMainFrame() == frame) {
969 Send(new ViewHostMsg_UpdateTitle(
970 routing_id_,
971 page_id_,
972 title.length() > chrome::kMaxTitleChars ?
973 title.substr(0, chrome::kMaxTitleChars) : title));
974 }
initial.commit09911bf2008-07-26 23:55:29975}
976
977void RenderView::UpdateEncoding(WebFrame* frame,
[email protected]e38f40152008-09-12 23:08:30978 const std::wstring& encoding_name) {
initial.commit09911bf2008-07-26 23:55:29979 // Only update main frame's encoding_name.
980 if (webview()->GetMainFrame() == frame &&
981 last_encoding_name_ != encoding_name) {
[email protected]e38f40152008-09-12 23:08:30982 // Save the encoding name for later comparing.
initial.commit09911bf2008-07-26 23:55:29983 last_encoding_name_ = encoding_name;
984
[email protected]e38f40152008-09-12 23:08:30985 Send(new ViewHostMsg_UpdateEncoding(routing_id_, last_encoding_name_));
initial.commit09911bf2008-07-26 23:55:29986 }
987}
988
[email protected]f4d34b52008-11-24 23:05:01989// Sends the previous session history state to the browser so it will be saved
990// before we navigate to a new page. This must be called *before* the page ID
991// has been updated so we know what it was.
initial.commit09911bf2008-07-26 23:55:29992void RenderView::UpdateSessionHistory(WebFrame* frame) {
993 // If we have a valid page ID at this point, then it corresponds to the page
994 // we are navigating away from. Otherwise, this is the first navigation, so
995 // there is no past session history to record.
996 if (page_id_ == -1)
997 return;
998
[email protected]ca948a22009-06-25 19:36:17999 const WebHistoryItem& item =
1000 webview()->GetMainFrame()->GetPreviousHistoryItem();
1001 if (item.isNull())
initial.commit09911bf2008-07-26 23:55:291002 return;
[email protected]ca948a22009-06-25 19:36:171003
1004 Send(new ViewHostMsg_UpdateState(
1005 routing_id_, page_id_, webkit_glue::HistoryItemToString(item)));
initial.commit09911bf2008-07-26 23:55:291006}
1007
1008///////////////////////////////////////////////////////////////////////////////
1009// WebViewDelegate
1010
[email protected]80d96fa2009-06-10 22:34:511011bool RenderView::CanAcceptLoadDrops() const {
1012 return renderer_preferences_.can_accept_load_drops;
1013}
1014
initial.commit09911bf2008-07-26 23:55:291015void RenderView::DidStartLoading(WebView* webview) {
1016 if (is_loading_) {
1017 DLOG(WARNING) << "DidStartLoading called while loading";
1018 return;
1019 }
1020
1021 is_loading_ = true;
1022 // Clear the pointer so that we can assign it only when there is an unknown
1023 // plugin on a page.
1024 first_default_plugin_ = NULL;
1025
[email protected]329581b2009-04-28 06:52:351026 Send(new ViewHostMsg_DidStartLoading(routing_id_));
initial.commit09911bf2008-07-26 23:55:291027}
1028
1029void RenderView::DidStopLoading(WebView* webview) {
1030 if (!is_loading_) {
1031 DLOG(WARNING) << "DidStopLoading called while not loading";
1032 return;
1033 }
1034
1035 is_loading_ = false;
1036
1037 // NOTE: For now we're doing the safest thing, and sending out notification
1038 // when done loading. This currently isn't an issue as the favicon is only
1039 // displayed when done loading. Ideally we would send notification when
1040 // finished parsing the head, but webkit doesn't support that yet.
1041 // The feed discovery code would also benefit from access to the head.
1042 GURL favicon_url(webview->GetMainFrame()->GetFavIconURL());
1043 if (!favicon_url.is_empty())
1044 Send(new ViewHostMsg_UpdateFavIconURL(routing_id_, page_id_, favicon_url));
1045
1046 AddGURLSearchProvider(webview->GetMainFrame()->GetOSDDURL(),
1047 true); // autodetected
1048
[email protected]329581b2009-04-28 06:52:351049 Send(new ViewHostMsg_DidStopLoading(routing_id_));
initial.commit09911bf2008-07-26 23:55:291050
1051 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1052 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo, page_id_,
1053 false),
1054 kDelayForCaptureMs);
1055
1056 // The page is loaded. Try to process the file we need to upload if any.
1057 ProcessPendingUpload();
1058
1059 // Since the page is done loading, we are sure we don't need to try
1060 // again.
1061 ResetPendingUpload();
1062}
1063
[email protected]77f17a82009-05-21 04:42:541064void RenderView::DidCreateDataSource(WebFrame* frame, WebDataSource* ds) {
[email protected]daa8c58e2009-06-15 17:21:101065 // The rest of RenderView assumes that a WebDataSource will always have a
1066 // non-null NavigationState.
1067 if (pending_navigation_state_.get()) {
[email protected]726985e22009-06-18 21:09:281068 ds->setExtraData(pending_navigation_state_.release());
[email protected]daa8c58e2009-06-15 17:21:101069 } else {
[email protected]726985e22009-06-18 21:09:281070 ds->setExtraData(NavigationState::CreateContentInitiated());
[email protected]daa8c58e2009-06-15 17:21:101071 }
[email protected]77f17a82009-05-21 04:42:541072}
1073
initial.commit09911bf2008-07-26 23:55:291074void RenderView::DidStartProvisionalLoadForFrame(
1075 WebView* webview,
1076 WebFrame* frame,
1077 NavigationGesture gesture) {
[email protected]ed3fb032009-06-16 19:50:561078 WebDataSource* ds = frame->GetProvisionalDataSource();
1079 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
1080
1081 navigation_state->set_start_load_time(Time::Now());
1082
1083 // Update the request time if WebKit has better knowledge of it.
1084 if (navigation_state->request_time().is_null()) {
[email protected]726985e22009-06-18 21:09:281085 double event_time = ds->triggeringEventTime();
[email protected]ed3fb032009-06-16 19:50:561086 if (event_time != 0.0)
1087 navigation_state->set_request_time(Time::FromDoubleT(event_time));
1088 }
1089
1090 bool is_top_most = !frame->GetParent();
1091 if (is_top_most) {
initial.commit09911bf2008-07-26 23:55:291092 navigation_gesture_ = gesture;
[email protected]266eb6f2008-09-30 23:56:501093
[email protected]77e09a92008-08-01 18:11:041094 // Make sure redirect tracking state is clear for the new load.
1095 completed_client_redirect_src_ = GURL();
1096 }
initial.commit09911bf2008-07-26 23:55:291097
1098 Send(new ViewHostMsg_DidStartProvisionalLoadForFrame(
[email protected]726985e22009-06-18 21:09:281099 routing_id_, is_top_most, ds->request().url()));
initial.commit09911bf2008-07-26 23:55:291100}
1101
1102bool RenderView::DidLoadResourceFromMemoryCache(WebView* webview,
[email protected]726985e22009-06-18 21:09:281103 const WebURLRequest& request,
1104 const WebURLResponse& response,
initial.commit09911bf2008-07-26 23:55:291105 WebFrame* frame) {
1106 // Let the browser know we loaded a resource from the memory cache. This
1107 // message is needed to display the correct SSL indicators.
1108 Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(routing_id_,
[email protected]726985e22009-06-18 21:09:281109 request.url(), frame->GetSecurityOrigin(),
[email protected]ffc45862009-03-17 06:11:081110 frame->GetTop()->GetSecurityOrigin(),
[email protected]726985e22009-06-18 21:09:281111 response.securityInfo()));
initial.commit09911bf2008-07-26 23:55:291112
1113 return false;
1114}
1115
1116void RenderView::DidReceiveProvisionalLoadServerRedirect(WebView* webview,
1117 WebFrame* frame) {
1118 if (frame == webview->GetMainFrame()) {
1119 // Received a redirect on the main frame.
1120 WebDataSource* data_source =
1121 webview->GetMainFrame()->GetProvisionalDataSource();
1122 if (!data_source) {
1123 // Should only be invoked when we have a data source.
1124 NOTREACHED();
1125 return;
1126 }
[email protected]726985e22009-06-18 21:09:281127 std::vector<GURL> redirects;
1128 GetRedirectChain(data_source, &redirects);
initial.commit09911bf2008-07-26 23:55:291129 if (redirects.size() >= 2) {
1130 Send(new ViewHostMsg_DidRedirectProvisionalLoad(
1131 routing_id_, page_id_, redirects[redirects.size() - 2],
1132 redirects[redirects.size() - 1]));
1133 }
1134 }
1135}
1136
1137void RenderView::DidFailProvisionalLoadWithError(WebView* webview,
[email protected]726985e22009-06-18 21:09:281138 const WebURLError& error,
initial.commit09911bf2008-07-26 23:55:291139 WebFrame* frame) {
1140 // Notify the browser that we failed a provisional load with an error.
1141 //
1142 // Note: It is important this notification occur before DidStopLoading so the
1143 // SSL manager can react to the provisional load failure before being
1144 // notified the load stopped.
1145 //
1146 WebDataSource* ds = frame->GetProvisionalDataSource();
1147 DCHECK(ds);
1148
[email protected]726985e22009-06-18 21:09:281149 const WebURLRequest& failed_request = ds->request();
initial.commit09911bf2008-07-26 23:55:291150
1151 bool show_repost_interstitial =
[email protected]726985e22009-06-18 21:09:281152 (error.reason == net::ERR_CACHE_MISS &&
1153 EqualsASCII(failed_request.httpMethod(), "POST"));
initial.commit09911bf2008-07-26 23:55:291154 Send(new ViewHostMsg_DidFailProvisionalLoadWithError(
[email protected]726985e22009-06-18 21:09:281155 routing_id_, !frame->GetParent(),
1156 error.reason, error.unreachableURL,
initial.commit09911bf2008-07-26 23:55:291157 show_repost_interstitial));
1158
initial.commit09911bf2008-07-26 23:55:291159 // Don't display an error page if this is simply a cancelled load. Aside
1160 // from being dumb, WebCore doesn't expect it and it will cause a crash.
[email protected]726985e22009-06-18 21:09:281161 if (error.reason == net::ERR_ABORTED)
initial.commit09911bf2008-07-26 23:55:291162 return;
1163
[email protected]546ddd172009-06-25 00:25:011164 // Make sure we never show errors in view source mode.
1165 frame->SetInViewSourceMode(false);
1166
initial.commit09911bf2008-07-26 23:55:291167 // If this is a failed back/forward/reload navigation, then we need to do a
1168 // 'replace' load. This is necessary to avoid messing up session history.
1169 // Otherwise, we do a normal load, which simulates a 'go' navigation as far
1170 // as session history is concerned.
[email protected]daa8c58e2009-06-15 17:21:101171 bool replace = !NavigationState::FromDataSource(ds)->is_new_navigation();
initial.commit09911bf2008-07-26 23:55:291172
[email protected]5df266ac2008-10-15 19:50:131173 // Use the alternate error page service if this is a DNS failure or
1174 // connection failure. ERR_CONNECTION_FAILED can be dropped once we no longer
1175 // use winhttp.
[email protected]726985e22009-06-18 21:09:281176 int ec = error.reason;
[email protected]5df266ac2008-10-15 19:50:131177 if (ec == net::ERR_NAME_NOT_RESOLVED ||
1178 ec == net::ERR_CONNECTION_FAILED ||
1179 ec == net::ERR_CONNECTION_REFUSED ||
1180 ec == net::ERR_ADDRESS_UNREACHABLE ||
1181 ec == net::ERR_TIMED_OUT) {
[email protected]726985e22009-06-18 21:09:281182 const GURL& failed_url = error.unreachableURL;
[email protected]5df266ac2008-10-15 19:50:131183 const GURL& error_page_url = GetAlternateErrorPageURL(failed_url,
1184 ec == net::ERR_NAME_NOT_RESOLVED ? WebViewDelegate::DNS_ERROR
1185 : WebViewDelegate::CONNECTION_ERROR);
1186 if (error_page_url.is_valid()) {
1187 // Ask the WebFrame to fetch the alternate error page for us.
[email protected]726985e22009-06-18 21:09:281188 frame->LoadAlternateHTMLErrorPage(failed_request, error, error_page_url,
[email protected]5df266ac2008-10-15 19:50:131189 replace, GURL(kUnreachableWebDataURL));
1190 return;
1191 }
initial.commit09911bf2008-07-26 23:55:291192 }
[email protected]5df266ac2008-10-15 19:50:131193
[email protected]be645db2009-02-06 20:36:331194 // Fallback to a local error page.
[email protected]726985e22009-06-18 21:09:281195 LoadNavigationErrorPage(frame, failed_request, error, std::string(),
[email protected]5df266ac2008-10-15 19:50:131196 replace);
initial.commit09911bf2008-07-26 23:55:291197}
1198
1199void RenderView::LoadNavigationErrorPage(WebFrame* frame,
[email protected]726985e22009-06-18 21:09:281200 const WebURLRequest& failed_request,
1201 const WebURLError& error,
initial.commit09911bf2008-07-26 23:55:291202 const std::string& html,
1203 bool replace) {
[email protected]726985e22009-06-18 21:09:281204 GURL failed_url = error.unreachableURL;
initial.commit09911bf2008-07-26 23:55:291205
1206 std::string alt_html;
1207 if (html.empty()) {
1208 // Use a local error page.
1209 int resource_id;
1210 DictionaryValue error_strings;
[email protected]726985e22009-06-18 21:09:281211 if (error.reason == net::ERR_CACHE_MISS &&
1212 EqualsASCII(failed_request.httpMethod(), "POST")) {
initial.commit09911bf2008-07-26 23:55:291213 GetFormRepostErrorValues(failed_url, &error_strings);
1214 resource_id = IDR_ERROR_NO_DETAILS_HTML;
1215 } else {
1216 GetLocalizedErrorValues(error, &error_strings);
1217 resource_id = IDR_NET_ERROR_HTML;
1218 }
[email protected]8e50b602009-03-03 22:59:431219 error_strings.SetString(L"textdirection",
1220 (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) ?
1221 L"rtl" : L"ltr");
initial.commit09911bf2008-07-26 23:55:291222
1223 alt_html = GetAltHTMLForTemplate(error_strings, resource_id);
1224 } else {
1225 alt_html = html;
1226 }
1227
1228 // Use a data: URL as the site URL to prevent against XSS attacks.
[email protected]726985e22009-06-18 21:09:281229 WebURLRequest request(failed_request);
1230 request.setURL(GURL(kUnreachableWebDataURL));
initial.commit09911bf2008-07-26 23:55:291231
[email protected]726985e22009-06-18 21:09:281232 frame->LoadAlternateHTMLString(request, alt_html, failed_url, replace);
initial.commit09911bf2008-07-26 23:55:291233}
1234
1235void RenderView::DidCommitLoadForFrame(WebView *webview, WebFrame* frame,
1236 bool is_new_navigation) {
[email protected]daa8c58e2009-06-15 17:21:101237 NavigationState* navigation_state =
1238 NavigationState::FromDataSource(frame->GetDataSource());
initial.commit09911bf2008-07-26 23:55:291239
initial.commit09911bf2008-07-26 23:55:291240 if (is_new_navigation) {
1241 // When we perform a new navigation, we need to update the previous session
1242 // history entry with state for the page we are leaving.
1243 UpdateSessionHistory(frame);
1244
1245 // We bump our Page ID to correspond with the new session history entry.
1246 page_id_ = next_page_id_++;
1247
1248 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1249 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo,
1250 page_id_, true),
1251 kDelayForForcedCaptureMs);
1252 } else {
[email protected]77f17a82009-05-21 04:42:541253 // Inspect the navigation_state on the main frame (set in our Navigate
1254 // method) to see if the navigation corresponds to a session history
1255 // navigation... Note: |frame| may or may not be the toplevel frame, but
1256 // for the case of capturing session history, the first committed frame
1257 // suffices. We keep track of whether we've seen this commit before so
1258 // that only capture session history once per navigation.
[email protected]f4d34b52008-11-24 23:05:011259 //
1260 // Note that we need to check if the page ID changed. In the case of a
1261 // reload, the page ID doesn't change, and UpdateSessionHistory gets the
1262 // previous URL and the current page ID, which would be wrong.
[email protected]daa8c58e2009-06-15 17:21:101263 if (!navigation_state->is_new_navigation() &&
1264 !navigation_state->request_committed() &&
[email protected]77f17a82009-05-21 04:42:541265 page_id_ != navigation_state->pending_page_id()) {
initial.commit09911bf2008-07-26 23:55:291266 // This is a successful session history navigation!
1267 UpdateSessionHistory(frame);
[email protected]77f17a82009-05-21 04:42:541268 page_id_ = navigation_state->pending_page_id();
initial.commit09911bf2008-07-26 23:55:291269 }
1270 }
1271
1272 // Remember that we've already processed this request, so we don't update
1273 // the session history again. We do this regardless of whether this is
1274 // a session history navigation, because if we attempted a session history
1275 // navigation without valid HistoryItem state, WebCore will think it is a
1276 // new navigation.
[email protected]daa8c58e2009-06-15 17:21:101277 navigation_state->set_request_committed(true);
initial.commit09911bf2008-07-26 23:55:291278
1279 UpdateURL(frame);
1280
1281 // If this committed load was initiated by a client redirect, we're
1282 // at the last stop now, so clear it.
1283 completed_client_redirect_src_ = GURL();
1284
1285 // Check whether we have new encoding name.
1286 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
1287}
1288
1289void RenderView::DidReceiveTitle(WebView* webview,
1290 const std::wstring& title,
1291 WebFrame* frame) {
1292 UpdateTitle(frame, title);
1293
1294 // Also check whether we have new encoding name.
1295 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
1296}
1297
1298void RenderView::DidFinishLoadForFrame(WebView* webview, WebFrame* frame) {
[email protected]c20210e62009-04-03 21:39:261299 if (webview->GetMainFrame() == frame) {
1300 const GURL& url = frame->GetURL();
1301 if (url.SchemeIs("http") || url.SchemeIs("https"))
1302 DumpLoadHistograms();
1303 }
initial.commit09911bf2008-07-26 23:55:291304}
1305
1306void RenderView::DidFailLoadWithError(WebView* webview,
[email protected]726985e22009-06-18 21:09:281307 const WebURLError& error,
initial.commit09911bf2008-07-26 23:55:291308 WebFrame* frame) {
[email protected]546ddd172009-06-25 00:25:011309 // Currently this function is empty. When you implement something here and it
1310 // will display any error messages in HTML, please make sure to call
1311 // frame->SetInViewSourceMode(false) not to show them in view source mode.
initial.commit09911bf2008-07-26 23:55:291312}
1313
1314void RenderView::DidFinishDocumentLoadForFrame(WebView* webview,
1315 WebFrame* frame) {
[email protected]09b8f82f2009-06-16 20:22:111316 Send(new ViewHostMsg_DocumentLoadedInFrame(routing_id_));
1317
[email protected]daa8c58e2009-06-15 17:21:101318 // The document has now been fully loaded. Scan for password forms to be
1319 // sent up to the browser.
1320 SendPasswordForms(frame);
1321
initial.commit09911bf2008-07-26 23:55:291322 // Check whether we have new encoding name.
1323 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
[email protected]1e0f70402008-10-16 23:57:471324
[email protected]8930d472009-02-21 08:05:281325 if (RenderThread::current()) // Will be NULL during unit tests.
1326 RenderThread::current()->user_script_slave()->InjectScripts(
[email protected]0afe8272009-02-14 04:15:161327 frame, UserScript::DOCUMENT_END);
initial.commit09911bf2008-07-26 23:55:291328}
1329
1330void RenderView::DidHandleOnloadEventsForFrame(WebView* webview,
1331 WebFrame* frame) {
1332}
1333
1334void RenderView::DidChangeLocationWithinPageForFrame(WebView* webview,
1335 WebFrame* frame,
1336 bool is_new_navigation) {
[email protected]77f17a82009-05-21 04:42:541337 // If this was a reference fragment navigation that we initiated, then we
1338 // could end up having a non-null pending navigation state. We just need to
1339 // update the ExtraData on the datasource so that others who read the
1340 // ExtraData will get the new NavigationState. Similarly, if we did not
[email protected]daa8c58e2009-06-15 17:21:101341 // initiate this navigation, then we need to take care to reset any pre-
1342 // existing navigation state to a content-initiated navigation state.
1343 // DidCreateDataSource conveniently takes care of this for us.
1344 DidCreateDataSource(frame, frame->GetDataSource());
[email protected]77f17a82009-05-21 04:42:541345
initial.commit09911bf2008-07-26 23:55:291346 DidCommitLoadForFrame(webview, frame, is_new_navigation);
[email protected]77f17a82009-05-21 04:42:541347
[email protected]9d806f52009-03-12 22:50:541348 const string16& title =
[email protected]726985e22009-06-18 21:09:281349 webview->GetMainFrame()->GetDataSource()->pageTitle();
[email protected]9d806f52009-03-12 22:50:541350 UpdateTitle(frame, UTF16ToWideHack(title));
initial.commit09911bf2008-07-26 23:55:291351}
1352
initial.commit09911bf2008-07-26 23:55:291353void RenderView::DidCompleteClientRedirect(WebView* webview,
1354 WebFrame* frame,
1355 const GURL& source) {
1356 if (webview->GetMainFrame() == frame)
1357 completed_client_redirect_src_ = source;
1358}
1359
[email protected]daa8c58e2009-06-15 17:21:101360void RenderView::WillSubmitForm(WebView* webview, WebFrame* frame,
1361 const WebForm& form) {
1362 NavigationState* navigation_state =
1363 NavigationState::FromDataSource(frame->GetProvisionalDataSource());
1364
1365 if (navigation_state->transition_type() == PageTransition::LINK)
1366 navigation_state->set_transition_type(PageTransition::FORM_SUBMIT);
1367
1368 // Save these to be processed when the ensuing navigation is committed.
1369 navigation_state->set_searchable_form_data(
1370 SearchableFormData::Create(form));
1371 navigation_state->set_password_form_data(
1372 PasswordFormDomManager::CreatePasswordForm(form));
1373
1374 if (form.isAutoCompleteEnabled()) {
1375 scoped_ptr<AutofillForm> autofill_form(AutofillForm::Create(form));
1376 if (autofill_form.get())
1377 Send(new ViewHostMsg_AutofillFormSubmitted(routing_id_, *autofill_form));
1378 }
1379}
1380
[email protected]5b35a6b2009-03-16 19:58:081381void RenderView::WillSendRequest(WebView* webview,
1382 uint32 identifier,
[email protected]726985e22009-06-18 21:09:281383 WebURLRequest* request) {
1384 request->setRequestorID(routing_id_);
[email protected]5b35a6b2009-03-16 19:58:081385}
1386
initial.commit09911bf2008-07-26 23:55:291387void RenderView::BindDOMAutomationController(WebFrame* webframe) {
1388 dom_automation_controller_.set_message_sender(this);
1389 dom_automation_controller_.set_routing_id(routing_id_);
1390 dom_automation_controller_.BindToJavascript(webframe,
1391 L"domAutomationController");
1392}
1393
1394void RenderView::WindowObjectCleared(WebFrame* webframe) {
[email protected]81e63782009-02-27 19:35:091395 if (BindingsPolicy::is_dom_automation_enabled(enabled_bindings_))
initial.commit09911bf2008-07-26 23:55:291396 BindDOMAutomationController(webframe);
[email protected]81e63782009-02-27 19:35:091397 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_)) {
initial.commit09911bf2008-07-26 23:55:291398 dom_ui_bindings_.set_message_sender(this);
1399 dom_ui_bindings_.set_routing_id(routing_id_);
1400 dom_ui_bindings_.BindToJavascript(webframe, L"chrome");
1401 }
[email protected]81e63782009-02-27 19:35:091402 if (BindingsPolicy::is_external_host_enabled(enabled_bindings_)) {
[email protected]18cb2572008-08-21 20:34:451403 external_host_bindings_.set_message_sender(this);
1404 external_host_bindings_.set_routing_id(routing_id_);
1405 external_host_bindings_.BindToJavascript(webframe, L"externalHost");
1406 }
initial.commit09911bf2008-07-26 23:55:291407}
1408
[email protected]0afe8272009-02-14 04:15:161409void RenderView::DocumentElementAvailable(WebFrame* frame) {
[email protected]4b8323b2009-04-17 18:45:441410 // TODO(mpcomplete): remove this before Chrome extensions ship.
1411 // HACK. This is a temporary workaround to allow cross-origin XHR for Chrome
1412 // extensions. It grants full access to every origin, when we really want
1413 // to be able to restrict them more specifically.
[email protected]d959ce22009-04-15 21:03:421414 if (frame->GetURL().SchemeIs(chrome::kExtensionScheme))
[email protected]4b8323b2009-04-17 18:45:441415 frame->GrantUniversalAccess();
[email protected]d959ce22009-04-15 21:03:421416
[email protected]d02982242009-06-19 02:51:421417 // Tell extensions to self-register their js contexts.
1418 // TODO(rafaelw): This is kind of gross. We need a way to call through
1419 // the glue layer to retrieve the current v8::Context.
1420 if (frame->GetURL().SchemeIs(chrome::kExtensionScheme))
1421 ExtensionProcessBindings::RegisterExtensionContext(frame);
[email protected]85b99842009-05-16 02:01:251422
[email protected]8930d472009-02-21 08:05:281423 if (RenderThread::current()) // Will be NULL during unit tests.
1424 RenderThread::current()->user_script_slave()->InjectScripts(
[email protected]0afe8272009-02-14 04:15:161425 frame, UserScript::DOCUMENT_START);
1426}
1427
initial.commit09911bf2008-07-26 23:55:291428WindowOpenDisposition RenderView::DispositionForNavigationAction(
1429 WebView* webview,
1430 WebFrame* frame,
[email protected]726985e22009-06-18 21:09:281431 const WebURLRequest& request,
initial.commit09911bf2008-07-26 23:55:291432 WebNavigationType type,
1433 WindowOpenDisposition disposition,
1434 bool is_redirect) {
[email protected]daa8c58e2009-06-15 17:21:101435 // A content initiated navigation may have originated from a link-click,
1436 // script, drag-n-drop operation, etc.
[email protected]77f17a82009-05-21 04:42:541437 bool is_content_initiated =
[email protected]daa8c58e2009-06-15 17:21:101438 NavigationState::FromDataSource(frame->GetProvisionalDataSource())->
1439 is_content_initiated();
[email protected]77f17a82009-05-21 04:42:541440
initial.commit09911bf2008-07-26 23:55:291441 // Webkit is asking whether to navigate to a new URL.
1442 // This is fine normally, except if we're showing UI from one security
1443 // context and they're trying to navigate to a different context.
[email protected]726985e22009-06-18 21:09:281444 const GURL& url = request.url();
[email protected]77f17a82009-05-21 04:42:541445
initial.commit09911bf2008-07-26 23:55:291446 // We only care about navigations that are within the current tab (as opposed
1447 // to, for example, opening a new window).
1448 // But we sometimes navigate to about:blank to clear a tab, and we want to
1449 // still allow that.
[email protected]77f17a82009-05-21 04:42:541450 if (disposition == CURRENT_TAB && is_content_initiated &&
1451 frame->GetParent() == NULL && !url.SchemeIs(chrome::kAboutScheme)) {
1452 // When we received such unsolicited navigations, we sometimes want to
1453 // punt them up to the browser to handle.
1454 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_) ||
[email protected]1e5f53a2009-06-15 23:48:041455 BindingsPolicy::is_extension_enabled(enabled_bindings_) ||
[email protected]77f17a82009-05-21 04:42:541456 frame->GetInViewSourceMode() ||
1457 url.SchemeIs(chrome::kViewSourceScheme)) {
1458 OpenURL(webview, url, GURL(), disposition);
1459 return IGNORE_ACTION; // Suppress the load here.
initial.commit09911bf2008-07-26 23:55:291460 }
1461 }
1462
1463 // Detect when a page is "forking" a new tab that can be safely rendered in
1464 // its own process. This is done by sites like Gmail that try to open links
1465 // in new windows without script connections back to the original page. We
1466 // treat such cases as browser navigations (in which we will create a new
1467 // renderer for a cross-site navigation), rather than WebKit navigations.
1468 //
1469 // We use the following heuristic to decide whether to fork a new page in its
1470 // own process:
1471 // The parent page must open a new tab to about:blank, set the new tab's
1472 // window.opener to null, and then redirect the tab to a cross-site URL using
1473 // JavaScript.
1474 bool is_fork =
1475 // Must start from a tab showing about:blank, which is later redirected.
[email protected]6aad4bd2009-02-26 22:55:171476 frame->GetURL() == GURL("about:blank") &&
initial.commit09911bf2008-07-26 23:55:291477 // Must be the first real navigation of the tab.
1478 GetHistoryBackListCount() < 1 &&
1479 GetHistoryForwardListCount() < 1 &&
1480 // The parent page must have set the child's window.opener to null before
1481 // redirecting to the desired URL.
1482 frame->GetOpener() == NULL &&
1483 // Must be a top-level frame.
1484 frame->GetParent() == NULL &&
[email protected]77f17a82009-05-21 04:42:541485 // Must not have issued the request from this page.
1486 is_content_initiated &&
initial.commit09911bf2008-07-26 23:55:291487 // Must be targeted at the current tab.
1488 disposition == CURRENT_TAB &&
1489 // Must be a JavaScript navigation, which appears as "other".
[email protected]726985e22009-06-18 21:09:281490 type == WebKit::WebNavigationTypeOther;
initial.commit09911bf2008-07-26 23:55:291491 if (is_fork) {
1492 // Open the URL via the browser, not via WebKit.
[email protected]c0588052008-10-27 23:01:501493 OpenURL(webview, url, GURL(), disposition);
initial.commit09911bf2008-07-26 23:55:291494 return IGNORE_ACTION;
1495 }
1496
1497 return disposition;
1498}
1499
[email protected]a455d3812009-03-05 20:18:071500void RenderView::RunJavaScriptAlert(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291501 const std::wstring& message) {
[email protected]478ff2ed2009-04-21 23:49:181502 RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptAlert,
initial.commit09911bf2008-07-26 23:55:291503 message,
1504 std::wstring(),
[email protected]a455d3812009-03-05 20:18:071505 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291506 NULL);
1507}
1508
[email protected]a455d3812009-03-05 20:18:071509bool RenderView::RunJavaScriptConfirm(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291510 const std::wstring& message) {
[email protected]478ff2ed2009-04-21 23:49:181511 return RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptConfirm,
initial.commit09911bf2008-07-26 23:55:291512 message,
1513 std::wstring(),
[email protected]a455d3812009-03-05 20:18:071514 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291515 NULL);
1516}
1517
[email protected]a455d3812009-03-05 20:18:071518bool RenderView::RunJavaScriptPrompt(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291519 const std::wstring& message,
1520 const std::wstring& default_value,
1521 std::wstring* result) {
[email protected]478ff2ed2009-04-21 23:49:181522 return RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptPrompt,
initial.commit09911bf2008-07-26 23:55:291523 message,
1524 default_value,
[email protected]a455d3812009-03-05 20:18:071525 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291526 result);
1527}
1528
1529bool RenderView::RunJavaScriptMessage(int type,
1530 const std::wstring& message,
1531 const std::wstring& default_value,
[email protected]a455d3812009-03-05 20:18:071532 const GURL& frame_url,
initial.commit09911bf2008-07-26 23:55:291533 std::wstring* result) {
1534 bool success = false;
1535 std::wstring result_temp;
1536 if (!result)
1537 result = &result_temp;
1538 IPC::SyncMessage* msg = new ViewHostMsg_RunJavaScriptMessage(
[email protected]a455d3812009-03-05 20:18:071539 routing_id_, message, default_value, frame_url, type, &success, result);
initial.commit09911bf2008-07-26 23:55:291540
[email protected]1c4947f2009-01-15 22:25:111541 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291542 Send(msg);
1543
1544 return success;
1545}
1546
1547void RenderView::AddGURLSearchProvider(const GURL& osd_url, bool autodetected) {
1548 if (!osd_url.is_empty())
1549 Send(new ViewHostMsg_PageHasOSDD(routing_id_, page_id_, osd_url,
1550 autodetected));
1551}
1552
[email protected]a455d3812009-03-05 20:18:071553bool RenderView::RunBeforeUnloadConfirm(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291554 const std::wstring& message) {
1555 bool success = false;
1556 // This is an ignored return value, but is included so we can accept the same
1557 // response as RunJavaScriptMessage.
1558 std::wstring ignored_result;
1559 IPC::SyncMessage* msg = new ViewHostMsg_RunBeforeUnloadConfirm(
[email protected]a455d3812009-03-05 20:18:071560 routing_id_, webframe->GetURL(), message, &success, &ignored_result);
initial.commit09911bf2008-07-26 23:55:291561
[email protected]1c4947f2009-01-15 22:25:111562 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291563 Send(msg);
1564
1565 return success;
1566}
1567
[email protected]0ebf3872008-11-07 21:35:031568void RenderView::QueryFormFieldAutofill(const std::wstring& field_name,
1569 const std::wstring& text,
1570 int64 node_id) {
1571 static int message_id_counter = 0;
1572 form_field_autofill_request_id_ = message_id_counter++;
1573 Send(new ViewHostMsg_QueryFormFieldAutofill(routing_id_,
1574 field_name, text,
1575 node_id,
1576 form_field_autofill_request_id_));
1577}
1578
[email protected]4d2b6fb2009-03-20 22:28:171579void RenderView::RemoveStoredAutofillEntry(const std::wstring& name,
1580 const std::wstring& value) {
1581 Send(new ViewHostMsg_RemoveAutofillEntry(routing_id_, name, value));
1582}
1583
[email protected]0ebf3872008-11-07 21:35:031584void RenderView::OnReceivedAutofillSuggestions(
1585 int64 node_id,
1586 int request_id,
[email protected]8d0f15c2008-11-11 01:01:091587 const std::vector<std::wstring>& suggestions,
[email protected]0ebf3872008-11-07 21:35:031588 int default_suggestion_index) {
1589 if (!webview() || request_id != form_field_autofill_request_id_)
1590 return;
1591
1592 webview()->AutofillSuggestionsForNode(node_id, suggestions,
1593 default_suggestion_index);
1594}
1595
[email protected]2c4410d2009-05-06 23:46:221596void RenderView::OnPopupNotificationVisibilityChanged(bool visible) {
[email protected]634a6f92008-12-01 21:39:311597 popup_notification_visible_ = visible;
1598}
1599
initial.commit09911bf2008-07-26 23:55:291600void RenderView::ShowModalHTMLDialog(const GURL& url, int width, int height,
1601 const std::string& json_arguments,
1602 std::string* json_retval) {
1603 IPC::SyncMessage* msg = new ViewHostMsg_ShowModalHTMLDialog(
1604 routing_id_, url, width, height, json_arguments, json_retval);
1605
[email protected]1c4947f2009-01-15 22:25:111606 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291607 Send(msg);
1608}
1609
1610uint32 RenderView::GetCPBrowsingContext() {
1611 uint32 context = 0;
1612 Send(new ViewHostMsg_GetCPBrowsingContext(&context));
1613 return context;
1614}
1615
1616// Tell the browser to display a destination link.
1617void RenderView::UpdateTargetURL(WebView* webview, const GURL& url) {
1618 if (url != target_url_) {
1619 if (target_url_status_ == TARGET_INFLIGHT ||
1620 target_url_status_ == TARGET_PENDING) {
1621 // If we have a request in-flight, save the URL to be sent when we
1622 // receive an ACK to the in-flight request. We can happily overwrite
1623 // any existing pending sends.
1624 pending_target_url_ = url;
1625 target_url_status_ = TARGET_PENDING;
1626 } else {
1627 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_, url));
1628 target_url_ = url;
1629 target_url_status_ = TARGET_INFLIGHT;
1630 }
1631 }
1632}
1633
[email protected]b62d1a8c2009-01-13 23:54:571634void RenderView::RunFileChooser(bool multi_select,
[email protected]b949f1112009-04-12 20:03:081635 const string16& title,
1636 const FilePath& default_filename,
initial.commit09911bf2008-07-26 23:55:291637 WebFileChooserCallback* file_chooser) {
1638 if (file_chooser_.get()) {
1639 // TODO(brettw): bug 1235154: This should be a synchronous message to deal
1640 // with the fact that web pages can programatically trigger this. With the
1641 // asnychronous messages, we can get an additional call when one is pending,
1642 // which this test is for. For now, we just ignore the additional file
1643 // chooser request. WebKit doesn't do anything to expect the callback, so
1644 // we can just ignore calling it.
1645 delete file_chooser;
1646 return;
1647 }
1648 file_chooser_.reset(file_chooser);
[email protected]b62d1a8c2009-01-13 23:54:571649 Send(new ViewHostMsg_RunFileChooser(routing_id_, multi_select, title,
[email protected]b949f1112009-04-12 20:03:081650 default_filename));
initial.commit09911bf2008-07-26 23:55:291651}
1652
1653void RenderView::AddMessageToConsole(WebView* webview,
1654 const std::wstring& message,
1655 unsigned int line_no,
1656 const std::wstring& source_id) {
1657 Send(new ViewHostMsg_AddMessageToConsole(routing_id_, message,
1658 static_cast<int32>(line_no),
1659 source_id));
1660}
1661
1662void RenderView::AddSearchProvider(const std::string& url) {
1663 AddGURLSearchProvider(GURL(url),
1664 false); // not autodetected
1665}
1666
[email protected]c88a70fe2009-05-05 20:00:221667WebView* RenderView::CreateWebView(WebView* webview,
1668 bool user_gesture,
1669 const GURL& creator_url) {
[email protected]0aa55312008-10-17 21:53:081670 // Check to make sure we aren't overloading on popups.
1671 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups)
1672 return NULL;
1673
[email protected]634a6f92008-12-01 21:39:311674 // This window can't be closed from a window.close() call until we receive a
1675 // message from the Browser process explicitly allowing it.
1676 popup_notification_visible_ = true;
1677
initial.commit09911bf2008-07-26 23:55:291678 int32 routing_id = MSG_ROUTING_NONE;
[email protected]6c8afae52009-01-22 02:24:571679
[email protected]18bcc3c2009-01-27 21:39:151680 ModalDialogEvent modal_dialog_event;
[email protected]6c8afae52009-01-22 02:24:571681 render_thread_->Send(
[email protected]15787f8f2008-10-17 15:29:031682 new ViewHostMsg_CreateWindow(routing_id_, user_gesture, &routing_id,
1683 &modal_dialog_event));
initial.commit09911bf2008-07-26 23:55:291684 if (routing_id == MSG_ROUTING_NONE) {
initial.commit09911bf2008-07-26 23:55:291685 return NULL;
1686 }
1687
1688 // The WebView holds a reference to this new RenderView
[email protected]80d96fa2009-06-10 22:34:511689 const WebPreferences& web_prefs = webview->GetPreferences();
[email protected]6c8afae52009-01-22 02:24:571690 base::WaitableEvent* waitable_event = new base::WaitableEvent
1691#if defined(OS_WIN)
[email protected]18bcc3c2009-01-27 21:39:151692 (modal_dialog_event.event);
[email protected]6c8afae52009-01-22 02:24:571693#else
1694 (true, false);
1695#endif
[email protected]81a34412009-01-05 19:17:241696 RenderView* view = RenderView::Create(render_thread_,
[email protected]1c4947f2009-01-15 22:25:111697 NULL, waitable_event, routing_id_,
[email protected]80d96fa2009-06-10 22:34:511698 renderer_preferences_, web_prefs,
1699 shared_popup_counter_, routing_id);
[email protected]ed4bf2d2009-05-05 00:10:061700 view->opened_by_user_gesture_ = user_gesture;
[email protected]c88a70fe2009-05-05 20:00:221701 view->creator_url_ = creator_url;
initial.commit09911bf2008-07-26 23:55:291702
1703 // Copy over the alternate error page URL so we can have alt error pages in
1704 // the new render view (we don't need the browser to send the URL back down).
1705 view->alternate_error_page_url_ = alternate_error_page_url_;
1706
1707 return view->webview();
1708}
1709
[email protected]0ebf3872008-11-07 21:35:031710WebWidget* RenderView::CreatePopupWidget(WebView* webview,
[email protected]cfd727f2009-01-09 20:21:111711 bool activatable) {
[email protected]8085dbc82008-09-26 22:53:441712 RenderWidget* widget = RenderWidget::Create(routing_id_,
[email protected]81a34412009-01-05 19:17:241713 render_thread_,
[email protected]cfd727f2009-01-09 20:21:111714 activatable);
initial.commit09911bf2008-07-26 23:55:291715 return widget->webwidget();
1716}
1717
1718WebPluginDelegate* RenderView::CreatePluginDelegate(
1719 WebView* webview,
1720 const GURL& url,
1721 const std::string& mime_type,
1722 const std::string& clsid,
1723 std::string* actual_mime_type) {
[email protected]ffeba6d2009-04-27 20:43:261724#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]6273e2e72009-04-17 00:13:551725 if (!PluginChannelHost::IsListening())
1726 return NULL;
1727
[email protected]9dd9e8382009-06-05 18:23:211728 GURL policy_url;
1729 if (webview->GetMainFrame())
1730 policy_url = webview->GetMainFrame()->GetURL();
1731
[email protected]f5cdaff2009-05-19 21:01:471732 FilePath path;
1733 render_thread_->Send(
[email protected]9dd9e8382009-06-05 18:23:211734 new ViewHostMsg_GetPluginPath(url, policy_url, mime_type, clsid, &path,
[email protected]f5cdaff2009-05-19 21:01:471735 actual_mime_type));
1736 if (path.value().empty())
1737 return NULL;
1738
1739 std::string mime_type_to_use;
1740 if (!actual_mime_type->empty())
1741 mime_type_to_use = *actual_mime_type;
1742 else
1743 mime_type_to_use = mime_type;
1744
[email protected]ffeba6d2009-04-27 20:43:261745#if !defined(OS_LINUX) // In-proc plugins aren't supported on Linux.
[email protected]88a1fb47a2009-03-13 00:18:061746 if (RenderProcess::current()->in_process_plugins()) {
[email protected]b94d3322009-02-12 19:49:041747 return WebPluginDelegate::Create(path,
1748 mime_type_to_use,
1749 gfx::NativeViewFromId(host_window_));
initial.commit09911bf2008-07-26 23:55:291750 }
[email protected]ffeba6d2009-04-27 20:43:261751#endif
initial.commit09911bf2008-07-26 23:55:291752
1753 WebPluginDelegateProxy* proxy =
[email protected]f5cdaff2009-05-19 21:01:471754 WebPluginDelegateProxy::Create(url, mime_type_to_use, clsid, this);
initial.commit09911bf2008-07-26 23:55:291755 if (!proxy)
1756 return NULL;
1757
[email protected]41da4792009-06-26 16:39:011758 // We hold onto the proxy so we can poke it when we are painting. See our
1759 // DidPaint implementation below.
initial.commit09911bf2008-07-26 23:55:291760 plugin_delegates_.push_back(proxy);
1761
1762 return proxy;
[email protected]6c8afae52009-01-22 02:24:571763#else
[email protected]157e5d22009-04-23 18:43:351764 // TODO(port): Plugins currently not supported
1765 NOTIMPLEMENTED();
1766 return NULL;
[email protected]6c8afae52009-01-22 02:24:571767#endif
initial.commit09911bf2008-07-26 23:55:291768}
1769
[email protected]4e6be3f2009-05-07 02:24:441770WebKit::WebMediaPlayer* RenderView::CreateWebMediaPlayer(
1771 WebKit::WebMediaPlayerClient* client) {
[email protected]add51772009-06-11 18:25:171772 scoped_refptr<media::FilterFactoryCollection> factory =
1773 new media::FilterFactoryCollection();
1774 // Add in any custom filter factories first.
1775 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
1776 if (!cmd_line->HasSwitch(switches::kDisableAudio)) {
1777 // Add the chrome specific audio renderer.
1778 factory->AddFactory(
1779 AudioRendererImpl::CreateFactory(audio_message_filter()));
1780 }
[email protected]8380c092009-06-25 17:45:511781
1782 // TODO(hclam): obtain the following parameters from |client|.
1783 webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory =
1784 new webkit_glue::MediaResourceLoaderBridgeFactory(
1785 GURL::EmptyGURL(), // referrer
1786 "null", // frame origin
1787 "null", // main_frame_origin
1788 base::GetCurrentProcId(),
1789 WebAppCacheContext::kNoAppCacheContextId,
1790 routing_id());
1791
[email protected]add51772009-06-11 18:25:171792 if (!cmd_line->HasSwitch(switches::kSimpleDataSource)) {
1793 // Add the chrome specific media data source.
[email protected]70ab61c92009-06-16 19:29:391794 factory->AddFactory(
1795 BufferedDataSource::CreateFactory(MessageLoop::current(),
[email protected]8380c092009-06-25 17:45:511796 bridge_factory));
1797 } else {
1798 factory->AddFactory(
1799 webkit_glue::SimpleDataSource::CreateFactory(MessageLoop::current(),
1800 bridge_factory));
[email protected]add51772009-06-11 18:25:171801 }
1802 return new webkit_glue::WebMediaPlayerImpl(client, factory);
[email protected]ec9212f2008-12-18 21:40:361803}
1804
initial.commit09911bf2008-07-26 23:55:291805void RenderView::OnMissingPluginStatus(WebPluginDelegate* delegate,
1806 int status) {
[email protected]6c8afae52009-01-22 02:24:571807#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291808 if (first_default_plugin_ == NULL) {
1809 // Show the InfoBar for the first available plugin.
1810 if (status == default_plugin::MISSING_PLUGIN_AVAILABLE) {
1811 first_default_plugin_ = delegate;
1812 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1813 }
1814 } else {
1815 // Closes the InfoBar if user clicks on the plugin (instead of the InfoBar)
1816 // to start the download/install.
1817 if (status == default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD) {
1818 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1819 }
1820 }
[email protected]6c8afae52009-01-22 02:24:571821#else
1822 // TODO(port): plugins current not supported
1823 NOTIMPLEMENTED();
1824#endif
initial.commit09911bf2008-07-26 23:55:291825}
1826
[email protected]eb47a132009-03-04 00:39:561827WebWorker* RenderView::CreateWebWorker(WebWorkerClient* client) {
1828#if defined(OS_WIN)
[email protected]ec775ef2009-05-01 21:20:471829 return new WebWorkerProxy(client, RenderThread::current(), routing_id_);
[email protected]eb47a132009-03-04 00:39:561830#else
1831 // TODO(port): out of process workers
1832 NOTIMPLEMENTED();
1833 return NULL;
1834#endif
1835}
1836
initial.commit09911bf2008-07-26 23:55:291837void RenderView::OpenURL(WebView* webview, const GURL& url,
[email protected]c0588052008-10-27 23:01:501838 const GURL& referrer,
initial.commit09911bf2008-07-26 23:55:291839 WindowOpenDisposition disposition) {
[email protected]c0588052008-10-27 23:01:501840 Send(new ViewHostMsg_OpenURL(routing_id_, url, referrer, disposition));
initial.commit09911bf2008-07-26 23:55:291841}
1842
[email protected]1d522202009-04-04 01:56:421843void RenderView::DidContentsSizeChange(WebWidget* webwidget,
1844 int new_width,
1845 int new_height) {
[email protected]0666aef2009-05-13 19:48:081846 // We don't always want to send the change messages over IPC, only if we've
1847 // be put in that mode by getting a |ViewMsg_EnableIntrinsicWidthChangedMode|
1848 // message.
1849 // TODO(rafaelw): Figure out where the best place to set this for extensions
1850 // is. It isn't clean to test for ExtensionView by examining the
1851 // enabled_bindings. This needs to be generalized as it becomes clear what
1852 // extension toolbars need.
1853 if (BindingsPolicy::is_extension_enabled(enabled_bindings_) ||
1854 send_preferred_width_changes_) {
1855 // WebCore likes to tell us things have changed even when they haven't, so
1856 // cache the width and only send the IPC message when we're sure the
1857 // width is different.
[email protected]1d522202009-04-04 01:56:421858 int width = webview()->GetMainFrame()->GetContentsPreferredWidth();
[email protected]0666aef2009-05-13 19:48:081859 if (width != preferred_width_) {
1860 Send(new ViewHostMsg_DidContentsPreferredWidthChange(routing_id_, width));
1861 preferred_width_ = width;
1862 }
[email protected]1d522202009-04-04 01:56:421863 }
1864}
1865
initial.commit09911bf2008-07-26 23:55:291866// We are supposed to get a single call to Show for a newly created RenderView
1867// that was created via RenderView::CreateWebView. So, we wait until this
1868// point to dispatch the ShowView message.
1869//
1870// This method provides us with the information about how to display the newly
1871// created RenderView (i.e., as a constrained popup or as a new tab).
1872//
1873void RenderView::Show(WebWidget* webwidget, WindowOpenDisposition disposition) {
1874 DCHECK(!did_show_) << "received extraneous Show call";
1875 DCHECK(opener_id_ != MSG_ROUTING_NONE);
1876
1877 if (did_show_)
1878 return;
1879 did_show_ = true;
1880
1881 // NOTE: initial_pos_ may still have its default values at this point, but
1882 // that's okay. It'll be ignored if disposition is not NEW_POPUP, or the
1883 // browser process will impose a default position otherwise.
[email protected]35f7d212009-04-29 21:19:271884 Send(new ViewHostMsg_ShowView(opener_id_, routing_id_, disposition,
[email protected]c88a70fe2009-05-05 20:00:221885 initial_pos_, opened_by_user_gesture_, creator_url_));
[email protected]2533ce12009-05-09 00:02:241886 SetPendingWindowRect(initial_pos_);
initial.commit09911bf2008-07-26 23:55:291887}
1888
[email protected]634a6f92008-12-01 21:39:311889void RenderView::CloseWidgetSoon(WebWidget* webwidget) {
[email protected]2c4410d2009-05-06 23:46:221890 if (!popup_notification_visible_)
[email protected]634a6f92008-12-01 21:39:311891 RenderWidget::CloseWidgetSoon(webwidget);
1892}
1893
initial.commit09911bf2008-07-26 23:55:291894void RenderView::RunModal(WebWidget* webwidget) {
1895 DCHECK(did_show_) << "should already have shown the view";
1896
1897 IPC::SyncMessage* msg = new ViewHostMsg_RunModal(routing_id_);
1898
[email protected]1c4947f2009-01-15 22:25:111899 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291900 Send(msg);
1901}
1902
1903void RenderView::SyncNavigationState() {
1904 if (!webview())
1905 return;
1906
[email protected]ca948a22009-06-25 19:36:171907 const WebHistoryItem& item =
1908 webview()->GetMainFrame()->GetCurrentHistoryItem();
1909 if (item.isNull())
initial.commit09911bf2008-07-26 23:55:291910 return;
[email protected]ca948a22009-06-25 19:36:171911
1912 Send(new ViewHostMsg_UpdateState(
1913 routing_id_, page_id_, webkit_glue::HistoryItemToString(item)));
initial.commit09911bf2008-07-26 23:55:291914}
1915
1916void RenderView::ShowContextMenu(WebView* webview,
[email protected]124646932009-01-28 18:39:021917 ContextNode node,
initial.commit09911bf2008-07-26 23:55:291918 int x,
1919 int y,
1920 const GURL& link_url,
1921 const GURL& image_url,
1922 const GURL& page_url,
1923 const GURL& frame_url,
1924 const std::wstring& selection_text,
1925 const std::wstring& misspelled_word,
[email protected]6aa376b2008-09-23 18:49:521926 int edit_flags,
[email protected]c9825a42009-05-01 22:51:501927 const std::string& security_info,
1928 const std::string& frame_charset) {
[email protected]e09ba552009-02-05 03:26:291929 ContextMenuParams params;
[email protected]124646932009-01-28 18:39:021930 params.node = node;
initial.commit09911bf2008-07-26 23:55:291931 params.x = x;
1932 params.y = y;
1933 params.image_url = image_url;
1934 params.link_url = link_url;
[email protected]e6c79812009-04-22 22:31:421935 params.unfiltered_link_url = link_url;
initial.commit09911bf2008-07-26 23:55:291936 params.page_url = page_url;
1937 params.frame_url = frame_url;
1938 params.selection_text = selection_text;
1939 params.misspelled_word = misspelled_word;
[email protected]be645db2009-02-06 20:36:331940 params.spellcheck_enabled =
[email protected]bbbd545c2008-12-15 20:18:041941 webview->GetFocusedFrame()->SpellCheckEnabled();
initial.commit09911bf2008-07-26 23:55:291942 params.edit_flags = edit_flags;
[email protected]6aa376b2008-09-23 18:49:521943 params.security_info = security_info;
[email protected]c9825a42009-05-01 22:51:501944 params.frame_charset = frame_charset;
initial.commit09911bf2008-07-26 23:55:291945 Send(new ViewHostMsg_ContextMenu(routing_id_, params));
1946}
1947
[email protected]e80c73b2009-04-07 23:24:581948void RenderView::StartDragging(WebView* webview,
1949 const WebDragData& drag_data) {
1950 Send(new ViewHostMsg_StartDragging(routing_id_, WebDropData(drag_data)));
initial.commit09911bf2008-07-26 23:55:291951}
1952
1953void RenderView::TakeFocus(WebView* webview, bool reverse) {
1954 Send(new ViewHostMsg_TakeFocus(routing_id_, reverse));
1955}
1956
1957void RenderView::DidDownloadImage(int id,
1958 const GURL& image_url,
1959 bool errored,
1960 const SkBitmap& image) {
1961 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, errored,
1962 image));
1963}
1964
1965
1966void RenderView::OnDownloadImage(int id,
1967 const GURL& image_url,
1968 int image_size) {
[email protected]f11ca0732009-04-11 00:09:341969 bool data_image_failed = false;
1970 if (image_url.SchemeIs("data")) {
1971 SkBitmap data_image = ImageFromDataUrl(image_url);
1972 data_image_failed = data_image.empty();
1973 if (!data_image_failed) {
1974 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, false,
1975 data_image));
1976 }
1977 }
1978
1979 if (data_image_failed || !webview()->DownloadImage(id, image_url, image_size))
initial.commit09911bf2008-07-26 23:55:291980 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, true,
1981 SkBitmap()));
1982}
1983
[email protected]f11ca0732009-04-11 00:09:341984SkBitmap RenderView::ImageFromDataUrl(const GURL& url) const {
1985 std::string mime_type, char_set, data;
1986 if (net::DataURL::Parse(url, &mime_type, &char_set, &data) && !data.empty()) {
1987 // Decode the favicon using WebKit's image decoder.
1988 webkit_glue::ImageDecoder decoder(gfx::Size(kFavIconSize, kFavIconSize));
1989 const unsigned char* src_data =
1990 reinterpret_cast<const unsigned char*>(&data[0]);
1991
1992 return decoder.Decode(src_data, data.size());
1993 }
1994 return SkBitmap();
1995}
1996
initial.commit09911bf2008-07-26 23:55:291997void RenderView::OnGetApplicationInfo(int page_id) {
1998 webkit_glue::WebApplicationInfo app_info;
1999 if (page_id == page_id_)
2000 webkit_glue::GetApplicationInfo(webview(), &app_info);
2001
2002 // Prune out any data URLs in the set of icons. The browser process expects
2003 // any icon with a data URL to have originated from a favicon. We don't want
2004 // to decode arbitrary data URLs in the browser process. See
2005 // http://b/issue?id=1162972
2006 for (size_t i = 0; i < app_info.icons.size(); ++i) {
[email protected]6de74452009-02-25 18:04:592007 if (app_info.icons[i].url.SchemeIs(chrome::kDataScheme)) {
initial.commit09911bf2008-07-26 23:55:292008 app_info.icons.erase(app_info.icons.begin() + i);
2009 --i;
2010 }
2011 }
2012
2013 Send(new ViewHostMsg_DidGetApplicationInfo(routing_id_, page_id, app_info));
2014}
2015
2016GURL RenderView::GetAlternateErrorPageURL(const GURL& failedURL,
2017 ErrorPageType error_type) {
2018 if (failedURL.SchemeIsSecure()) {
2019 // If the URL that failed was secure, then the embedding web page was not
2020 // expecting a network attacker to be able to manipulate its contents. As
2021 // we fetch alternate error pages over HTTP, we would be allowing a network
2022 // attacker to manipulate the contents of the response if we tried to use
2023 // the link doctor here.
2024 return GURL::EmptyGURL();
2025 }
2026
2027 // Grab the base URL from the browser process.
2028 if (!alternate_error_page_url_.is_valid())
2029 return GURL::EmptyGURL();
2030
2031 // Strip query params from the failed URL.
2032 GURL::Replacements remove_params;
2033 remove_params.ClearUsername();
2034 remove_params.ClearPassword();
2035 remove_params.ClearQuery();
2036 remove_params.ClearRef();
2037 const GURL url_to_send = failedURL.ReplaceComponents(remove_params);
2038
2039 // Construct the query params to send to link doctor.
2040 std::string params(alternate_error_page_url_.query());
2041 params.append("&url=");
2042 params.append(EscapeQueryParamValue(url_to_send.spec()));
2043 params.append("&sourceid=chrome");
2044 params.append("&error=");
2045 switch (error_type) {
2046 case DNS_ERROR:
2047 params.append("dnserror");
2048 break;
2049
2050 case HTTP_404:
2051 params.append("http404");
2052 break;
2053
[email protected]5df266ac2008-10-15 19:50:132054 case CONNECTION_ERROR:
[email protected]e1f934b2009-01-26 20:41:332055 params.append("connectionfailure");
[email protected]5df266ac2008-10-15 19:50:132056 break;
2057
initial.commit09911bf2008-07-26 23:55:292058 default:
2059 NOTREACHED() << "unknown ErrorPageType";
2060 }
2061
2062 // OK, build the final url to return.
2063 GURL::Replacements link_doctor_params;
2064 link_doctor_params.SetQueryStr(params);
2065 GURL url = alternate_error_page_url_.ReplaceComponents(link_doctor_params);
2066 return url;
2067}
2068
[email protected]7ea066a2009-04-06 20:21:592069void RenderView::OnFind(int request_id,
2070 const string16& search_text,
2071 const WebKit::WebFindOptions& options) {
initial.commit09911bf2008-07-26 23:55:292072 WebFrame* main_frame = webview()->GetMainFrame();
2073 WebFrame* frame_after_main = webview()->GetNextFrameAfter(main_frame, true);
2074 WebFrame* focused_frame = webview()->GetFocusedFrame();
2075 WebFrame* search_frame = focused_frame; // start searching focused frame.
2076
2077 bool multi_frame = (frame_after_main != main_frame);
2078
2079 // If we have multiple frames, we don't want to wrap the search within the
2080 // frame, so we check here if we only have main_frame in the chain.
2081 bool wrap_within_frame = !multi_frame;
2082
[email protected]b3f2b912009-04-09 16:18:522083 WebRect selection_rect;
initial.commit09911bf2008-07-26 23:55:292084 bool result = false;
2085
2086 do {
[email protected]7ea066a2009-04-06 20:21:592087 result = search_frame->Find(
2088 request_id, search_text, options, wrap_within_frame, &selection_rect);
initial.commit09911bf2008-07-26 23:55:292089
2090 if (!result) {
2091 // don't leave text selected as you move to the next frame.
2092 search_frame->ClearSelection();
2093
2094 // Find the next frame, but skip the invisible ones.
2095 do {
2096 // What is the next frame to search? (we might be going backwards). Note
2097 // that we specify wrap=true so that search_frame never becomes NULL.
[email protected]7ea066a2009-04-06 20:21:592098 search_frame = options.forward ?
initial.commit09911bf2008-07-26 23:55:292099 webview()->GetNextFrameAfter(search_frame, true) :
2100 webview()->GetPreviousFrameBefore(search_frame, true);
2101 } while (!search_frame->Visible() && search_frame != focused_frame);
2102
[email protected]884db412008-11-24 23:46:502103 // Make sure selection doesn't affect the search operation in new frame.
initial.commit09911bf2008-07-26 23:55:292104 search_frame->ClearSelection();
2105
2106 // If we have multiple frames and we have wrapped back around to the
2107 // focused frame, we need to search it once more allowing wrap within
2108 // the frame, otherwise it will report 'no match' if the focused frame has
2109 // reported matches, but no frames after the focused_frame contain a
2110 // match for the search word(s).
2111 if (multi_frame && search_frame == focused_frame) {
[email protected]7ea066a2009-04-06 20:21:592112 result = search_frame->Find(
2113 request_id, search_text, options, true, // Force wrapping.
2114 &selection_rect);
initial.commit09911bf2008-07-26 23:55:292115 }
2116 }
2117
2118 // TODO(jcampan): http://b/issue?id=1157486 Remove StoreForFocus call once
2119 // we have the fix for 792423.
2120 search_frame->GetView()->StoreFocusForFrame(search_frame);
2121 webview()->SetFocusedFrame(search_frame);
2122 } while (!result && search_frame != focused_frame);
2123
2124 // Make sure we don't leave any frame focused or the focus won't be restored
2125 // properly in WebViewImpl::SetFocus(). Note that we are talking here about
2126 // focused on the SelectionController, not FocusController.
2127 // webview()->GetFocusedFrame() will still return the last focused frame (as
2128 // it queries the FocusController).
2129 // TODO(jcampan): http://b/issue?id=1157486 Remove next line once we have the
2130 // fix for 792423.
2131 webview()->SetFocusedFrame(NULL);
2132
[email protected]7ea066a2009-04-06 20:21:592133 if (options.findNext) {
[email protected]4f3dc372009-02-24 00:10:292134 // Force the main_frame to report the actual count.
[email protected]7ea066a2009-04-06 20:21:592135 main_frame->IncreaseMatchCount(0, request_id);
[email protected]4f3dc372009-02-24 00:10:292136 } else {
2137 // If nothing is found, set result to "0 of 0", otherwise, set it to
2138 // "-1 of 1" to indicate that we found at least one item, but we don't know
2139 // yet what is active.
2140 int ordinal = result ? -1 : 0; // -1 here means, we might know more later.
2141 int match_count = result ? 1 : 0; // 1 here means possibly more coming.
initial.commit09911bf2008-07-26 23:55:292142
[email protected]4f3dc372009-02-24 00:10:292143 // If we find no matches then this will be our last status update.
2144 // Otherwise the scoping effort will send more results.
2145 bool final_status_update = !result;
initial.commit09911bf2008-07-26 23:55:292146
[email protected]4f3dc372009-02-24 00:10:292147 // Send the search result over to the browser process.
[email protected]4f999132009-03-31 18:08:402148 Send(new ViewHostMsg_Find_Reply(routing_id_,
[email protected]7ea066a2009-04-06 20:21:592149 request_id,
[email protected]4f3dc372009-02-24 00:10:292150 match_count,
2151 selection_rect,
2152 ordinal,
2153 final_status_update));
initial.commit09911bf2008-07-26 23:55:292154
initial.commit09911bf2008-07-26 23:55:292155 // Scoping effort begins, starting with the mainframe.
2156 search_frame = main_frame;
2157
2158 main_frame->ResetMatchCount();
2159
2160 do {
2161 // Cancel all old scoping requests before starting a new one.
2162 search_frame->CancelPendingScopingEffort();
2163
2164 // We don't start another scoping effort unless at least one match has
2165 // been found.
2166 if (result) {
2167 // Start new scoping request. If the scoping function determines that it
2168 // needs to scope, it will defer until later.
[email protected]7ea066a2009-04-06 20:21:592169 search_frame->ScopeStringMatches(request_id,
2170 search_text,
2171 options,
initial.commit09911bf2008-07-26 23:55:292172 true); // reset the tickmarks
2173 }
2174
2175 // Iterate to the next frame. The frame will not necessarily scope, for
2176 // example if it is not visible.
2177 search_frame = webview()->GetNextFrameAfter(search_frame, true);
2178 } while (search_frame != main_frame);
2179 }
2180}
2181
2182void RenderView::ReportFindInPageMatchCount(int count, int request_id,
2183 bool final_update) {
2184 // If we have a message that has been queued up, then we should just replace
2185 // it. The ACK from the browser will make sure it gets sent when the browser
2186 // wants it.
2187 if (queued_find_reply_message_.get()) {
2188 IPC::Message* msg = new ViewHostMsg_Find_Reply(
2189 routing_id_,
2190 request_id,
2191 count,
[email protected]b3f2b912009-04-09 16:18:522192 gfx::Rect(),
initial.commit09911bf2008-07-26 23:55:292193 -1, // Don't update active match ordinal.
2194 final_update);
2195 queued_find_reply_message_.reset(msg);
2196 } else {
2197 // Send the search result over to the browser process.
2198 Send(new ViewHostMsg_Find_Reply(
2199 routing_id_,
2200 request_id,
2201 count,
[email protected]b3f2b912009-04-09 16:18:522202 gfx::Rect(),
initial.commit09911bf2008-07-26 23:55:292203 -1, // // Don't update active match ordinal.
2204 final_update));
2205 }
2206}
2207
2208void RenderView::ReportFindInPageSelection(int request_id,
2209 int active_match_ordinal,
[email protected]b3f2b912009-04-09 16:18:522210 const WebRect& selection_rect) {
initial.commit09911bf2008-07-26 23:55:292211 // Send the search result over to the browser process.
2212 Send(new ViewHostMsg_Find_Reply(routing_id_,
2213 request_id,
2214 -1,
2215 selection_rect,
2216 active_match_ordinal,
2217 false));
2218}
2219
[email protected]ed4bf2d2009-05-05 00:10:062220bool RenderView::WasOpenedByUserGesture() const {
initial.commit09911bf2008-07-26 23:55:292221 return opened_by_user_gesture_;
2222}
2223
[email protected]7f40fc5b2009-06-12 19:23:082224void RenderView::SpellCheck(const std::wstring& word, int* misspell_location,
2225 int* misspell_length) {
2226 Send(new ViewHostMsg_SpellCheck(routing_id_, word, misspell_location,
2227 misspell_length));
initial.commit09911bf2008-07-26 23:55:292228}
2229
[email protected]26ea6c42009-06-10 22:32:212230std::wstring RenderView::GetAutoCorrectWord(
2231 const std::wstring& misspelled_word) {
2232 std::wstring autocorrect_word;
[email protected]eda2b5a2009-05-12 19:30:212233 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2234 if (command_line.HasSwitch(switches::kAutoSpellCorrect)) {
2235 Send(new ViewHostMsg_GetAutoCorrectWord(routing_id_, misspelled_word,
2236 &autocorrect_word));
2237 }
[email protected]26ea6c42009-06-10 22:32:212238
2239 return autocorrect_word;
[email protected]eda2b5a2009-05-12 19:30:212240}
2241
initial.commit09911bf2008-07-26 23:55:292242void RenderView::SetInputMethodState(bool enabled) {
2243 // Save the updated IME status and mark the input focus has been updated.
2244 // The IME status is to be sent to a browser process next time when
2245 // the input caret is rendered.
[email protected]9f23f592008-11-17 08:36:342246 if (!ime_control_busy_) {
2247 ime_control_updated_ = true;
2248 ime_control_new_state_ = enabled;
2249 }
initial.commit09911bf2008-07-26 23:55:292250}
2251
2252void RenderView::ScriptedPrint(WebFrame* frame) {
[email protected]0fda7272009-06-26 15:49:332253 Print(frame, true);
initial.commit09911bf2008-07-26 23:55:292254}
2255
initial.commit09911bf2008-07-26 23:55:292256void RenderView::UserMetricsRecordAction(const std::wstring& action) {
2257 Send(new ViewHostMsg_UserMetricsRecordAction(routing_id_, action));
2258}
2259
2260void RenderView::DnsPrefetch(const std::vector<std::string>& host_names) {
2261 Send(new ViewHostMsg_DnsPrefetch(host_names));
2262}
2263
[email protected]630e26b2008-10-14 22:55:172264void RenderView::OnZoom(int function) {
2265 static const bool kZoomIsTextOnly = false;
2266 switch (function) {
2267 case PageZoom::SMALLER:
2268 webview()->ZoomOut(kZoomIsTextOnly);
initial.commit09911bf2008-07-26 23:55:292269 break;
[email protected]630e26b2008-10-14 22:55:172270 case PageZoom::STANDARD:
2271 webview()->ResetZoom();
initial.commit09911bf2008-07-26 23:55:292272 break;
[email protected]630e26b2008-10-14 22:55:172273 case PageZoom::LARGER:
2274 webview()->ZoomIn(kZoomIsTextOnly);
initial.commit09911bf2008-07-26 23:55:292275 break;
2276 default:
2277 NOTREACHED();
2278 }
2279}
2280
[email protected]ea8c7452009-04-02 20:47:062281void RenderView::OnInsertText(const string16& text) {
[email protected]5f9e0b82009-05-08 22:13:392282 WebFrame* frame = webview()->GetFocusedFrame();
2283 if (!frame)
2284 return;
2285 WebTextInput* text_input = frame->GetTextInput();
[email protected]00d7e622009-04-21 23:06:052286 if (text_input)
[email protected]7be0e172009-05-14 01:05:272287 text_input->InsertText(text);
[email protected]ea8c7452009-04-02 20:47:062288}
2289
[email protected]e38f40152008-09-12 23:08:302290void RenderView::OnSetPageEncoding(const std::wstring& encoding_name) {
initial.commit09911bf2008-07-26 23:55:292291 webview()->SetPageEncoding(encoding_name);
2292}
2293
[email protected]f6e59a62009-05-13 21:12:032294void RenderView::NavigateBackForwardSoon(int offset) {
[email protected]f46aff62008-10-16 07:58:052295 history_back_list_count_ += offset;
2296 history_forward_list_count_ -= offset;
2297
initial.commit09911bf2008-07-26 23:55:292298 Send(new ViewHostMsg_GoToEntryAtOffset(routing_id_, offset));
2299}
2300
2301int RenderView::GetHistoryBackListCount() {
2302 return history_back_list_count_;
2303}
2304
2305int RenderView::GetHistoryForwardListCount() {
2306 return history_forward_list_count_;
2307}
2308
2309void RenderView::OnNavStateChanged(WebView* webview) {
[email protected]81a34412009-01-05 19:17:242310 if (!nav_state_sync_timer_.IsRunning()) {
2311 nav_state_sync_timer_.Start(
2312 TimeDelta::FromSeconds(delay_seconds_for_form_state_sync_), this,
2313 &RenderView::SyncNavigationState);
2314 }
initial.commit09911bf2008-07-26 23:55:292315}
2316
2317void RenderView::SetTooltipText(WebView* webview,
2318 const std::wstring& tooltip_text) {
2319 Send(new ViewHostMsg_SetTooltipText(routing_id_, tooltip_text));
2320}
2321
[email protected]2e417c82009-04-02 22:30:262322void RenderView::DidChangeSelection(bool is_empty_selection) {
2323#if defined(OS_LINUX)
[email protected]d5d7b8002009-05-18 21:20:542324 // TODO(estade): investigate incremental updates to the selection so that we
2325 // don't send the entire selection over IPC every time.
[email protected]2e417c82009-04-02 22:30:262326 if (!is_empty_selection) {
[email protected]d5d7b8002009-05-18 21:20:542327 // Sometimes we get repeated DidChangeSelection calls from webkit when
2328 // the selection hasn't actually changed. We don't want to report these
2329 // because it will cause us to continually claim the X clipboard.
2330 const std::string& this_selection =
2331 webview()->GetFocusedFrame()->GetSelection(false);
2332 if (this_selection == last_selection_)
2333 return;
2334
[email protected]dbadbcc2009-04-09 00:57:102335 Send(new ViewHostMsg_SelectionChanged(routing_id_,
[email protected]d5d7b8002009-05-18 21:20:542336 this_selection));
2337 last_selection_ = this_selection;
[email protected]4f61a022009-06-25 23:49:012338 } else {
2339 last_selection_.clear();
[email protected]2e417c82009-04-02 22:30:262340 }
2341#endif
2342}
2343
initial.commit09911bf2008-07-26 23:55:292344void RenderView::DownloadUrl(const GURL& url, const GURL& referrer) {
2345 Send(new ViewHostMsg_DownloadUrl(routing_id_, url, referrer));
2346}
2347
[email protected]0df30122009-06-03 12:13:082348void RenderView::UpdateInspectorSettings(const std::wstring& raw_settings) {
2349 Send(new ViewHostMsg_UpdateInspectorSettings(routing_id_, raw_settings));
2350}
2351
[email protected]611cad42009-03-16 18:51:342352WebDevToolsAgentDelegate* RenderView::GetWebDevToolsAgentDelegate() {
[email protected]b75b7d072009-04-06 13:47:002353 return devtools_agent_.get();
[email protected]611cad42009-03-16 18:51:342354}
2355
[email protected]ea8c7452009-04-02 20:47:062356void RenderView::PasteFromSelectionClipboard() {
2357 Send(new ViewHostMsg_PasteFromSelectionClipboard(routing_id_));
2358}
2359
initial.commit09911bf2008-07-26 23:55:292360WebFrame* RenderView::GetChildFrame(const std::wstring& frame_xpath) const {
2361 WebFrame* web_frame;
2362 if (frame_xpath.empty()) {
2363 web_frame = webview()->GetMainFrame();
2364 } else {
2365 web_frame = webview()->GetMainFrame()->GetChildFrame(frame_xpath);
2366 }
2367
2368 return web_frame;
2369}
2370
[email protected]f29acf52008-11-03 20:08:332371void RenderView::EvaluateScript(const std::wstring& frame_xpath,
2372 const std::wstring& script) {
initial.commit09911bf2008-07-26 23:55:292373 WebFrame* web_frame = GetChildFrame(frame_xpath);
2374 if (!web_frame)
2375 return;
2376
[email protected]4f999132009-03-31 18:08:402377 web_frame->ExecuteScript(WebScriptSource(WideToUTF16Hack(script)));
initial.commit09911bf2008-07-26 23:55:292378}
2379
[email protected]1810e132009-03-24 23:35:482380void RenderView::InsertCSS(const std::wstring& frame_xpath,
2381 const std::string& css) {
2382 WebFrame* web_frame = GetChildFrame(frame_xpath);
2383 if (!web_frame)
2384 return;
2385
2386 web_frame->InsertCSSStyles(css);
2387}
2388
initial.commit09911bf2008-07-26 23:55:292389void RenderView::OnScriptEvalRequest(const std::wstring& frame_xpath,
2390 const std::wstring& jscript) {
[email protected]f29acf52008-11-03 20:08:332391 EvaluateScript(frame_xpath, jscript);
initial.commit09911bf2008-07-26 23:55:292392}
2393
[email protected]1810e132009-03-24 23:35:482394void RenderView::OnCSSInsertRequest(const std::wstring& frame_xpath,
2395 const std::string& css) {
2396 InsertCSS(frame_xpath, css);
[email protected]ae461542009-06-19 19:03:412397
2398 // Notify RenderViewHost that css has been inserted into the frame.
2399 Send(new ViewHostMsg_OnCSSInserted(routing_id_));
[email protected]1810e132009-03-24 23:35:482400}
2401
[email protected]7ea066a2009-04-06 20:21:592402void RenderView::OnAddMessageToConsole(
2403 const string16& frame_xpath,
2404 const string16& message,
2405 const WebConsoleMessage::Level& level) {
2406 WebFrame* web_frame = GetChildFrame(UTF16ToWideHack(frame_xpath));
[email protected]0dea3ea2009-03-31 23:30:592407 if (web_frame)
[email protected]7ea066a2009-04-06 20:21:592408 web_frame->AddMessageToConsole(WebConsoleMessage(level, message));
initial.commit09911bf2008-07-26 23:55:292409}
2410
[email protected]81e63782009-02-27 19:35:092411void RenderView::OnAllowBindings(int enabled_bindings_flags) {
2412 enabled_bindings_ |= enabled_bindings_flags;
initial.commit09911bf2008-07-26 23:55:292413}
2414
2415void RenderView::OnSetDOMUIProperty(const std::string& name,
2416 const std::string& value) {
[email protected]81e63782009-02-27 19:35:092417 DCHECK(BindingsPolicy::is_dom_ui_enabled(enabled_bindings_));
initial.commit09911bf2008-07-26 23:55:292418 dom_ui_bindings_.SetProperty(name, value);
2419}
2420
2421void RenderView::OnReservePageIDRange(int size_of_range) {
2422 next_page_id_ += size_of_range + 1;
2423}
2424
[email protected]e80c73b2009-04-07 23:24:582425void RenderView::OnDragSourceEndedOrMoved(const gfx::Point& client_point,
2426 const gfx::Point& screen_point,
initial.commit09911bf2008-07-26 23:55:292427 bool ended) {
2428 if (ended)
[email protected]e80c73b2009-04-07 23:24:582429 webview()->DragSourceEndedAt(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292430 else
[email protected]e80c73b2009-04-07 23:24:582431 webview()->DragSourceMovedTo(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292432}
2433
2434void RenderView::OnDragSourceSystemDragEnded() {
2435 webview()->DragSourceSystemDragEnded();
2436}
2437
2438void RenderView::OnUploadFileRequest(const ViewMsg_UploadFile_Params& p) {
2439 webkit_glue::FileUploadData* f = new webkit_glue::FileUploadData;
2440 f->file_path = p.file_path;
2441 f->form_name = p.form;
2442 f->file_name = p.file;
2443 f->submit_name = p.submit;
2444
2445 // Build the other form values map.
2446 if (!p.other_values.empty()) {
2447 std::vector<std::wstring> e;
2448 std::vector<std::wstring> kvp;
2449 std::vector<std::wstring>::iterator i;
2450
2451 SplitString(p.other_values, L'\n', &e);
2452 for (i = e.begin(); i != e.end(); ++i) {
2453 SplitString(*i, L'=', &kvp);
2454 if (kvp.size() == 2)
2455 f->other_form_values[kvp[0]] = kvp[1];
2456 kvp.clear();
2457 }
2458 }
2459
2460 pending_upload_data_.reset(f);
2461 ProcessPendingUpload();
2462}
2463
2464void RenderView::ProcessPendingUpload() {
2465 webkit_glue::FileUploadData* f = pending_upload_data_.get();
2466 if (f && webview() && webkit_glue::FillFormToUploadFile(webview(), *f))
2467 ResetPendingUpload();
2468}
2469
2470void RenderView::ResetPendingUpload() {
2471 pending_upload_data_.reset();
2472}
2473
2474void RenderView::OnFormFill(const FormData& form) {
2475 webkit_glue::FillForm(this->webview(), form);
2476}
2477
2478void RenderView::OnFillPasswordForm(
[email protected]daa8c58e2009-06-15 17:21:102479 const webkit_glue::PasswordFormDomManager::FillData& form_data) {
initial.commit09911bf2008-07-26 23:55:292480 webkit_glue::FillPasswordForm(this->webview(), form_data);
2481}
2482
2483void RenderView::OnDragTargetDragEnter(const WebDropData& drop_data,
[email protected]e80c73b2009-04-07 23:24:582484 const gfx::Point& client_point,
2485 const gfx::Point& screen_point) {
2486 bool is_drop_target = webview()->DragTargetDragEnter(
2487 drop_data.ToDragData(),
2488 drop_data.identity,
2489 client_point,
2490 screen_point);
initial.commit09911bf2008-07-26 23:55:292491
2492 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target));
2493}
2494
[email protected]e80c73b2009-04-07 23:24:582495void RenderView::OnDragTargetDragOver(const gfx::Point& client_point,
2496 const gfx::Point& screen_point) {
2497 bool is_drop_target =
2498 webview()->DragTargetDragOver(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292499
2500 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target));
2501}
2502
2503void RenderView::OnDragTargetDragLeave() {
2504 webview()->DragTargetDragLeave();
2505}
2506
[email protected]e80c73b2009-04-07 23:24:582507void RenderView::OnDragTargetDrop(const gfx::Point& client_point,
2508 const gfx::Point& screen_point) {
2509 webview()->DragTargetDrop(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292510}
2511
2512void RenderView::OnUpdateWebPreferences(const WebPreferences& prefs) {
2513 webview()->SetPreferences(prefs);
2514}
2515
2516void RenderView::OnSetAltErrorPageURL(const GURL& url) {
2517 alternate_error_page_url_ = url;
2518}
2519
initial.commit09911bf2008-07-26 23:55:292520void RenderView::OnInstallMissingPlugin() {
2521 // This could happen when the first default plugin is deleted.
2522 if (first_default_plugin_ == NULL)
2523 return;
2524 first_default_plugin_->InstallMissingPlugin();
2525}
2526
[email protected]b62d1a8c2009-01-13 23:54:572527void RenderView::OnFileChooserResponse(
[email protected]561abe62009-04-06 18:08:342528 const std::vector<FilePath>& file_names) {
[email protected]8029f5672009-03-20 22:33:362529 // This could happen if we navigated to a different page before the user
2530 // closed the chooser.
2531 if (!file_chooser_.get())
2532 return;
2533
[email protected]b62d1a8c2009-01-13 23:54:572534 file_chooser_->OnFileChoose(file_names);
initial.commit09911bf2008-07-26 23:55:292535 file_chooser_.reset();
2536}
2537
2538void RenderView::OnEnableViewSourceMode() {
2539 if (!webview())
2540 return;
2541 WebFrame* main_frame = webview()->GetMainFrame();
2542 if (!main_frame)
2543 return;
2544
2545 main_frame->SetInViewSourceMode(true);
2546}
2547
[email protected]0666aef2009-05-13 19:48:082548void RenderView::OnEnableIntrinsicWidthChangedMode() {
2549 send_preferred_width_changes_ = true;
2550}
2551
[email protected]80d96fa2009-06-10 22:34:512552void RenderView::OnSetRendererPrefs(const RendererPreferences& renderer_prefs) {
2553 renderer_preferences_ = renderer_prefs;
2554}
2555
initial.commit09911bf2008-07-26 23:55:292556void RenderView::OnUpdateBackForwardListCount(int back_list_count,
2557 int forward_list_count) {
2558 history_back_list_count_ = back_list_count;
2559 history_forward_list_count_ = forward_list_count;
2560}
2561
[email protected]266eb6f2008-09-30 23:56:502562void RenderView::OnGetAccessibilityInfo(
[email protected]6a983b42009-03-20 20:12:252563 const webkit_glue::WebAccessibility::InParams& in_params,
2564 webkit_glue::WebAccessibility::OutParams* out_params) {
[email protected]6c8afae52009-01-22 02:24:572565#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:252566 if (!web_accessibility_manager_.get()) {
2567 web_accessibility_manager_.reset(
2568 webkit_glue::WebAccessibilityManager::Create());
2569 }
[email protected]266eb6f2008-09-30 23:56:502570
[email protected]6a983b42009-03-20 20:12:252571 if (!web_accessibility_manager_->GetAccObjInfo(webview(), in_params,
2572 out_params)) {
[email protected]266eb6f2008-09-30 23:56:502573 return;
2574 }
[email protected]6c8afae52009-01-22 02:24:572575#else // defined(OS_WIN)
2576 // TODO(port): accessibility not yet implemented
2577 NOTIMPLEMENTED();
2578#endif
[email protected]266eb6f2008-09-30 23:56:502579}
2580
[email protected]6a983b42009-03-20 20:12:252581void RenderView::OnClearAccessibilityInfo(int acc_obj_id, bool clear_all) {
[email protected]6c8afae52009-01-22 02:24:572582#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:252583 if (!web_accessibility_manager_.get()) {
[email protected]266eb6f2008-09-30 23:56:502584 // If accessibility is not activated, ignore clearing message.
2585 return;
2586 }
[email protected]e846d0d2009-05-20 00:53:062587
[email protected]6a983b42009-03-20 20:12:252588 if (!web_accessibility_manager_->ClearAccObjMap(acc_obj_id, clear_all))
[email protected]266eb6f2008-09-30 23:56:502589 return;
[email protected]e846d0d2009-05-20 00:53:062590
[email protected]6c8afae52009-01-22 02:24:572591#else // defined(OS_WIN)
2592 // TODO(port): accessibility not yet implemented
2593 NOTIMPLEMENTED();
2594#endif
[email protected]266eb6f2008-09-30 23:56:502595}
2596
initial.commit09911bf2008-07-26 23:55:292597void RenderView::OnGetAllSavableResourceLinksForCurrentPage(
2598 const GURL& page_url) {
2599 // Prepare list to storage all savable resource links.
2600 std::vector<GURL> resources_list;
2601 std::vector<GURL> referrers_list;
2602 std::vector<GURL> frames_list;
2603 webkit_glue::SavableResourcesResult result(&resources_list,
2604 &referrers_list,
2605 &frames_list);
2606
2607 if (!webkit_glue::GetAllSavableResourceLinksForCurrentPage(webview(),
2608 page_url,
2609 &result)) {
2610 // If something is wrong when collecting all savable resource links,
2611 // send empty list to embedder(browser) to tell it failed.
2612 referrers_list.clear();
2613 resources_list.clear();
2614 frames_list.clear();
2615 }
2616
2617 // Send result of all savable resource links to embedder.
2618 Send(new ViewHostMsg_SendCurrentPageAllSavableResourceLinks(routing_id_,
2619 resources_list,
2620 referrers_list,
2621 frames_list));
2622}
2623
2624void RenderView::OnGetSerializedHtmlDataForCurrentPageWithLocalLinks(
[email protected]f6b48532009-02-12 01:56:322625 const std::vector<GURL>& links,
[email protected]fde6714d12009-02-18 22:39:312626 const std::vector<FilePath>& local_paths,
2627 const FilePath& local_directory_name) {
initial.commit09911bf2008-07-26 23:55:292628 webkit_glue::DomSerializer dom_serializer(webview()->GetMainFrame(),
2629 true,
2630 this,
2631 links,
2632 local_paths,
2633 local_directory_name);
2634 dom_serializer.SerializeDom();
2635}
2636
2637void RenderView::DidSerializeDataForFrame(const GURL& frame_url,
2638 const std::string& data, PageSavingSerializationStatus status) {
2639 Send(new ViewHostMsg_SendSerializedHtmlData(routing_id_,
2640 frame_url, data, static_cast<int32>(status)));
2641}
2642
[email protected]04b4a6c2008-08-02 00:44:472643void RenderView::OnMsgShouldClose() {
initial.commit09911bf2008-07-26 23:55:292644 bool should_close = webview()->ShouldClose();
[email protected]04b4a6c2008-08-02 00:44:472645 Send(new ViewHostMsg_ShouldClose_ACK(routing_id_, should_close));
initial.commit09911bf2008-07-26 23:55:292646}
2647
2648void RenderView::OnClosePage(int new_render_process_host_id,
[email protected]04b4a6c2008-08-02 00:44:472649 int new_request_id) {
initial.commit09911bf2008-07-26 23:55:292650 // TODO(creis): We'd rather use webview()->Close() here, but that currently
2651 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs
2652 // in the onunload handler from appearing. For now, we're bypassing that and
2653 // calling the FrameLoader's CloseURL method directly. This should be
2654 // revisited to avoid having two ways to close a page. Having a single way
2655 // to close that can run onunload is also useful for fixing
2656 // http://b/issue?id=753080.
2657 WebFrame* main_frame = webview()->GetMainFrame();
2658 if (main_frame)
2659 main_frame->ClosePage();
2660
2661 Send(new ViewHostMsg_ClosePage_ACK(routing_id_,
2662 new_render_process_host_id,
[email protected]04b4a6c2008-08-02 00:44:472663 new_request_id));
initial.commit09911bf2008-07-26 23:55:292664}
2665
2666void RenderView::OnThemeChanged() {
[email protected]6c8afae52009-01-22 02:24:572667#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292668 gfx::NativeTheme::instance()->CloseHandles();
2669 gfx::Rect view_rect(0, 0, size_.width(), size_.height());
2670 DidInvalidateRect(webwidget_, view_rect);
[email protected]6c8afae52009-01-22 02:24:572671#else // defined(OS_WIN)
2672 // TODO(port): we don't support theming on non-Windows platforms yet
2673 NOTIMPLEMENTED();
2674#endif
initial.commit09911bf2008-07-26 23:55:292675}
2676
[email protected]f46aff62008-10-16 07:58:052677void RenderView::DidAddHistoryItem() {
[email protected]f8901082008-10-31 23:34:032678 // We don't want to update the history length for the start page
2679 // navigation.
2680 WebFrame* main_frame = webview()->GetMainFrame();
2681 DCHECK(main_frame != NULL);
2682
2683 WebDataSource* ds = main_frame->GetDataSource();
2684 DCHECK(ds != NULL);
2685
[email protected]daa8c58e2009-06-15 17:21:102686 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
2687 if (navigation_state->transition_type() == PageTransition::START_PAGE)
[email protected]f8901082008-10-31 23:34:032688 return;
2689
[email protected]f46aff62008-10-16 07:58:052690 history_back_list_count_++;
2691 history_forward_list_count_ = 0;
2692}
2693
[email protected]28790922009-03-09 19:48:372694void RenderView::OnMessageFromExternalHost(const std::string& message,
2695 const std::string& origin,
2696 const std::string& target) {
[email protected]3ac14a052008-08-15 21:22:152697 if (message.empty())
2698 return;
2699
[email protected]28790922009-03-09 19:48:372700 external_host_bindings_.ForwardMessageFromExternalHost(message, origin,
2701 target);
[email protected]3ac14a052008-08-15 21:22:152702}
2703
[email protected]0aa55312008-10-17 21:53:082704void RenderView::OnDisassociateFromPopupCount() {
2705 if (decrement_shared_popup_at_destruction_)
2706 shared_popup_counter_->data--;
2707 shared_popup_counter_ = new SharedRenderViewCounter(0);
2708 decrement_shared_popup_at_destruction_ = false;
2709}
2710
initial.commit09911bf2008-07-26 23:55:292711std::string RenderView::GetAltHTMLForTemplate(
2712 const DictionaryValue& error_strings, int template_resource_id) const {
2713 const StringPiece template_html(
2714 ResourceBundle::GetSharedInstance().GetRawDataResource(
2715 template_resource_id));
2716
2717 if (template_html.empty()) {
2718 NOTREACHED() << "unable to load template. ID: " << template_resource_id;
2719 return "";
2720 }
2721 // "t" is the id of the templates root node.
2722 return jstemplate_builder::GetTemplateHtml(
2723 template_html, &error_strings, "t");
2724}
[email protected]0e79b9e2009-02-13 04:20:482725
2726MessageLoop* RenderView::GetMessageLoopForIO() {
2727 // Assume that we have only one RenderThread in the process and the owner loop
2728 // of RenderThread is an IO message loop.
[email protected]8930d472009-02-21 08:05:282729 if (RenderThread::current())
2730 return RenderThread::current()->owner_loop();
[email protected]0e79b9e2009-02-13 04:20:482731 return NULL;
2732}
[email protected]6f56d482009-02-20 05:02:562733
[email protected]30f75e62009-02-25 22:01:002734void RenderView::OnMoveOrResizeStarted() {
2735 if (webview())
2736 webview()->HideAutofillPopup();
2737}
2738
[email protected]30f75e62009-02-25 22:01:002739void RenderView::OnResize(const gfx::Size& new_size,
2740 const gfx::Rect& resizer_rect) {
2741 if (webview())
2742 webview()->HideAutofillPopup();
2743 RenderWidget::OnResize(new_size, resizer_rect);
2744}
[email protected]0aa477bd2009-03-23 22:21:432745
[email protected]05d478752009-04-08 23:38:162746void RenderView::OnClearFocusedNode() {
2747 if (webview())
2748 webview()->ClearFocusedNode();
2749}
2750
[email protected]699ab0d2009-04-23 23:19:142751void RenderView::OnSetBackground(const SkBitmap& background) {
2752 if (webview())
2753 webview()->SetIsTransparent(!background.empty());
2754
2755 SetBackground(background);
2756}
2757
[email protected]309d7a282009-03-24 09:18:272758void RenderView::SendExtensionRequest(const std::string& name,
2759 const std::string& args,
[email protected]c6619182009-05-12 14:59:322760 int request_id,
[email protected]2f25d7b92009-06-10 00:06:472761 bool has_callback) {
[email protected]c6619182009-05-12 14:59:322762 Send(new ViewHostMsg_ExtensionRequest(routing_id_, name, args, request_id,
[email protected]2f25d7b92009-06-10 00:06:472763 has_callback));
[email protected]309d7a282009-03-24 09:18:272764}
2765
[email protected]c6619182009-05-12 14:59:322766void RenderView::OnExtensionResponse(int request_id,
2767 bool success,
2768 const std::string& response,
2769 const std::string& error) {
[email protected]2f25d7b92009-06-10 00:06:472770 ExtensionProcessBindings::HandleResponse(request_id, success, response,
2771 error);
[email protected]309d7a282009-03-24 09:18:272772}
[email protected]c20210e62009-04-03 21:39:262773
[email protected]e7e4f3c2009-04-21 15:24:082774// Dump all load time histograms.
[email protected]c20210e62009-04-03 21:39:262775//
[email protected]41da4792009-06-26 16:39:012776// There are 7 histograms measuring various times.
[email protected]c20210e62009-04-03 21:39:262777// The time points we keep are
2778// request: time document was requested by user
2779// start: time load of document started
[email protected]c20210e62009-04-03 21:39:262780// finishDoc: main document loaded, before onload()
2781// finish: after onload() and all resources are loaded
[email protected]e7e4f3c2009-04-21 15:24:082782// firstLayout: first layout performed
[email protected]c20210e62009-04-03 21:39:262783// The times that we histogram are
[email protected]41da4792009-06-26 16:39:012784// requestToStart,
2785// startToFinishDoc,
2786// finishDocToFinish,
2787// startToFinish,
2788// requestToFinish,
2789// requestToFirstLayout
2790// startToFirstLayout
[email protected]c20210e62009-04-03 21:39:262791//
[email protected]e7e4f3c2009-04-21 15:24:082792// It's possible for the request time not to be set, if a client
2793// redirect had been done (the user never requested the page)
2794// Also, it's possible to load a page without ever laying it out
2795// so firstLayout can be 0.
[email protected]c20210e62009-04-03 21:39:262796void RenderView::DumpLoadHistograms() const {
2797 WebFrame* main_frame = webview()->GetMainFrame();
[email protected]ed3fb032009-06-16 19:50:562798 NavigationState* navigation_state =
2799 NavigationState::FromDataSource(main_frame->GetDataSource());
2800
2801 Time request_time = navigation_state->request_time();
2802 Time start_load_time = navigation_state->start_load_time();
[email protected]ed3fb032009-06-16 19:50:562803 Time finish_document_load_time =
2804 navigation_state->finish_document_load_time();
2805 Time finish_load_time = navigation_state->finish_load_time();
[email protected]41da4792009-06-26 16:39:012806 Time first_layout_time = navigation_state->first_layout_time();
[email protected]ed3fb032009-06-16 19:50:562807
[email protected]c20210e62009-04-03 21:39:262808 TimeDelta request_to_start = start_load_time - request_time;
[email protected]41da4792009-06-26 16:39:012809 TimeDelta start_to_finish_doc = finish_document_load_time - start_load_time;
[email protected]e7e4f3c2009-04-21 15:24:082810 TimeDelta finish_doc_to_finish =
2811 finish_load_time - finish_document_load_time;
[email protected]41da4792009-06-26 16:39:012812 TimeDelta start_to_finish = finish_load_time - start_load_time;
[email protected]978077e2009-06-20 22:32:512813 TimeDelta request_to_finish = finish_load_time - request_time;
[email protected]41da4792009-06-26 16:39:012814 TimeDelta request_to_first_layout = first_layout_time - request_time;
2815 TimeDelta start_to_first_layout = first_layout_time - start_load_time;
[email protected]c20210e62009-04-03 21:39:262816
[email protected]e7e4f3c2009-04-21 15:24:082817 // Client side redirects will have no request time
2818 if (request_time.ToInternalValue() != 0) {
[email protected]41da4792009-06-26 16:39:012819 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.RequestToStart", request_to_start);
[email protected]978077e2009-06-20 22:32:512820 UMA_HISTOGRAM_CUSTOM_TIMES(
[email protected]41da4792009-06-26 16:39:012821 FieldTrial::MakeName("Renderer2.RequestToFinish_2", "DnsImpact").data(),
[email protected]ed3fb032009-06-16 19:50:562822 request_to_finish, TimeDelta::FromMilliseconds(10),
2823 TimeDelta::FromMinutes(10), 100);
[email protected]41da4792009-06-26 16:39:012824 if (request_to_first_layout.ToInternalValue() >= 0) {
2825 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.RequestToFirstLayout",
2826 request_to_first_layout);
[email protected]e7e4f3c2009-04-21 15:24:082827 }
2828 }
[email protected]41da4792009-06-26 16:39:012829 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.StartToFinishDoc", start_to_finish_doc);
2830 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.FinishDocToFinish",
[email protected]f929f2f22009-06-12 16:56:582831 finish_doc_to_finish);
[email protected]41da4792009-06-26 16:39:012832 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.StartToFinish", start_to_finish);
2833 if (start_to_first_layout.ToInternalValue() >= 0) {
2834 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer2.StartToFirstLayout",
2835 start_to_first_layout);
[email protected]c20210e62009-04-03 21:39:262836 }
2837}
[email protected]e846d0d2009-05-20 00:53:062838
2839void RenderView::FocusAccessibilityObject(
2840 WebCore::AccessibilityObject* acc_obj) {
2841#if defined(OS_WIN)
2842 if (!web_accessibility_manager_.get()) {
2843 web_accessibility_manager_.reset(
2844 webkit_glue::WebAccessibilityManager::Create());
2845 }
2846
2847 // Retrieve the accessibility object id of the AccessibilityObject.
2848 int acc_obj_id = web_accessibility_manager_->FocusAccObj(acc_obj);
2849
2850 // If id is valid, alert the browser side that an accessibility focus change
2851 // occurred.
2852 if (acc_obj_id >= 0)
2853 Send(new ViewHostMsg_AccessibilityFocusChange(routing_id_, acc_obj_id));
2854
2855#else // defined(OS_WIN)
2856 // TODO(port): accessibility not yet implemented
2857 NOTIMPLEMENTED();
2858#endif
2859}
[email protected]daa8c58e2009-06-15 17:21:102860
2861void RenderView::SendPasswordForms(WebFrame* frame) {
2862 std::vector<WebForm> forms;
2863 frame->GetForms(&forms);
2864
2865 std::vector<PasswordForm> password_forms;
2866 for (size_t i = 0; i < forms.size(); ++i) {
2867 const WebForm& form = forms[i];
2868
2869 // Respect autocomplete=off.
2870 if (form.isAutoCompleteEnabled()) {
2871 scoped_ptr<PasswordForm> password_form(
2872 PasswordFormDomManager::CreatePasswordForm(form));
2873 if (password_form.get())
2874 password_forms.push_back(*password_form);
2875 }
2876 }
2877
2878 if (!password_forms.empty())
2879 Send(new ViewHostMsg_PasswordFormsSeen(routing_id_, password_forms));
2880}
[email protected]0fda7272009-06-26 15:49:332881
2882void RenderView::Print(WebFrame* frame, bool script_initiated) {
2883 DCHECK(frame);
2884 if (print_helper_.get() == NULL) {
2885 print_helper_.reset(new PrintWebViewHelper(this));
2886 }
2887 print_helper_->Print(frame, script_initiated);
2888}