blob: 6664d1c5827720874ea8de42fea63f8e4548e3d9 [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]9929da92009-05-05 02:05:1111#include "app/resource_bundle.h"
initial.commit09911bf2008-07-26 23:55:2912#include "base/command_line.h"
[email protected]bb063b72009-03-27 23:18:5013#include "base/compiler_specific.h"
initial.commit09911bf2008-07-26 23:55:2914#include "base/gfx/png_encoder.h"
[email protected]18bcc3c2009-01-27 21:39:1515#include "base/gfx/native_widget_types.h"
initial.commit09911bf2008-07-26 23:55:2916#include "base/string_piece.h"
17#include "base/string_util.h"
[email protected]6c8afae52009-01-22 02:24:5718#include "build/build_config.h"
[email protected]81e63782009-02-27 19:35:0919#include "chrome/common/bindings_policy.h"
initial.commit09911bf2008-07-26 23:55:2920#include "chrome/common/chrome_switches.h"
initial.commit09911bf2008-07-26 23:55:2921#include "chrome/common/gfx/favicon_size.h"
22#include "chrome/common/gfx/color_utils.h"
23#include "chrome/common/jstemplate_builder.h"
24#include "chrome/common/l10n_util.h"
[email protected]2e4bdcdc2009-03-27 23:07:3025#include "chrome/common/message_box_flags.h"
[email protected]630e26b2008-10-14 22:55:1726#include "chrome/common/page_zoom.h"
[email protected]e09ba552009-02-05 03:26:2927#include "chrome/common/render_messages.h"
initial.commit09911bf2008-07-26 23:55:2928#include "chrome/common/thumbnail_score.h"
[email protected]6de74452009-02-25 18:04:5929#include "chrome/common/url_constants.h"
initial.commit09911bf2008-07-26 23:55:2930#include "chrome/renderer/about_handler.h"
[email protected]5fb88962009-04-16 19:03:2531#include "chrome/renderer/audio_message_filter.h"
initial.commit09911bf2008-07-26 23:55:2932#include "chrome/renderer/debug_message_handler.h"
[email protected]e4ac5df2009-03-17 15:33:1133#include "chrome/renderer/devtools_agent.h"
34#include "chrome/renderer/devtools_client.h"
[email protected]309d7a282009-03-24 09:18:2735#include "chrome/renderer/extensions/extension_process_bindings.h"
initial.commit09911bf2008-07-26 23:55:2936#include "chrome/renderer/localized_error.h"
[email protected]6f56d482009-02-20 05:02:5637#include "chrome/renderer/media/audio_renderer_impl.h"
[email protected]39008c02009-02-11 23:59:2538#include "chrome/renderer/render_process.h"
[email protected]fcf19542009-03-30 21:24:0739#include "chrome/renderer/renderer_logging.h"
[email protected]0938d3c2009-01-09 20:37:3540#include "chrome/renderer/user_script_slave.h"
initial.commit09911bf2008-07-26 23:55:2941#include "chrome/renderer/visitedlink_slave.h"
[email protected]ec9212f2008-12-18 21:40:3642#include "chrome/renderer/webmediaplayer_delegate_impl.h"
[email protected]ba4b17f2009-02-11 21:32:2943#include "chrome/renderer/webplugin_delegate_proxy.h"
[email protected]eb47a132009-03-04 00:39:5644#include "chrome/renderer/webworker_proxy.h"
[email protected]34ac8f32009-02-22 23:03:2745#include "grit/generated_resources.h"
46#include "grit/renderer_resources.h"
[email protected]f11ca0732009-04-11 00:09:3447#include "net/base/data_url.h"
initial.commit09911bf2008-07-26 23:55:2948#include "net/base/escape.h"
49#include "net/base/net_errors.h"
[email protected]88a3ecc2009-03-19 17:36:2250#include "printing/units.h"
[email protected]c399a8a2008-11-22 19:38:0051#include "skia/ext/bitmap_platform_device.h"
[email protected]83c9e6552008-12-03 16:22:1052#include "skia/ext/image_operations.h"
[email protected]e80c73b2009-04-07 23:24:5853#include "third_party/WebKit/WebKit/chromium/public/WebDragData.h"
54#include "third_party/WebKit/WebKit/chromium/public/WebPoint.h"
[email protected]b3f2b912009-04-09 16:18:5255#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
[email protected]4f999132009-03-31 18:08:4056#include "third_party/WebKit/WebKit/chromium/public/WebScriptSource.h"
[email protected]b3f2b912009-04-09 16:18:5257#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
[email protected]ba4b17f2009-02-11 21:32:2958#include "webkit/default_plugin/default_plugin_shared.h"
initial.commit09911bf2008-07-26 23:55:2959#include "webkit/glue/dom_operations.h"
60#include "webkit/glue/dom_serializer.h"
[email protected]f11ca0732009-04-11 00:09:3461#include "webkit/glue/image_decoder.h"
initial.commit09911bf2008-07-26 23:55:2962#include "webkit/glue/password_form.h"
[email protected]ba4b17f2009-02-11 21:32:2963#include "webkit/glue/plugins/plugin_list.h"
initial.commit09911bf2008-07-26 23:55:2964#include "webkit/glue/searchable_form_data.h"
[email protected]6a983b42009-03-20 20:12:2565#include "webkit/glue/webaccessibilitymanager_impl.h"
initial.commit09911bf2008-07-26 23:55:2966#include "webkit/glue/webdatasource.h"
[email protected]611cad42009-03-16 18:51:3467#include "webkit/glue/webdevtoolsagent_delegate.h"
initial.commit09911bf2008-07-26 23:55:2968#include "webkit/glue/webdropdata.h"
69#include "webkit/glue/weberror.h"
70#include "webkit/glue/webframe.h"
[email protected]81cf6f72009-05-04 22:18:2971#include "webkit/glue/webhistoryitem.h"
initial.commit09911bf2008-07-26 23:55:2972#include "webkit/glue/webkit_glue.h"
73#include "webkit/glue/webpreferences.h"
[email protected]b94d3322009-02-12 19:49:0474#include "webkit/glue/webplugin_delegate.h"
initial.commit09911bf2008-07-26 23:55:2975#include "webkit/glue/webresponse.h"
[email protected]00d7e622009-04-21 23:06:0576#include "webkit/glue/webtextinput.h"
initial.commit09911bf2008-07-26 23:55:2977#include "webkit/glue/weburlrequest.h"
78#include "webkit/glue/webview.h"
initial.commit09911bf2008-07-26 23:55:2979
[email protected]6c8afae52009-01-22 02:24:5780#if defined(OS_WIN)
81// TODO(port): these files are currently Windows only because they concern:
[email protected]f8b6b6f2009-03-10 16:48:2682// * logging
[email protected]6c8afae52009-01-22 02:24:5783// * printing
84// * theming
85// * views
86#include "base/gfx/gdi_util.h"
87#include "base/gfx/native_theme.h"
88#include "chrome/common/gfx/emf.h"
[email protected]fcf19542009-03-30 21:24:0789#include "chrome/views/controls/message_box_view.h"
[email protected]6c8afae52009-01-22 02:24:5790#include "skia/ext/vector_canvas.h"
[email protected]6c8afae52009-01-22 02:24:5791#endif
92
[email protected]c20210e62009-04-03 21:39:2693using base::Time;
[email protected]e1acf6f2008-10-27 20:43:3394using base::TimeDelta;
[email protected]6a983b42009-03-20 20:12:2595using webkit_glue::WebAccessibility;
[email protected]0dea3ea2009-03-31 23:30:5996using WebKit::WebConsoleMessage;
[email protected]e80c73b2009-04-07 23:24:5897using WebKit::WebDragData;
[email protected]b3f2b912009-04-09 16:18:5298using WebKit::WebRect;
[email protected]4f999132009-03-31 18:08:4099using WebKit::WebScriptSource;
[email protected]27ba8532009-04-24 20:22:43100using WebKit::WebWorker;
101using WebKit::WebWorkerClient;
[email protected]e1acf6f2008-10-27 20:43:33102
initial.commit09911bf2008-07-26 23:55:29103//-----------------------------------------------------------------------------
104
105// define to write the time necessary for thumbnail/DOM text retrieval,
106// respectively, into the system debug log
107// #define TIME_BITMAP_RETRIEVAL
108// #define TIME_TEXT_RETRIEVAL
109
110// maximum number of characters in the document to index, any text beyond this
111// point will be clipped
[email protected]6c8afae52009-01-22 02:24:57112static const size_t kMaxIndexChars = 65535;
initial.commit09911bf2008-07-26 23:55:29113
114// Size of the thumbnails that we'll generate
115static const int kThumbnailWidth = 196;
116static const int kThumbnailHeight = 136;
117
118// Delay in milliseconds that we'll wait before capturing the page contents
119// and thumbnail.
120static const int kDelayForCaptureMs = 500;
121
122// Typically, we capture the page data once the page is loaded.
123// Sometimes, the page never finishes to load, preventing the page capture
124// To workaround this problem, we always perform a capture after the following
125// delay.
126static const int kDelayForForcedCaptureMs = 6000;
127
[email protected]81a34412009-01-05 19:17:24128// The default value for RenderView.delay_seconds_for_form_state_sync_, see
129// that variable for more.
130const int kDefaultDelaySecondsForFormStateSync = 5;
initial.commit09911bf2008-07-26 23:55:29131
132// The next available page ID to use. This ensures that the page IDs are
133// globally unique in the renderer.
134static int32 next_page_id_ = 1;
135
[email protected]0aa55312008-10-17 21:53:08136// The maximum number of popups that can be spawned from one page.
137static const int kMaximumNumberOfUnacknowledgedPopups = 25;
138
initial.commit09911bf2008-07-26 23:55:29139static const char* const kUnreachableWebDataURL =
[email protected]9527f9c2009-01-29 18:35:42140 "chrome-ui://chromewebdata/";
initial.commit09911bf2008-07-26 23:55:29141
[email protected]50b691c2008-10-31 19:08:35142static const char* const kBackForwardNavigationScheme = "history";
143
initial.commit09911bf2008-07-26 23:55:29144namespace {
145
146// Associated with browser-initiated navigations to hold tracking data.
147class RenderViewExtraRequestData : public WebRequest::ExtraData {
148 public:
149 RenderViewExtraRequestData(int32 pending_page_id,
[email protected]c20210e62009-04-03 21:39:26150 PageTransition::Type transition,
151 Time request_time)
[email protected]6c8afae52009-01-22 02:24:57152 : transition_type(transition),
[email protected]c20210e62009-04-03 21:39:26153 request_time(request_time),
[email protected]6c8afae52009-01-22 02:24:57154 request_committed(false),
155 pending_page_id_(pending_page_id) {
initial.commit09911bf2008-07-26 23:55:29156 }
157
158 // Contains the page_id for this navigation or -1 if there is none yet.
159 int32 pending_page_id() const { return pending_page_id_; }
160
161 // Is this a new navigation?
162 bool is_new_navigation() const { return pending_page_id_ == -1; }
163
164 // Contains the transition type that the browser specified when it
165 // initiated the load.
166 PageTransition::Type transition_type;
[email protected]c20210e62009-04-03 21:39:26167 Time request_time;
initial.commit09911bf2008-07-26 23:55:29168
169 // True if we have already processed the "DidCommitLoad" event for this
170 // request. Used by session history.
171 bool request_committed;
172
173 private:
174 int32 pending_page_id_;
175
[email protected]4f3dc372009-02-24 00:10:29176 DISALLOW_COPY_AND_ASSIGN(RenderViewExtraRequestData);
initial.commit09911bf2008-07-26 23:55:29177};
178
179} // namespace
180
181///////////////////////////////////////////////////////////////////////////////
182
[email protected]81a34412009-01-05 19:17:24183RenderView::RenderView(RenderThreadBase* render_thread)
184 : RenderWidget(render_thread, true),
[email protected]81e63782009-02-27 19:35:09185 enabled_bindings_(0),
[email protected]e75cb49e2009-01-05 23:13:21186 target_url_status_(TARGET_NONE),
[email protected]81a34412009-01-05 19:17:24187 is_loading_(false),
[email protected]e75cb49e2009-01-05 23:13:21188 navigation_gesture_(NavigationGestureUnknown),
[email protected]81a34412009-01-05 19:17:24189 page_id_(-1),
190 last_page_id_sent_to_browser_(-1),
191 last_indexed_page_id_(-1),
[email protected]81a34412009-01-05 19:17:24192 opened_by_user_gesture_(true),
[email protected]bb063b72009-03-27 23:18:50193 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
[email protected]81a34412009-01-05 19:17:24194 first_default_plugin_(NULL),
[email protected]e4ac5df2009-03-17 15:33:11195 devtools_agent_(NULL),
196 devtools_client_(NULL),
[email protected]81a34412009-01-05 19:17:24197 history_back_list_count_(0),
198 history_forward_list_count_(0),
[email protected]81a34412009-01-05 19:17:24199 has_unload_listener_(false),
200 decrement_shared_popup_at_destruction_(false),
[email protected]81a34412009-01-05 19:17:24201 form_field_autofill_request_id_(0),
202 popup_notification_visible_(false),
203 delay_seconds_for_form_state_sync_(kDefaultDelaySecondsForFormStateSync) {
initial.commit09911bf2008-07-26 23:55:29204}
205
206RenderView::~RenderView() {
[email protected]0aa55312008-10-17 21:53:08207 if (decrement_shared_popup_at_destruction_)
208 shared_popup_counter_->data--;
209
initial.commit09911bf2008-07-26 23:55:29210 // Clear any back-pointers that might still be held by plugins.
211 PluginDelegateList::iterator it = plugin_delegates_.begin();
212 while (it != plugin_delegates_.end()) {
213 (*it)->DropRenderView();
214 it = plugin_delegates_.erase(it);
215 }
216
[email protected]81a34412009-01-05 19:17:24217 render_thread_->RemoveFilter(debug_message_handler_);
[email protected]5fb88962009-04-16 19:03:25218 render_thread_->RemoveFilter(audio_message_filter_);
initial.commit09911bf2008-07-26 23:55:29219}
220
221/*static*/
[email protected]0aa55312008-10-17 21:53:08222RenderView* RenderView::Create(
[email protected]81a34412009-01-05 19:17:24223 RenderThreadBase* render_thread,
[email protected]18bcc3c2009-01-27 21:39:15224 gfx::NativeViewId parent_hwnd,
[email protected]1c4947f2009-01-15 22:25:11225 base::WaitableEvent* modal_dialog_event,
[email protected]0aa55312008-10-17 21:53:08226 int32 opener_id,
227 const WebPreferences& webkit_prefs,
228 SharedRenderViewCounter* counter,
229 int32 routing_id) {
initial.commit09911bf2008-07-26 23:55:29230 DCHECK(routing_id != MSG_ROUTING_NONE);
[email protected]81a34412009-01-05 19:17:24231 scoped_refptr<RenderView> view = new RenderView(render_thread);
initial.commit09911bf2008-07-26 23:55:29232 view->Init(parent_hwnd,
233 modal_dialog_event,
234 opener_id,
235 webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08236 counter,
initial.commit09911bf2008-07-26 23:55:29237 routing_id); // adds reference
238 return view;
239}
240
241/*static*/
242void RenderView::SetNextPageID(int32 next_page_id) {
243 // This method should only be called during process startup, and the given
244 // page id had better not exceed our current next page id!
245 DCHECK(next_page_id_ == 1);
246 DCHECK(next_page_id >= next_page_id_);
247 next_page_id_ = next_page_id;
248}
249
250void RenderView::PluginDestroyed(WebPluginDelegateProxy* proxy) {
251 PluginDelegateList::iterator it =
252 std::find(plugin_delegates_.begin(), plugin_delegates_.end(), proxy);
253 DCHECK(it != plugin_delegates_.end());
254 plugin_delegates_.erase(it);
255 // If the plugin is deleted, we need to clear our reference in case user
256 // clicks the info bar to install. Unfortunately we are getting
257 // PluginDestroyed in single process mode. However, that is not a huge
258 // concern.
259 if (proxy == first_default_plugin_)
260 first_default_plugin_ = NULL;
261}
262
[email protected]690a99c2009-01-06 16:48:45263void RenderView::PluginCrashed(const FilePath& plugin_path) {
initial.commit09911bf2008-07-26 23:55:29264 Send(new ViewHostMsg_CrashedPlugin(routing_id_, plugin_path));
265}
266
267
268void RenderView::JSOutOfMemory() {
269 Send(new ViewHostMsg_JSOutOfMemory(routing_id_));
270}
271
[email protected]18bcc3c2009-01-27 21:39:15272void RenderView::Init(gfx::NativeViewId parent_hwnd,
[email protected]1c4947f2009-01-15 22:25:11273 base::WaitableEvent* modal_dialog_event,
initial.commit09911bf2008-07-26 23:55:29274 int32 opener_id,
275 const WebPreferences& webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08276 SharedRenderViewCounter* counter,
initial.commit09911bf2008-07-26 23:55:29277 int32 routing_id) {
278 DCHECK(!webview());
279
280 if (opener_id != MSG_ROUTING_NONE)
281 opener_id_ = opener_id;
282
[email protected]0aa55312008-10-17 21:53:08283 if (counter) {
284 shared_popup_counter_ = counter;
285 shared_popup_counter_->data++;
286 decrement_shared_popup_at_destruction_ = true;
287 } else {
288 shared_popup_counter_ = new SharedRenderViewCounter(0);
289 decrement_shared_popup_at_destruction_ = false;
290 }
291
[email protected]90ca3692009-04-09 16:09:43292 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
293
294 bool dev_tools_enabled = command_line.HasSwitch(
295 switches::kEnableOutOfProcessDevTools);
296 if (dev_tools_enabled)
297 devtools_agent_.reset(new DevToolsAgent(routing_id, this));
[email protected]9b9d7282009-04-08 14:13:04298
[email protected]c5b3b5e2009-02-13 06:41:11299 webwidget_ = WebView::Create(this, webkit_prefs);
initial.commit09911bf2008-07-26 23:55:29300
[email protected]2e417c82009-04-02 22:30:26301#if defined(OS_LINUX)
302 // We have to enable ourselves as the editor delegate on linux so we can copy
303 // text selections to the X clipboard.
304 webview()->SetUseEditorDelegate(true);
305#endif
306
initial.commit09911bf2008-07-26 23:55:29307 // Don't let WebCore keep a B/F list - we have our own.
308 // We let it keep 1 entry because FrameLoader::goToItem expects an item in the
309 // backForwardList, which is used only in ASSERTs.
310 webview()->SetBackForwardListSize(1);
311
312 routing_id_ = routing_id;
[email protected]81a34412009-01-05 19:17:24313 render_thread_->AddRoute(routing_id_, this);
initial.commit09911bf2008-07-26 23:55:29314 // Take a reference on behalf of the RenderThread. This will be balanced
315 // when we receive ViewMsg_Close.
316 AddRef();
317
318 // If this is a popup, we must wait for the CreatingNew_ACK message before
319 // completing initialization. Otherwise, we can finish it now.
320 if (opener_id == MSG_ROUTING_NONE) {
321 did_show_ = true;
322 CompleteInit(parent_hwnd);
323 }
324
325 host_window_ = parent_hwnd;
[email protected]1c4947f2009-01-15 22:25:11326 modal_dialog_event_.reset(modal_dialog_event);
initial.commit09911bf2008-07-26 23:55:29327
[email protected]81e63782009-02-27 19:35:09328 if (command_line.HasSwitch(switches::kDomAutomationController))
329 enabled_bindings_ |= BindingsPolicy::DOM_AUTOMATION;
initial.commit09911bf2008-07-26 23:55:29330
331 debug_message_handler_ = new DebugMessageHandler(this);
[email protected]81a34412009-01-05 19:17:24332 render_thread_->AddFilter(debug_message_handler_);
[email protected]5fb88962009-04-16 19:03:25333
334 audio_message_filter_ = new AudioMessageFilter(routing_id_);
335 render_thread_->AddFilter(audio_message_filter_);
initial.commit09911bf2008-07-26 23:55:29336}
337
338void RenderView::OnMessageReceived(const IPC::Message& message) {
[email protected]f8b6b6f2009-03-10 16:48:26339 WebFrame* main_frame = webview() ? webview()->GetMainFrame() : NULL;
340 renderer_logging::ScopedActiveRenderingURLSetter url_setter(
341 main_frame ? main_frame->GetURL() : GURL());
[email protected]f8b6b6f2009-03-10 16:48:26342
[email protected]b2abac72009-02-26 12:39:28343 // If this is developer tools renderer intercept tools messages first.
[email protected]e4ac5df2009-03-17 15:33:11344 if (devtools_client_.get() && devtools_client_->OnMessageReceived(message))
[email protected]b2abac72009-02-26 12:39:28345 return;
[email protected]b4b967e2009-04-22 11:33:05346 if (devtools_agent_.get() && devtools_agent_->OnMessageReceived(message))
347 return;
[email protected]b2abac72009-02-26 12:39:28348
initial.commit09911bf2008-07-26 23:55:29349 IPC_BEGIN_MESSAGE_MAP(RenderView, message)
initial.commit09911bf2008-07-26 23:55:29350 IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)
initial.commit09911bf2008-07-26 23:55:29351 IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)
352 IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
353 IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
354 IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText)
355 IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
356 IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)
357 IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)
358 IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)
359 IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)
360 IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)
361 IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)
[email protected]bbbd545c2008-12-15 20:18:04362 IPC_MESSAGE_HANDLER(ViewMsg_ToggleSpellCheck, OnToggleSpellCheck)
initial.commit09911bf2008-07-26 23:55:29363 IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)
364 IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)
365 IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
366 IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
[email protected]630e26b2008-10-14 22:55:17367 IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
[email protected]ea8c7452009-04-02 20:47:06368 IPC_MESSAGE_HANDLER(ViewMsg_InsertText, OnInsertText)
initial.commit09911bf2008-07-26 23:55:29369 IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
370 IPC_MESSAGE_HANDLER(ViewMsg_InspectElement, OnInspectElement)
371 IPC_MESSAGE_HANDLER(ViewMsg_ShowJavaScriptConsole, OnShowJavaScriptConsole)
[email protected]b2abac72009-02-26 12:39:28372 IPC_MESSAGE_HANDLER(ViewMsg_SetupDevToolsClient, OnSetupDevToolsClient)
initial.commit09911bf2008-07-26 23:55:29373 IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)
374 IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
[email protected]1810e132009-03-24 23:35:48375 IPC_MESSAGE_HANDLER(ViewMsg_CSSInsertRequest, OnCSSInsertRequest)
initial.commit09911bf2008-07-26 23:55:29376 IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)
377 IPC_MESSAGE_HANDLER(ViewMsg_DebugAttach, OnDebugAttach)
[email protected]88010e082008-08-29 11:07:40378 IPC_MESSAGE_HANDLER(ViewMsg_DebugDetach, OnDebugDetach)
initial.commit09911bf2008-07-26 23:55:29379 IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)
380 IPC_MESSAGE_HANDLER(ViewMsg_UploadFile, OnUploadFileRequest)
381 IPC_MESSAGE_HANDLER(ViewMsg_FormFill, OnFormFill)
382 IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)
383 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)
384 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)
385 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)
386 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)
[email protected]18cb2572008-08-21 20:34:45387 IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)
initial.commit09911bf2008-07-26 23:55:29388 IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)
[email protected]266eb6f2008-09-30 23:56:50389 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved,
390 OnDragSourceEndedOrMoved)
initial.commit09911bf2008-07-26 23:55:29391 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,
392 OnDragSourceSystemDragEnded)
393 IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)
394 IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)
395 IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)
396 IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
397 IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)
398 IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)
399 IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
400 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)
401 IPC_MESSAGE_HANDLER(ViewMsg_UpdateBackForwardListCount,
402 OnUpdateBackForwardListCount)
403 IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,
404 OnGetAllSavableResourceLinksForCurrentPage)
[email protected]f09c7182009-03-10 12:54:04405 IPC_MESSAGE_HANDLER(
406 ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,
407 OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)
initial.commit09911bf2008-07-26 23:55:29408 IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)
[email protected]266eb6f2008-09-30 23:56:50409 IPC_MESSAGE_HANDLER(ViewMsg_GetAccessibilityInfo, OnGetAccessibilityInfo)
410 IPC_MESSAGE_HANDLER(ViewMsg_ClearAccessibilityInfo,
411 OnClearAccessibilityInfo)
initial.commit09911bf2008-07-26 23:55:29412 IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose)
413 IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
414 IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)
[email protected]18cb2572008-08-21 20:34:45415 IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,
416 OnMessageFromExternalHost)
[email protected]0aa55312008-10-17 21:53:08417 IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
418 OnDisassociateFromPopupCount)
[email protected]0ebf3872008-11-07 21:35:03419 IPC_MESSAGE_HANDLER(ViewMsg_AutofillSuggestions,
420 OnReceivedAutofillSuggestions)
[email protected]634a6f92008-12-01 21:39:31421 IPC_MESSAGE_HANDLER(ViewMsg_PopupNotificationVisiblityChanged,
422 OnPopupNotificationVisiblityChanged)
[email protected]30f75e62009-02-25 22:01:00423 IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
[email protected]309d7a282009-03-24 09:18:27424 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionResponse, OnExtensionResponse)
[email protected]05d478752009-04-08 23:38:16425 IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
[email protected]699ab0d2009-04-23 23:19:14426 IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
[email protected]634a6f92008-12-01 21:39:31427
initial.commit09911bf2008-07-26 23:55:29428 // Have the super handle all other messages.
429 IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))
430 IPC_END_MESSAGE_MAP()
431}
432
initial.commit09911bf2008-07-26 23:55:29433void RenderView::SendThumbnail() {
434 WebFrame* main_frame = webview()->GetMainFrame();
435 if (!main_frame)
436 return;
437
438 // get the URL for this page
439 GURL url(main_frame->GetURL());
440 if (url.is_empty())
441 return;
442
443 if (size_.IsEmpty())
444 return; // Don't create an empty thumbnail!
445
446 ThumbnailScore score;
447 SkBitmap thumbnail;
[email protected]b6e4bec2008-11-12 01:17:15448 if (!CaptureThumbnail(main_frame, kThumbnailWidth, kThumbnailHeight,
449 &thumbnail, &score))
450 return;
451
initial.commit09911bf2008-07-26 23:55:29452 // send the thumbnail message to the browser process
[email protected]674741932009-02-04 23:44:46453 Send(new ViewHostMsg_Thumbnail(routing_id_, url, score, thumbnail));
initial.commit09911bf2008-07-26 23:55:29454}
455
initial.commit09911bf2008-07-26 23:55:29456void RenderView::PrintPage(const ViewMsg_PrintPage_Params& params,
[email protected]88a3ecc2009-03-19 17:36:22457 const gfx::Size& canvas_size,
initial.commit09911bf2008-07-26 23:55:29458 WebFrame* frame) {
[email protected]6c8afae52009-01-22 02:24:57459#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29460 // Generate a memory-based EMF file. The EMF will use the current screen's
461 // DPI.
462 gfx::Emf emf;
463
464 emf.CreateDc(NULL, NULL);
465 HDC hdc = emf.hdc();
466 DCHECK(hdc);
[email protected]21f527e2008-12-17 23:29:40467 skia::PlatformDeviceWin::InitializeDC(hdc);
[email protected]0e92fa32009-03-31 20:39:33468 // Since WebKit extends the page width depending on the magical shrink
[email protected]0dea3ea2009-03-31 23:30:59469 // factor we make sure the canvas covers the worst case scenario
[email protected]0e92fa32009-03-31 20:39:33470 // (x2.0 currently). PrintContext will then set the correct clipping region.
471 int size_x = static_cast<int>(canvas_size.width() * params.params.max_shrink);
472 int size_y = static_cast<int>(canvas_size.height() *
473 params.params.max_shrink);
[email protected]88a3ecc2009-03-19 17:36:22474 // Calculate the dpi adjustment.
475 float shrink = static_cast<float>(canvas_size.width()) /
476 params.params.printable_size.width();
initial.commit09911bf2008-07-26 23:55:29477#if 0
478 // TODO(maruel): This code is kept for testing until the 100% GDI drawing
479 // code is stable. maruels use this code's output as a reference when the
480 // GDI drawing code fails.
481
482 // Mix of Skia and GDI based.
[email protected]88a3ecc2009-03-19 17:36:22483 skia::PlatformCanvasWin canvas(size_x, size_y, true);
initial.commit09911bf2008-07-26 23:55:29484 canvas.drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode);
[email protected]88a3ecc2009-03-19 17:36:22485 float webkit_shrink = frame->PrintPage(params.page_number, &canvas);
486 if (shrink <= 0) {
initial.commit09911bf2008-07-26 23:55:29487 NOTREACHED() << "Printing page " << params.page_number << " failed.";
[email protected]88a3ecc2009-03-19 17:36:22488 } else {
489 // Update the dpi adjustment with the "page shrink" calculated in webkit.
490 shrink /= webkit_shrink;
initial.commit09911bf2008-07-26 23:55:29491 }
492
493 // Create a BMP v4 header that we can serialize.
494 BITMAPV4HEADER bitmap_header;
[email protected]88a3ecc2009-03-19 17:36:22495 gfx::CreateBitmapV4Header(size_x, size_y, &bitmap_header);
initial.commit09911bf2008-07-26 23:55:29496 const SkBitmap& src_bmp = canvas.getDevice()->accessBitmap(true);
497 SkAutoLockPixels src_lock(src_bmp);
498 int retval = StretchDIBits(hdc,
499 0,
500 0,
[email protected]88a3ecc2009-03-19 17:36:22501 size_x, size_y,
initial.commit09911bf2008-07-26 23:55:29502 0, 0,
[email protected]88a3ecc2009-03-19 17:36:22503 size_x, size_y,
initial.commit09911bf2008-07-26 23:55:29504 src_bmp.getPixels(),
505 reinterpret_cast<BITMAPINFO*>(&bitmap_header),
506 DIB_RGB_COLORS,
507 SRCCOPY);
508 DCHECK(retval != GDI_ERROR);
509#else
510 // 100% GDI based.
[email protected]88a3ecc2009-03-19 17:36:22511 skia::VectorCanvas canvas(hdc, size_x, size_y);
512 float webkit_shrink = frame->PrintPage(params.page_number, &canvas);
513 if (shrink <= 0) {
initial.commit09911bf2008-07-26 23:55:29514 NOTREACHED() << "Printing page " << params.page_number << " failed.";
[email protected]88a3ecc2009-03-19 17:36:22515 } else {
516 // Update the dpi adjustment with the "page shrink" calculated in webkit.
517 shrink /= webkit_shrink;
initial.commit09911bf2008-07-26 23:55:29518 }
519#endif
520
521 // Done printing. Close the device context to retrieve the compiled EMF.
522 if (!emf.CloseDc()) {
523 NOTREACHED() << "EMF failed";
524 }
525
526 // Get the size of the compiled EMF.
527 unsigned buf_size = emf.GetDataSize();
528 DCHECK(buf_size > 128);
529 ViewHostMsg_DidPrintPage_Params page_params;
530 page_params.data_size = 0;
531 page_params.emf_data_handle = NULL;
532 page_params.page_number = params.page_number;
533 page_params.document_cookie = params.params.document_cookie;
534 page_params.actual_shrink = shrink;
[email protected]176aa482008-11-14 03:25:15535 base::SharedMemory shared_buf;
initial.commit09911bf2008-07-26 23:55:29536
537 // http://msdn2.microsoft.com/en-us/library/ms535522.aspx
538 // Windows 2000/XP: When a page in a spooled file exceeds approximately 350
539 // MB, it can fail to print and not send an error message.
540 if (buf_size < 350*1024*1024) {
541 // Allocate a shared memory buffer to hold the generated EMF data.
542 if (shared_buf.Create(L"", false, false, buf_size) &&
543 shared_buf.Map(buf_size)) {
544 // Copy the bits into shared memory.
545 if (emf.GetData(shared_buf.memory(), buf_size)) {
546 page_params.emf_data_handle = shared_buf.handle();
547 page_params.data_size = buf_size;
548 } else {
549 NOTREACHED() << "GetData() failed";
550 }
551 shared_buf.Unmap();
552 } else {
553 NOTREACHED() << "Buffer allocation failed";
554 }
555 } else {
556 NOTREACHED() << "Buffer too large: " << buf_size;
557 }
558 emf.CloseEmf();
559 if (Send(new ViewHostMsg_DuplicateSection(routing_id_,
560 page_params.emf_data_handle,
561 &page_params.emf_data_handle))) {
562 Send(new ViewHostMsg_DidPrintPage(routing_id_, page_params));
563 }
[email protected]6c8afae52009-01-22 02:24:57564#else // defined(OS_WIN)
565 // TODO(port) implement printing
566 NOTIMPLEMENTED();
567#endif
initial.commit09911bf2008-07-26 23:55:29568}
569
[email protected]068637222009-01-29 16:58:07570void RenderView::OnPrintPages() {
initial.commit09911bf2008-07-26 23:55:29571 DCHECK(webview());
[email protected]068637222009-01-29 16:58:07572 if (webview()) {
573 // The renderer own the control flow as if it was a window.print() call.
574 ScriptedPrint(webview()->GetMainFrame());
initial.commit09911bf2008-07-26 23:55:29575 }
initial.commit09911bf2008-07-26 23:55:29576}
577
578void RenderView::PrintPages(const ViewMsg_PrintPages_Params& params,
579 WebFrame* frame) {
[email protected]88a3ecc2009-03-19 17:36:22580 int page_count = 0;
581 gfx::Size canvas_size;
582 canvas_size.set_width(
583 printing::ConvertUnit(params.params.printable_size.width(),
584 static_cast<int>(params.params.dpi),
585 params.params.desired_dpi));
586 canvas_size.set_height(
587 printing::ConvertUnit(params.params.printable_size.height(),
588 static_cast<int>(params.params.dpi),
589 params.params.desired_dpi));
590 frame->BeginPrint(canvas_size, &page_count);
initial.commit09911bf2008-07-26 23:55:29591 Send(new ViewHostMsg_DidGetPrintedPagesCount(routing_id_,
592 params.params.document_cookie,
[email protected]88a3ecc2009-03-19 17:36:22593 page_count));
594 if (page_count) {
initial.commit09911bf2008-07-26 23:55:29595 ViewMsg_PrintPage_Params page_params;
596 page_params.params = params.params;
597 if (params.pages.empty()) {
[email protected]88a3ecc2009-03-19 17:36:22598 for (int i = 0; i < page_count; ++i) {
initial.commit09911bf2008-07-26 23:55:29599 page_params.page_number = i;
[email protected]88a3ecc2009-03-19 17:36:22600 PrintPage(page_params, canvas_size, frame);
initial.commit09911bf2008-07-26 23:55:29601 }
602 } else {
603 for (size_t i = 0; i < params.pages.size(); ++i) {
604 page_params.page_number = params.pages[i];
[email protected]88a3ecc2009-03-19 17:36:22605 PrintPage(page_params, canvas_size, frame);
initial.commit09911bf2008-07-26 23:55:29606 }
607 }
608 }
[email protected]88a3ecc2009-03-19 17:36:22609 frame->EndPrint();
initial.commit09911bf2008-07-26 23:55:29610}
611
612void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) {
613 if (load_id != page_id_)
614 return; // this capture call is no longer relevant due to navigation
615 if (load_id == last_indexed_page_id_)
616 return; // we already indexed this page
617
618 if (!webview())
619 return;
620
621 WebFrame* main_frame = webview()->GetMainFrame();
622 if (!main_frame)
623 return;
624
625 // Don't index/capture pages that are in view source mode.
626 if (main_frame->GetInViewSourceMode())
627 return;
628
629 // Don't index/capture pages that failed to load. This only checks the top
630 // level frame so the thumbnail may contain a frame that failed to load.
631 WebDataSource* ds = main_frame->GetDataSource();
632 if (ds && ds->HasUnreachableURL())
633 return;
634
635 if (!preliminary_capture)
636 last_indexed_page_id_ = load_id;
637
638 // get the URL for this page
639 GURL url(main_frame->GetURL());
640 if (url.is_empty())
641 return;
642
643 // full text
644 std::wstring contents;
645 CaptureText(main_frame, &contents);
646 if (contents.size()) {
647 // Send the text to the browser for indexing.
648 Send(new ViewHostMsg_PageContents(url, load_id, contents));
649 }
650
651 // thumbnail
652 SendThumbnail();
653}
654
655void RenderView::CaptureText(WebFrame* frame, std::wstring* contents) {
656 contents->clear();
657 if (!frame)
658 return;
659
[email protected]0faf0bd92008-09-09 20:53:27660 // Don't index any https pages. People generally don't want their bank
661 // accounts, etc. indexed on their computer, especially since some of these
662 // things are not marked cachable.
663 // TODO(brettw) we may want to consider more elaborate heuristics such as
664 // the cachability of the page. We may also want to consider subframes (this
665 // test will still index subframes if the subframe is SSL).
666 if (frame->GetURL().SchemeIsSecure())
667 return;
668
initial.commit09911bf2008-07-26 23:55:29669#ifdef TIME_TEXT_RETRIEVAL
670 double begin = time_util::GetHighResolutionTimeNow();
671#endif
672
673 // get the contents of the frame
674 frame->GetContentAsPlainText(kMaxIndexChars, contents);
675
676#ifdef TIME_TEXT_RETRIEVAL
677 double end = time_util::GetHighResolutionTimeNow();
678 char buf[128];
679 sprintf_s(buf, "%d chars retrieved for indexing in %gms\n",
680 contents.size(), (end - begin)*1000);
681 OutputDebugStringA(buf);
682#endif
683
684 // When the contents are clipped to the maximum, we don't want to have a
685 // partial word indexed at the end that might have been clipped. Therefore,
686 // terminate the string at the last space to ensure no words are clipped.
687 if (contents->size() == kMaxIndexChars) {
688 size_t last_space_index = contents->find_last_of(kWhitespaceWide);
689 if (last_space_index == std::wstring::npos)
690 return; // don't index if we got a huge block of text with no spaces
691 contents->resize(last_space_index);
692 }
693}
694
[email protected]b6e4bec2008-11-12 01:17:15695bool RenderView::CaptureThumbnail(WebFrame* frame,
initial.commit09911bf2008-07-26 23:55:29696 int w,
697 int h,
698 SkBitmap* thumbnail,
699 ThumbnailScore* score) {
700#ifdef TIME_BITMAP_RETRIEVAL
701 double begin = time_util::GetHighResolutionTimeNow();
702#endif
703
[email protected]21f527e2008-12-17 23:29:40704 scoped_ptr<skia::BitmapPlatformDevice> device;
[email protected]b6e4bec2008-11-12 01:17:15705 if (!frame->CaptureImage(&device, true))
706 return false;
707
708 const SkBitmap& src_bmp = device->accessBitmap(false);
initial.commit09911bf2008-07-26 23:55:29709
710 SkRect dest_rect;
711 dest_rect.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
712 float dest_aspect = dest_rect.width() / dest_rect.height();
713
714 // Get the src rect so that we can preserve the aspect ratio while filling
715 // the destination.
716 SkIRect src_rect;
717 if (src_bmp.width() < dest_rect.width() ||
718 src_bmp.height() < dest_rect.height()) {
719 // Source image is smaller: we clip the part of source image within the
720 // dest rect, and then stretch it to fill the dest rect. We don't respect
721 // the aspect ratio in this case.
722 src_rect.set(0, 0, static_cast<S16CPU>(dest_rect.width()),
723 static_cast<S16CPU>(dest_rect.height()));
724 score->good_clipping = false;
725 } else {
726 float src_aspect = static_cast<float>(src_bmp.width()) / src_bmp.height();
727 if (src_aspect > dest_aspect) {
728 // Wider than tall, clip horizontally: we center the smaller thumbnail in
729 // the wider screen.
730 S16CPU new_width = static_cast<S16CPU>(src_bmp.height() * dest_aspect);
731 S16CPU x_offset = (src_bmp.width() - new_width) / 2;
732 src_rect.set(x_offset, 0, new_width + x_offset, src_bmp.height());
733 score->good_clipping = false;
734 } else {
735 src_rect.set(0, 0, src_bmp.width(),
736 static_cast<S16CPU>(src_bmp.width() / dest_aspect));
737 score->good_clipping = true;
738 }
739 }
740
[email protected]b3f2b912009-04-09 16:18:52741 score->at_top = (frame->ScrollOffset().height == 0);
initial.commit09911bf2008-07-26 23:55:29742
743 SkBitmap subset;
[email protected]b6e4bec2008-11-12 01:17:15744 device->accessBitmap(false).extractSubset(&subset, src_rect);
initial.commit09911bf2008-07-26 23:55:29745
746 // Resample the subset that we want to get it the right size.
[email protected]465b34b72008-12-12 20:19:14747 *thumbnail = skia::ImageOperations::Resize(
748 subset, skia::ImageOperations::RESIZE_LANCZOS3, w, h);
initial.commit09911bf2008-07-26 23:55:29749
750 score->boring_score = CalculateBoringScore(thumbnail);
751
752#ifdef TIME_BITMAP_RETRIEVAL
753 double end = time_util::GetHighResolutionTimeNow();
754 char buf[128];
755 sprintf_s(buf, "thumbnail in %gms\n", (end - begin) * 1000);
756 OutputDebugStringA(buf);
757#endif
[email protected]b6e4bec2008-11-12 01:17:15758 return true;
initial.commit09911bf2008-07-26 23:55:29759}
760
761double RenderView::CalculateBoringScore(SkBitmap* bitmap) {
762 int histogram[256] = {0};
763 color_utils::BuildLumaHistogram(bitmap, histogram);
764
765 int color_count = *std::max_element(histogram, histogram + 256);
766 int pixel_count = bitmap->width() * bitmap->height();
767 return static_cast<double>(color_count) / pixel_count;
768}
769
770void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {
771 if (!webview())
772 return;
773
[email protected]f8b6b6f2009-03-10 16:48:26774 renderer_logging::ScopedActiveRenderingURLSetter url_setter(params.url);
[email protected]f8b6b6f2009-03-10 16:48:26775
initial.commit09911bf2008-07-26 23:55:29776 AboutHandler::MaybeHandle(params.url);
777
778 bool is_reload = params.reload;
779
780 WebFrame* main_frame = webview()->GetMainFrame();
[email protected]606843fa2008-12-02 19:08:56781 if (is_reload && !main_frame->HasCurrentHistoryState()) {
initial.commit09911bf2008-07-26 23:55:29782 // We cannot reload if we do not have any history state. This happens, for
783 // example, when recovering from a crash. Our workaround here is a bit of
784 // a hack since it means that reload after a crashed tab does not cause an
785 // end-to-end cache validation.
786 is_reload = false;
787 }
788
789 WebRequestCachePolicy cache_policy;
790 if (is_reload) {
791 cache_policy = WebRequestReloadIgnoringCacheData;
792 } else if (params.page_id != -1 || main_frame->GetInViewSourceMode()) {
793 cache_policy = WebRequestReturnCacheDataElseLoad;
794 } else {
795 cache_policy = WebRequestUseProtocolCachePolicy;
796 }
797
798 scoped_ptr<WebRequest> request(WebRequest::Create(params.url));
799 request->SetCachePolicy(cache_policy);
800 request->SetExtraData(new RenderViewExtraRequestData(
[email protected]c20210e62009-04-03 21:39:26801 params.page_id, params.transition, params.request_time));
initial.commit09911bf2008-07-26 23:55:29802
803 // If we are reloading, then WebKit will use the state of the current page.
804 // Otherwise, we give it the state to navigate to.
805 if (!is_reload)
806 request->SetHistoryState(params.state);
807
[email protected]4c6f2c92008-10-28 20:26:15808 if (params.referrer.is_valid()) {
[email protected]8e3c1a72008-11-25 01:13:32809 request->SetHttpHeaderValue("Referer",
810 params.referrer.spec());
[email protected]c0588052008-10-27 23:01:50811 }
812
initial.commit09911bf2008-07-26 23:55:29813 main_frame->LoadRequest(request.get());
814}
815
816// Stop loading the current page
817void RenderView::OnStop() {
818 if (webview())
819 webview()->StopLoading();
820}
821
822void RenderView::OnLoadAlternateHTMLText(const std::string& html_contents,
823 bool new_navigation,
824 const GURL& display_url,
825 const std::string& security_info) {
826 if (!webview())
827 return;
828
829 scoped_ptr<WebRequest> request(WebRequest::Create(
830 GURL(kUnreachableWebDataURL)));
831 request->SetSecurityInfo(security_info);
832
833 webview()->GetMainFrame()->LoadAlternateHTMLString(request.get(),
834 html_contents,
835 display_url,
836 !new_navigation);
837}
838
839void RenderView::OnCopyImageAt(int x, int y) {
840 webview()->CopyImageAt(x, y);
841}
842
843void RenderView::OnInspectElement(int x, int y) {
844 webview()->InspectElement(x, y);
845}
846
847void RenderView::OnShowJavaScriptConsole() {
848 webview()->ShowJavaScriptConsole();
849}
850
[email protected]b2abac72009-02-26 12:39:28851void RenderView::OnSetupDevToolsClient() {
[email protected]e4ac5df2009-03-17 15:33:11852 DCHECK(!devtools_client_.get());
853 devtools_client_.reset(new DevToolsClient(this));
[email protected]b2abac72009-02-26 12:39:28854}
855
initial.commit09911bf2008-07-26 23:55:29856void RenderView::OnStopFinding(bool clear_selection) {
857 WebView* view = webview();
858 if (!view)
859 return;
860
861 if (clear_selection)
862 view->GetFocusedFrame()->ClearSelection();
863
864 WebFrame* frame = view->GetMainFrame();
865 while (frame) {
[email protected]65134c432008-09-26 21:47:20866 frame->StopFinding(clear_selection);
initial.commit09911bf2008-07-26 23:55:29867 frame = view->GetNextFrameAfter(frame, false);
868 }
869}
870
871void RenderView::OnFindReplyAck() {
872 // Check if there is any queued up request waiting to be sent.
873 if (queued_find_reply_message_.get()) {
874 // Send the search result over to the browser process.
875 Send(queued_find_reply_message_.get());
876 queued_find_reply_message_.release();
877 }
878}
879
880void RenderView::OnUpdateTargetURLAck() {
881 // Check if there is a targeturl waiting to be sent.
882 if (target_url_status_ == TARGET_PENDING) {
883 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_,
884 pending_target_url_));
885 }
886
887 target_url_status_ = TARGET_NONE;
888}
889
890void RenderView::OnUndo() {
891 if (!webview())
892 return;
893
894 webview()->GetFocusedFrame()->Undo();
895}
896
897void RenderView::OnRedo() {
898 if (!webview())
899 return;
900
901 webview()->GetFocusedFrame()->Redo();
902}
903
904void RenderView::OnCut() {
905 if (!webview())
906 return;
907
908 webview()->GetFocusedFrame()->Cut();
909}
910
911void RenderView::OnCopy() {
912 if (!webview())
913 return;
914
915 webview()->GetFocusedFrame()->Copy();
916}
917
918void RenderView::OnPaste() {
919 if (!webview())
920 return;
921
922 webview()->GetFocusedFrame()->Paste();
923}
924
925void RenderView::OnReplace(const std::wstring& text) {
926 if (!webview())
927 return;
928
929 webview()->GetFocusedFrame()->Replace(text);
930}
931
[email protected]bbbd545c2008-12-15 20:18:04932void RenderView::OnToggleSpellCheck() {
933 if (!webview())
934 return;
935
936 webview()->GetFocusedFrame()->ToggleSpellCheck();
937}
938
initial.commit09911bf2008-07-26 23:55:29939void RenderView::OnDelete() {
940 if (!webview())
941 return;
942
943 webview()->GetFocusedFrame()->Delete();
944}
945
946void RenderView::OnSelectAll() {
947 if (!webview())
948 return;
949
950 webview()->GetFocusedFrame()->SelectAll();
951}
952
953void RenderView::OnSetInitialFocus(bool reverse) {
954 if (!webview())
955 return;
956 webview()->SetInitialFocus(reverse);
957}
958
959///////////////////////////////////////////////////////////////////////////////
960
961// Tell the embedding application that the URL of the active page has changed
962void RenderView::UpdateURL(WebFrame* frame) {
963 WebDataSource* ds = frame->GetDataSource();
964 DCHECK(ds);
965
966 const WebRequest& request = ds->GetRequest();
967 const WebRequest& initial_request = ds->GetInitialRequest();
968 const WebResponse& response = ds->GetResponse();
969
970 // We don't hold a reference to the extra data. The request's reference will
971 // be sufficient because we won't modify it during our call. MAY BE NULL.
972 RenderViewExtraRequestData* extra_data =
973 static_cast<RenderViewExtraRequestData*>(request.GetExtraData());
974
975 ViewHostMsg_FrameNavigate_Params params;
[email protected]2e39d2e2009-02-19 18:41:31976 params.http_status_code = response.GetHttpStatusCode();
initial.commit09911bf2008-07-26 23:55:29977 params.is_post = false;
978 params.page_id = page_id_;
[email protected]8a3422c92008-09-24 17:42:42979 params.is_content_filtered = response.IsContentFiltered();
initial.commit09911bf2008-07-26 23:55:29980 if (!request.GetSecurityInfo().empty()) {
981 // SSL state specified in the request takes precedence over the one in the
982 // response.
983 // So far this is only intended for error pages that are not expected to be
984 // over ssl, so we should not get any clash.
985 DCHECK(response.GetSecurityInfo().empty());
986 params.security_info = request.GetSecurityInfo();
987 } else {
988 params.security_info = response.GetSecurityInfo();
989 }
990
991 // Set the URL to be displayed in the browser UI to the user.
992 if (ds->HasUnreachableURL()) {
993 params.url = ds->GetUnreachableURL();
994 } else {
995 params.url = request.GetURL();
996 }
997
998 params.redirects = ds->GetRedirectChain();
999 params.should_update_history = !ds->HasUnreachableURL();
1000
1001 const SearchableFormData* searchable_form_data =
1002 frame->GetDataSource()->GetSearchableFormData();
1003 if (searchable_form_data) {
1004 params.searchable_form_url = searchable_form_data->url();
1005 params.searchable_form_element_name = searchable_form_data->element_name();
1006 params.searchable_form_encoding = searchable_form_data->encoding();
1007 }
1008
1009 const PasswordForm* password_form_data =
1010 frame->GetDataSource()->GetPasswordFormData();
1011 if (password_form_data)
1012 params.password_form = *password_form_data;
1013
1014 params.gesture = navigation_gesture_;
1015 navigation_gesture_ = NavigationGestureUnknown;
1016
1017 if (webview()->GetMainFrame() == frame) {
1018 // Top-level navigation.
1019
1020 // Update contents MIME type for main frame.
[email protected]9d806f52009-03-12 22:50:541021 params.contents_mime_type = ds->GetResponse().GetMimeType();
initial.commit09911bf2008-07-26 23:55:291022
1023 // We assume top level navigations initiated by the renderer are link
1024 // clicks.
1025 params.transition = extra_data ?
1026 extra_data->transition_type : PageTransition::LINK;
1027 if (!PageTransition::IsMainFrame(params.transition)) {
1028 // If the main frame does a load, it should not be reported as a subframe
1029 // navigation. This can occur in the following case:
1030 // 1. You're on a site with frames.
1031 // 2. You do a subframe navigation. This is stored with transition type
1032 // MANUAL_SUBFRAME.
1033 // 3. You navigate to some non-frame site, say, google.com.
1034 // 4. You navigate back to the page from step 2. Since it was initially
1035 // MANUAL_SUBFRAME, it will be that same transition type here.
1036 // We don't want that, because any navigation that changes the toplevel
1037 // frame should be tracked as a toplevel navigation (this allows us to
1038 // update the URL bar, etc).
1039 params.transition = PageTransition::LINK;
1040 }
1041
1042 if (params.transition == PageTransition::LINK &&
1043 frame->GetDataSource()->IsFormSubmit()) {
1044 params.transition = PageTransition::FORM_SUBMIT;
1045 }
1046
1047 // If we have a valid consumed client redirect source,
1048 // the page contained a client redirect (meta refresh, document.loc...),
1049 // so we set the referrer and transition to match.
1050 if (completed_client_redirect_src_.is_valid()) {
[email protected]77e09a92008-08-01 18:11:041051 DCHECK(completed_client_redirect_src_ == params.redirects[0]);
initial.commit09911bf2008-07-26 23:55:291052 params.referrer = completed_client_redirect_src_;
1053 params.transition = static_cast<PageTransition::Type>(
1054 params.transition | PageTransition::CLIENT_REDIRECT);
1055 } else {
1056 // Bug 654101: the referrer will be empty on https->http transitions. It
1057 // would be nice if we could get the real referrer from somewhere.
1058 params.referrer = GURL(initial_request.GetHttpReferrer());
1059 }
1060
[email protected]8e3c1a72008-11-25 01:13:321061 std::string method = request.GetHttpMethod();
1062 if (method == "POST")
initial.commit09911bf2008-07-26 23:55:291063 params.is_post = true;
1064
1065 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
1066 } else {
1067 // Subframe navigation: the type depends on whether this navigation
1068 // generated a new session history entry. When they do generate a session
1069 // history entry, it means the user initiated the navigation and we should
1070 // mark it as such. This test checks if this is the first time UpdateURL
1071 // has been called since WillNavigateToURL was called to initiate the load.
1072 if (page_id_ > last_page_id_sent_to_browser_)
1073 params.transition = PageTransition::MANUAL_SUBFRAME;
1074 else
1075 params.transition = PageTransition::AUTO_SUBFRAME;
1076
1077 // The browser should never initiate a subframe navigation.
1078 DCHECK(!extra_data);
1079 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
1080 }
1081
1082 last_page_id_sent_to_browser_ =
1083 std::max(last_page_id_sent_to_browser_, page_id_);
1084
1085 // If we end up reusing this WebRequest (for example, due to a #ref click),
1086 // we don't want the transition type to persist.
1087 if (extra_data)
1088 extra_data->transition_type = PageTransition::LINK; // Just clear it.
[email protected]266eb6f2008-09-30 23:56:501089
[email protected]6c8afae52009-01-22 02:24:571090#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:251091 if (web_accessibility_manager_.get()) {
[email protected]be645db2009-02-06 20:36:331092 // Clear accessibility info cache.
[email protected]6a983b42009-03-20 20:12:251093 web_accessibility_manager_->ClearAccObjMap(-1, true);
[email protected]266eb6f2008-09-30 23:56:501094 }
[email protected]6c8afae52009-01-22 02:24:571095#else
[email protected]7d926f92009-03-03 14:26:541096 // TODO(port): accessibility not yet implemented. See http://crbug.com/8288.
[email protected]6c8afae52009-01-22 02:24:571097#endif
initial.commit09911bf2008-07-26 23:55:291098}
1099
1100// Tell the embedding application that the title of the active page has changed
1101void RenderView::UpdateTitle(WebFrame* frame, const std::wstring& title) {
1102 // Ignore all but top level navigations...
1103 if (webview()->GetMainFrame() == frame)
1104 Send(new ViewHostMsg_UpdateTitle(routing_id_, page_id_, title));
1105}
1106
1107void RenderView::UpdateEncoding(WebFrame* frame,
[email protected]e38f40152008-09-12 23:08:301108 const std::wstring& encoding_name) {
initial.commit09911bf2008-07-26 23:55:291109 // Only update main frame's encoding_name.
1110 if (webview()->GetMainFrame() == frame &&
1111 last_encoding_name_ != encoding_name) {
[email protected]e38f40152008-09-12 23:08:301112 // Save the encoding name for later comparing.
initial.commit09911bf2008-07-26 23:55:291113 last_encoding_name_ = encoding_name;
1114
[email protected]e38f40152008-09-12 23:08:301115 Send(new ViewHostMsg_UpdateEncoding(routing_id_, last_encoding_name_));
initial.commit09911bf2008-07-26 23:55:291116 }
1117}
1118
[email protected]f4d34b52008-11-24 23:05:011119// Sends the previous session history state to the browser so it will be saved
1120// before we navigate to a new page. This must be called *before* the page ID
1121// has been updated so we know what it was.
initial.commit09911bf2008-07-26 23:55:291122void RenderView::UpdateSessionHistory(WebFrame* frame) {
1123 // If we have a valid page ID at this point, then it corresponds to the page
1124 // we are navigating away from. Otherwise, this is the first navigation, so
1125 // there is no past session history to record.
1126 if (page_id_ == -1)
1127 return;
1128
initial.commit09911bf2008-07-26 23:55:291129 std::string state;
[email protected]606843fa2008-12-02 19:08:561130 if (!webview()->GetMainFrame()->GetPreviousHistoryState(&state))
initial.commit09911bf2008-07-26 23:55:291131 return;
[email protected]606843fa2008-12-02 19:08:561132 Send(new ViewHostMsg_UpdateState(routing_id_, page_id_, state));
initial.commit09911bf2008-07-26 23:55:291133}
1134
1135///////////////////////////////////////////////////////////////////////////////
1136// WebViewDelegate
1137
1138void RenderView::DidStartLoading(WebView* webview) {
1139 if (is_loading_) {
1140 DLOG(WARNING) << "DidStartLoading called while loading";
1141 return;
1142 }
1143
1144 is_loading_ = true;
1145 // Clear the pointer so that we can assign it only when there is an unknown
1146 // plugin on a page.
1147 first_default_plugin_ = NULL;
1148
[email protected]329581b2009-04-28 06:52:351149 Send(new ViewHostMsg_DidStartLoading(routing_id_));
initial.commit09911bf2008-07-26 23:55:291150}
1151
1152void RenderView::DidStopLoading(WebView* webview) {
1153 if (!is_loading_) {
1154 DLOG(WARNING) << "DidStopLoading called while not loading";
1155 return;
1156 }
1157
1158 is_loading_ = false;
1159
1160 // NOTE: For now we're doing the safest thing, and sending out notification
1161 // when done loading. This currently isn't an issue as the favicon is only
1162 // displayed when done loading. Ideally we would send notification when
1163 // finished parsing the head, but webkit doesn't support that yet.
1164 // The feed discovery code would also benefit from access to the head.
1165 GURL favicon_url(webview->GetMainFrame()->GetFavIconURL());
1166 if (!favicon_url.is_empty())
1167 Send(new ViewHostMsg_UpdateFavIconURL(routing_id_, page_id_, favicon_url));
1168
1169 AddGURLSearchProvider(webview->GetMainFrame()->GetOSDDURL(),
1170 true); // autodetected
1171
[email protected]329581b2009-04-28 06:52:351172 Send(new ViewHostMsg_DidStopLoading(routing_id_));
initial.commit09911bf2008-07-26 23:55:291173
1174 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1175 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo, page_id_,
1176 false),
1177 kDelayForCaptureMs);
1178
1179 // The page is loaded. Try to process the file we need to upload if any.
1180 ProcessPendingUpload();
1181
1182 // Since the page is done loading, we are sure we don't need to try
1183 // again.
1184 ResetPendingUpload();
1185}
1186
1187void RenderView::DidStartProvisionalLoadForFrame(
1188 WebView* webview,
1189 WebFrame* frame,
1190 NavigationGesture gesture) {
[email protected]77e09a92008-08-01 18:11:041191 if (webview->GetMainFrame() == frame) {
initial.commit09911bf2008-07-26 23:55:291192 navigation_gesture_ = gesture;
[email protected]266eb6f2008-09-30 23:56:501193
[email protected]77e09a92008-08-01 18:11:041194 // Make sure redirect tracking state is clear for the new load.
1195 completed_client_redirect_src_ = GURL();
1196 }
initial.commit09911bf2008-07-26 23:55:291197
[email protected]c20210e62009-04-03 21:39:261198 WebDataSource* ds = frame->GetProvisionalDataSource();
1199 if (ds) {
1200 const WebRequest& req = ds->GetRequest();
1201 RenderViewExtraRequestData* extra_data =
1202 static_cast<RenderViewExtraRequestData*>(req.GetExtraData());
1203 if (extra_data) {
1204 ds->SetRequestTime(extra_data->request_time);
1205 }
1206 }
initial.commit09911bf2008-07-26 23:55:291207 Send(new ViewHostMsg_DidStartProvisionalLoadForFrame(
1208 routing_id_, webview->GetMainFrame() == frame,
1209 frame->GetProvisionalDataSource()->GetRequest().GetURL()));
1210}
1211
1212bool RenderView::DidLoadResourceFromMemoryCache(WebView* webview,
1213 const WebRequest& request,
1214 const WebResponse& response,
1215 WebFrame* frame) {
1216 // Let the browser know we loaded a resource from the memory cache. This
1217 // message is needed to display the correct SSL indicators.
1218 Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(routing_id_,
[email protected]ffc45862009-03-17 06:11:081219 request.GetURL(), frame->GetSecurityOrigin(),
1220 frame->GetTop()->GetSecurityOrigin(),
1221 response.GetSecurityInfo()));
initial.commit09911bf2008-07-26 23:55:291222
1223 return false;
1224}
1225
1226void RenderView::DidReceiveProvisionalLoadServerRedirect(WebView* webview,
1227 WebFrame* frame) {
1228 if (frame == webview->GetMainFrame()) {
1229 // Received a redirect on the main frame.
1230 WebDataSource* data_source =
1231 webview->GetMainFrame()->GetProvisionalDataSource();
1232 if (!data_source) {
1233 // Should only be invoked when we have a data source.
1234 NOTREACHED();
1235 return;
1236 }
1237 const std::vector<GURL>& redirects = data_source->GetRedirectChain();
1238 if (redirects.size() >= 2) {
1239 Send(new ViewHostMsg_DidRedirectProvisionalLoad(
1240 routing_id_, page_id_, redirects[redirects.size() - 2],
1241 redirects[redirects.size() - 1]));
1242 }
1243 }
1244}
1245
1246void RenderView::DidFailProvisionalLoadWithError(WebView* webview,
1247 const WebError& error,
1248 WebFrame* frame) {
1249 // Notify the browser that we failed a provisional load with an error.
1250 //
1251 // Note: It is important this notification occur before DidStopLoading so the
1252 // SSL manager can react to the provisional load failure before being
1253 // notified the load stopped.
1254 //
1255 WebDataSource* ds = frame->GetProvisionalDataSource();
1256 DCHECK(ds);
1257
1258 const WebRequest& failed_request = ds->GetRequest();
1259
1260 bool show_repost_interstitial =
1261 (error.GetErrorCode() == net::ERR_CACHE_MISS &&
1262 LowerCaseEqualsASCII(failed_request.GetHttpMethod(), "post"));
1263 Send(new ViewHostMsg_DidFailProvisionalLoadWithError(
1264 routing_id_, frame == webview->GetMainFrame(),
1265 error.GetErrorCode(), error.GetFailedURL(),
1266 show_repost_interstitial));
1267
initial.commit09911bf2008-07-26 23:55:291268 // Don't display an error page if this is simply a cancelled load. Aside
1269 // from being dumb, WebCore doesn't expect it and it will cause a crash.
1270 if (error.GetErrorCode() == net::ERR_ABORTED)
1271 return;
1272
1273 // If this is a failed back/forward/reload navigation, then we need to do a
1274 // 'replace' load. This is necessary to avoid messing up session history.
1275 // Otherwise, we do a normal load, which simulates a 'go' navigation as far
1276 // as session history is concerned.
1277 RenderViewExtraRequestData* extra_data =
1278 static_cast<RenderViewExtraRequestData*>(failed_request.GetExtraData());
1279 bool replace = extra_data && !extra_data->is_new_navigation();
1280
[email protected]5df266ac2008-10-15 19:50:131281 // Use the alternate error page service if this is a DNS failure or
1282 // connection failure. ERR_CONNECTION_FAILED can be dropped once we no longer
1283 // use winhttp.
1284 int ec = error.GetErrorCode();
1285 if (ec == net::ERR_NAME_NOT_RESOLVED ||
1286 ec == net::ERR_CONNECTION_FAILED ||
1287 ec == net::ERR_CONNECTION_REFUSED ||
1288 ec == net::ERR_ADDRESS_UNREACHABLE ||
1289 ec == net::ERR_TIMED_OUT) {
1290 const GURL& failed_url = error.GetFailedURL();
1291 const GURL& error_page_url = GetAlternateErrorPageURL(failed_url,
1292 ec == net::ERR_NAME_NOT_RESOLVED ? WebViewDelegate::DNS_ERROR
1293 : WebViewDelegate::CONNECTION_ERROR);
1294 if (error_page_url.is_valid()) {
1295 // Ask the WebFrame to fetch the alternate error page for us.
1296 frame->LoadAlternateHTMLErrorPage(&failed_request, error, error_page_url,
1297 replace, GURL(kUnreachableWebDataURL));
1298 return;
1299 }
initial.commit09911bf2008-07-26 23:55:291300 }
[email protected]5df266ac2008-10-15 19:50:131301
[email protected]be645db2009-02-06 20:36:331302 // Fallback to a local error page.
[email protected]5df266ac2008-10-15 19:50:131303 LoadNavigationErrorPage(frame, &failed_request, error, std::string(),
1304 replace);
initial.commit09911bf2008-07-26 23:55:291305}
1306
1307void RenderView::LoadNavigationErrorPage(WebFrame* frame,
1308 const WebRequest* failed_request,
1309 const WebError& error,
1310 const std::string& html,
1311 bool replace) {
1312 const GURL& failed_url = error.GetFailedURL();
1313
1314 std::string alt_html;
1315 if (html.empty()) {
1316 // Use a local error page.
1317 int resource_id;
1318 DictionaryValue error_strings;
1319 if (error.GetErrorCode() == net::ERR_CACHE_MISS &&
1320 LowerCaseEqualsASCII(failed_request->GetHttpMethod(), "post")) {
1321 GetFormRepostErrorValues(failed_url, &error_strings);
1322 resource_id = IDR_ERROR_NO_DETAILS_HTML;
1323 } else {
1324 GetLocalizedErrorValues(error, &error_strings);
1325 resource_id = IDR_NET_ERROR_HTML;
1326 }
[email protected]8e50b602009-03-03 22:59:431327 error_strings.SetString(L"textdirection",
1328 (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) ?
1329 L"rtl" : L"ltr");
initial.commit09911bf2008-07-26 23:55:291330
1331 alt_html = GetAltHTMLForTemplate(error_strings, resource_id);
1332 } else {
1333 alt_html = html;
1334 }
1335
1336 // Use a data: URL as the site URL to prevent against XSS attacks.
1337 scoped_ptr<WebRequest> request(failed_request->Clone());
1338 request->SetURL(GURL(kUnreachableWebDataURL));
1339
1340 frame->LoadAlternateHTMLString(request.get(), alt_html, failed_url,
1341 replace);
1342}
1343
1344void RenderView::DidCommitLoadForFrame(WebView *webview, WebFrame* frame,
1345 bool is_new_navigation) {
1346 const WebRequest& request =
1347 webview->GetMainFrame()->GetDataSource()->GetRequest();
1348 RenderViewExtraRequestData* extra_data =
1349 static_cast<RenderViewExtraRequestData*>(request.GetExtraData());
1350
1351 if (is_new_navigation) {
1352 // When we perform a new navigation, we need to update the previous session
1353 // history entry with state for the page we are leaving.
1354 UpdateSessionHistory(frame);
1355
1356 // We bump our Page ID to correspond with the new session history entry.
1357 page_id_ = next_page_id_++;
1358
1359 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1360 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo,
1361 page_id_, true),
1362 kDelayForForcedCaptureMs);
1363 } else {
1364 // Inspect the extra_data on the main frame (set in our Navigate method) to
1365 // see if the navigation corresponds to a session history navigation...
1366 // Note: |frame| may or may not be the toplevel frame, but for the case
1367 // of capturing session history, the first committed frame suffices. We
1368 // keep track of whether we've seen this commit before so that only capture
1369 // session history once per navigation.
[email protected]f4d34b52008-11-24 23:05:011370 //
1371 // Note that we need to check if the page ID changed. In the case of a
1372 // reload, the page ID doesn't change, and UpdateSessionHistory gets the
1373 // previous URL and the current page ID, which would be wrong.
initial.commit09911bf2008-07-26 23:55:291374 if (extra_data && !extra_data->is_new_navigation() &&
[email protected]f4d34b52008-11-24 23:05:011375 !extra_data->request_committed &&
1376 page_id_ != extra_data->pending_page_id()) {
initial.commit09911bf2008-07-26 23:55:291377 // This is a successful session history navigation!
1378 UpdateSessionHistory(frame);
initial.commit09911bf2008-07-26 23:55:291379 page_id_ = extra_data->pending_page_id();
1380 }
1381 }
1382
1383 // Remember that we've already processed this request, so we don't update
1384 // the session history again. We do this regardless of whether this is
1385 // a session history navigation, because if we attempted a session history
1386 // navigation without valid HistoryItem state, WebCore will think it is a
1387 // new navigation.
1388 if (extra_data)
1389 extra_data->request_committed = true;
1390
1391 UpdateURL(frame);
1392
1393 // If this committed load was initiated by a client redirect, we're
1394 // at the last stop now, so clear it.
1395 completed_client_redirect_src_ = GURL();
1396
1397 // Check whether we have new encoding name.
1398 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
1399}
1400
1401void RenderView::DidReceiveTitle(WebView* webview,
1402 const std::wstring& title,
1403 WebFrame* frame) {
1404 UpdateTitle(frame, title);
1405
1406 // Also check whether we have new encoding name.
1407 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
1408}
1409
1410void RenderView::DidFinishLoadForFrame(WebView* webview, WebFrame* frame) {
[email protected]c20210e62009-04-03 21:39:261411 if (webview->GetMainFrame() == frame) {
1412 const GURL& url = frame->GetURL();
1413 if (url.SchemeIs("http") || url.SchemeIs("https"))
1414 DumpLoadHistograms();
1415 }
initial.commit09911bf2008-07-26 23:55:291416}
1417
1418void RenderView::DidFailLoadWithError(WebView* webview,
1419 const WebError& error,
1420 WebFrame* frame) {
1421}
1422
1423void RenderView::DidFinishDocumentLoadForFrame(WebView* webview,
1424 WebFrame* frame) {
1425 // Check whether we have new encoding name.
1426 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
[email protected]1e0f70402008-10-16 23:57:471427
[email protected]8930d472009-02-21 08:05:281428 if (RenderThread::current()) // Will be NULL during unit tests.
1429 RenderThread::current()->user_script_slave()->InjectScripts(
[email protected]0afe8272009-02-14 04:15:161430 frame, UserScript::DOCUMENT_END);
initial.commit09911bf2008-07-26 23:55:291431}
1432
1433void RenderView::DidHandleOnloadEventsForFrame(WebView* webview,
1434 WebFrame* frame) {
1435}
1436
1437void RenderView::DidChangeLocationWithinPageForFrame(WebView* webview,
1438 WebFrame* frame,
1439 bool is_new_navigation) {
1440 DidCommitLoadForFrame(webview, frame, is_new_navigation);
[email protected]9d806f52009-03-12 22:50:541441 const string16& title =
[email protected]de56f3782008-10-01 22:31:351442 webview->GetMainFrame()->GetDataSource()->GetPageTitle();
[email protected]9d806f52009-03-12 22:50:541443 UpdateTitle(frame, UTF16ToWideHack(title));
initial.commit09911bf2008-07-26 23:55:291444}
1445
1446void RenderView::DidReceiveIconForFrame(WebView* webview,
1447 WebFrame* frame) {
1448}
1449
1450void RenderView::WillPerformClientRedirect(WebView* webview,
1451 WebFrame* frame,
1452 const GURL& src_url,
1453 const GURL& dest_url,
1454 unsigned int delay_seconds,
1455 unsigned int fire_date) {
1456}
1457
1458void RenderView::DidCancelClientRedirect(WebView* webview,
1459 WebFrame* frame) {
1460}
1461
[email protected]309d7a282009-03-24 09:18:271462void RenderView::WillCloseFrame(WebView* view, WebFrame* frame) {
1463 // Remove all the pending extension callbacks for this frame.
1464 if (pending_extension_callbacks_.IsEmpty())
1465 return;
1466
1467 std::vector<int> orphaned_callbacks;
1468 for (IDMap<WebFrame>::const_iterator iter =
1469 pending_extension_callbacks_.begin();
1470 iter != pending_extension_callbacks_.end(); ++iter) {
1471 if (iter->second == frame)
1472 orphaned_callbacks.push_back(iter->first);
1473 }
1474
1475 for (std::vector<int>::const_iterator iter = orphaned_callbacks.begin();
1476 iter != orphaned_callbacks.end(); ++iter) {
1477 pending_extension_callbacks_.Remove(*iter);
1478 }
1479}
1480
initial.commit09911bf2008-07-26 23:55:291481void RenderView::DidCompleteClientRedirect(WebView* webview,
1482 WebFrame* frame,
1483 const GURL& source) {
1484 if (webview->GetMainFrame() == frame)
1485 completed_client_redirect_src_ = source;
1486}
1487
[email protected]5b35a6b2009-03-16 19:58:081488void RenderView::WillSendRequest(WebView* webview,
1489 uint32 identifier,
1490 WebRequest* request) {
1491 request->SetRequestorID(routing_id_);
1492}
1493
initial.commit09911bf2008-07-26 23:55:291494void RenderView::BindDOMAutomationController(WebFrame* webframe) {
1495 dom_automation_controller_.set_message_sender(this);
1496 dom_automation_controller_.set_routing_id(routing_id_);
1497 dom_automation_controller_.BindToJavascript(webframe,
1498 L"domAutomationController");
1499}
1500
1501void RenderView::WindowObjectCleared(WebFrame* webframe) {
[email protected]81e63782009-02-27 19:35:091502 if (BindingsPolicy::is_dom_automation_enabled(enabled_bindings_))
initial.commit09911bf2008-07-26 23:55:291503 BindDOMAutomationController(webframe);
[email protected]81e63782009-02-27 19:35:091504 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_)) {
initial.commit09911bf2008-07-26 23:55:291505 dom_ui_bindings_.set_message_sender(this);
1506 dom_ui_bindings_.set_routing_id(routing_id_);
1507 dom_ui_bindings_.BindToJavascript(webframe, L"chrome");
1508 }
[email protected]81e63782009-02-27 19:35:091509 if (BindingsPolicy::is_external_host_enabled(enabled_bindings_)) {
[email protected]18cb2572008-08-21 20:34:451510 external_host_bindings_.set_message_sender(this);
1511 external_host_bindings_.set_routing_id(routing_id_);
1512 external_host_bindings_.BindToJavascript(webframe, L"externalHost");
1513 }
initial.commit09911bf2008-07-26 23:55:291514}
1515
[email protected]0afe8272009-02-14 04:15:161516void RenderView::DocumentElementAvailable(WebFrame* frame) {
[email protected]4b8323b2009-04-17 18:45:441517 // TODO(mpcomplete): remove this before Chrome extensions ship.
1518 // HACK. This is a temporary workaround to allow cross-origin XHR for Chrome
1519 // extensions. It grants full access to every origin, when we really want
1520 // to be able to restrict them more specifically.
[email protected]d959ce22009-04-15 21:03:421521 if (frame->GetURL().SchemeIs(chrome::kExtensionScheme))
[email protected]4b8323b2009-04-17 18:45:441522 frame->GrantUniversalAccess();
[email protected]d959ce22009-04-15 21:03:421523
[email protected]8930d472009-02-21 08:05:281524 if (RenderThread::current()) // Will be NULL during unit tests.
1525 RenderThread::current()->user_script_slave()->InjectScripts(
[email protected]0afe8272009-02-14 04:15:161526 frame, UserScript::DOCUMENT_START);
1527}
1528
initial.commit09911bf2008-07-26 23:55:291529WindowOpenDisposition RenderView::DispositionForNavigationAction(
1530 WebView* webview,
1531 WebFrame* frame,
1532 const WebRequest* request,
1533 WebNavigationType type,
1534 WindowOpenDisposition disposition,
1535 bool is_redirect) {
1536 // Webkit is asking whether to navigate to a new URL.
1537 // This is fine normally, except if we're showing UI from one security
1538 // context and they're trying to navigate to a different context.
1539 const GURL& url = request->GetURL();
1540 // We only care about navigations that are within the current tab (as opposed
1541 // to, for example, opening a new window).
1542 // But we sometimes navigate to about:blank to clear a tab, and we want to
1543 // still allow that.
[email protected]6de74452009-02-25 18:04:591544 if (disposition == CURRENT_TAB && !(url.SchemeIs(chrome::kAboutScheme))) {
initial.commit09911bf2008-07-26 23:55:291545 // GetExtraData is NULL when we did not issue the request ourselves (see
1546 // OnNavigate), and so such a request may correspond to a link-click,
1547 // script, or drag-n-drop initiated navigation.
1548 if (frame == webview->GetMainFrame() && !request->GetExtraData()) {
1549 // When we received such unsolicited navigations, we sometimes want to
1550 // punt them up to the browser to handle.
[email protected]81e63782009-02-27 19:35:091551 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_) ||
initial.commit09911bf2008-07-26 23:55:291552 frame->GetInViewSourceMode() ||
[email protected]6de74452009-02-25 18:04:591553 url.SchemeIs(chrome::kViewSourceScheme)) {
[email protected]c0588052008-10-27 23:01:501554 OpenURL(webview, url, GURL(), disposition);
initial.commit09911bf2008-07-26 23:55:291555 return IGNORE_ACTION; // Suppress the load here.
[email protected]81cf6f72009-05-04 22:18:291556 } else if (url.SchemeIs(kBackForwardNavigationScheme)) {
1557 std::string offset_str = url.ExtractFileName();
1558 int offset;
1559 if (StringToInt(offset_str, &offset)) {
1560 GoToEntryAtOffset(offset);
1561 return IGNORE_ACTION; // The browser process handles this one.
1562 }
initial.commit09911bf2008-07-26 23:55:291563 }
1564 }
1565 }
1566
1567 // Detect when a page is "forking" a new tab that can be safely rendered in
1568 // its own process. This is done by sites like Gmail that try to open links
1569 // in new windows without script connections back to the original page. We
1570 // treat such cases as browser navigations (in which we will create a new
1571 // renderer for a cross-site navigation), rather than WebKit navigations.
1572 //
1573 // We use the following heuristic to decide whether to fork a new page in its
1574 // own process:
1575 // The parent page must open a new tab to about:blank, set the new tab's
1576 // window.opener to null, and then redirect the tab to a cross-site URL using
1577 // JavaScript.
1578 bool is_fork =
1579 // Must start from a tab showing about:blank, which is later redirected.
[email protected]6aad4bd2009-02-26 22:55:171580 frame->GetURL() == GURL("about:blank") &&
initial.commit09911bf2008-07-26 23:55:291581 // Must be the first real navigation of the tab.
1582 GetHistoryBackListCount() < 1 &&
1583 GetHistoryForwardListCount() < 1 &&
1584 // The parent page must have set the child's window.opener to null before
1585 // redirecting to the desired URL.
1586 frame->GetOpener() == NULL &&
1587 // Must be a top-level frame.
1588 frame->GetParent() == NULL &&
1589 // Must not have issued the request from this page. GetExtraData is NULL
1590 // when the navigation is being done by something outside the page.
1591 !request->GetExtraData() &&
1592 // Must be targeted at the current tab.
1593 disposition == CURRENT_TAB &&
1594 // Must be a JavaScript navigation, which appears as "other".
1595 type == WebNavigationTypeOther;
1596 if (is_fork) {
1597 // Open the URL via the browser, not via WebKit.
[email protected]c0588052008-10-27 23:01:501598 OpenURL(webview, url, GURL(), disposition);
initial.commit09911bf2008-07-26 23:55:291599 return IGNORE_ACTION;
1600 }
1601
1602 return disposition;
1603}
1604
[email protected]a455d3812009-03-05 20:18:071605void RenderView::RunJavaScriptAlert(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291606 const std::wstring& message) {
[email protected]478ff2ed2009-04-21 23:49:181607 RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptAlert,
initial.commit09911bf2008-07-26 23:55:291608 message,
1609 std::wstring(),
[email protected]a455d3812009-03-05 20:18:071610 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291611 NULL);
1612}
1613
[email protected]a455d3812009-03-05 20:18:071614bool RenderView::RunJavaScriptConfirm(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291615 const std::wstring& message) {
[email protected]478ff2ed2009-04-21 23:49:181616 return RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptConfirm,
initial.commit09911bf2008-07-26 23:55:291617 message,
1618 std::wstring(),
[email protected]a455d3812009-03-05 20:18:071619 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291620 NULL);
1621}
1622
[email protected]a455d3812009-03-05 20:18:071623bool RenderView::RunJavaScriptPrompt(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291624 const std::wstring& message,
1625 const std::wstring& default_value,
1626 std::wstring* result) {
[email protected]478ff2ed2009-04-21 23:49:181627 return RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptPrompt,
initial.commit09911bf2008-07-26 23:55:291628 message,
1629 default_value,
[email protected]a455d3812009-03-05 20:18:071630 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291631 result);
1632}
1633
1634bool RenderView::RunJavaScriptMessage(int type,
1635 const std::wstring& message,
1636 const std::wstring& default_value,
[email protected]a455d3812009-03-05 20:18:071637 const GURL& frame_url,
initial.commit09911bf2008-07-26 23:55:291638 std::wstring* result) {
1639 bool success = false;
1640 std::wstring result_temp;
1641 if (!result)
1642 result = &result_temp;
1643 IPC::SyncMessage* msg = new ViewHostMsg_RunJavaScriptMessage(
[email protected]a455d3812009-03-05 20:18:071644 routing_id_, message, default_value, frame_url, type, &success, result);
initial.commit09911bf2008-07-26 23:55:291645
[email protected]1c4947f2009-01-15 22:25:111646 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291647 Send(msg);
1648
1649 return success;
1650}
1651
1652void RenderView::AddGURLSearchProvider(const GURL& osd_url, bool autodetected) {
1653 if (!osd_url.is_empty())
1654 Send(new ViewHostMsg_PageHasOSDD(routing_id_, page_id_, osd_url,
1655 autodetected));
1656}
1657
[email protected]a455d3812009-03-05 20:18:071658bool RenderView::RunBeforeUnloadConfirm(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291659 const std::wstring& message) {
1660 bool success = false;
1661 // This is an ignored return value, but is included so we can accept the same
1662 // response as RunJavaScriptMessage.
1663 std::wstring ignored_result;
1664 IPC::SyncMessage* msg = new ViewHostMsg_RunBeforeUnloadConfirm(
[email protected]a455d3812009-03-05 20:18:071665 routing_id_, webframe->GetURL(), message, &success, &ignored_result);
initial.commit09911bf2008-07-26 23:55:291666
[email protected]1c4947f2009-01-15 22:25:111667 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291668 Send(msg);
1669
1670 return success;
1671}
1672
[email protected]0ebf3872008-11-07 21:35:031673void RenderView::QueryFormFieldAutofill(const std::wstring& field_name,
1674 const std::wstring& text,
1675 int64 node_id) {
1676 static int message_id_counter = 0;
1677 form_field_autofill_request_id_ = message_id_counter++;
1678 Send(new ViewHostMsg_QueryFormFieldAutofill(routing_id_,
1679 field_name, text,
1680 node_id,
1681 form_field_autofill_request_id_));
1682}
1683
[email protected]4d2b6fb2009-03-20 22:28:171684void RenderView::RemoveStoredAutofillEntry(const std::wstring& name,
1685 const std::wstring& value) {
1686 Send(new ViewHostMsg_RemoveAutofillEntry(routing_id_, name, value));
1687}
1688
[email protected]0ebf3872008-11-07 21:35:031689void RenderView::OnReceivedAutofillSuggestions(
1690 int64 node_id,
1691 int request_id,
[email protected]8d0f15c2008-11-11 01:01:091692 const std::vector<std::wstring>& suggestions,
[email protected]0ebf3872008-11-07 21:35:031693 int default_suggestion_index) {
1694 if (!webview() || request_id != form_field_autofill_request_id_)
1695 return;
1696
1697 webview()->AutofillSuggestionsForNode(node_id, suggestions,
1698 default_suggestion_index);
1699}
1700
[email protected]634a6f92008-12-01 21:39:311701void RenderView::OnPopupNotificationVisiblityChanged(bool visible) {
1702 popup_notification_visible_ = visible;
1703}
1704
initial.commit09911bf2008-07-26 23:55:291705void RenderView::ShowModalHTMLDialog(const GURL& url, int width, int height,
1706 const std::string& json_arguments,
1707 std::string* json_retval) {
1708 IPC::SyncMessage* msg = new ViewHostMsg_ShowModalHTMLDialog(
1709 routing_id_, url, width, height, json_arguments, json_retval);
1710
[email protected]1c4947f2009-01-15 22:25:111711 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291712 Send(msg);
1713}
1714
1715uint32 RenderView::GetCPBrowsingContext() {
1716 uint32 context = 0;
1717 Send(new ViewHostMsg_GetCPBrowsingContext(&context));
1718 return context;
1719}
1720
1721// Tell the browser to display a destination link.
1722void RenderView::UpdateTargetURL(WebView* webview, const GURL& url) {
1723 if (url != target_url_) {
1724 if (target_url_status_ == TARGET_INFLIGHT ||
1725 target_url_status_ == TARGET_PENDING) {
1726 // If we have a request in-flight, save the URL to be sent when we
1727 // receive an ACK to the in-flight request. We can happily overwrite
1728 // any existing pending sends.
1729 pending_target_url_ = url;
1730 target_url_status_ = TARGET_PENDING;
1731 } else {
1732 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_, url));
1733 target_url_ = url;
1734 target_url_status_ = TARGET_INFLIGHT;
1735 }
1736 }
1737}
1738
[email protected]b62d1a8c2009-01-13 23:54:571739void RenderView::RunFileChooser(bool multi_select,
[email protected]b949f1112009-04-12 20:03:081740 const string16& title,
1741 const FilePath& default_filename,
initial.commit09911bf2008-07-26 23:55:291742 WebFileChooserCallback* file_chooser) {
1743 if (file_chooser_.get()) {
1744 // TODO(brettw): bug 1235154: This should be a synchronous message to deal
1745 // with the fact that web pages can programatically trigger this. With the
1746 // asnychronous messages, we can get an additional call when one is pending,
1747 // which this test is for. For now, we just ignore the additional file
1748 // chooser request. WebKit doesn't do anything to expect the callback, so
1749 // we can just ignore calling it.
1750 delete file_chooser;
1751 return;
1752 }
1753 file_chooser_.reset(file_chooser);
[email protected]b62d1a8c2009-01-13 23:54:571754 Send(new ViewHostMsg_RunFileChooser(routing_id_, multi_select, title,
[email protected]b949f1112009-04-12 20:03:081755 default_filename));
initial.commit09911bf2008-07-26 23:55:291756}
1757
1758void RenderView::AddMessageToConsole(WebView* webview,
1759 const std::wstring& message,
1760 unsigned int line_no,
1761 const std::wstring& source_id) {
1762 Send(new ViewHostMsg_AddMessageToConsole(routing_id_, message,
1763 static_cast<int32>(line_no),
1764 source_id));
1765}
1766
1767void RenderView::AddSearchProvider(const std::string& url) {
1768 AddGURLSearchProvider(GURL(url),
1769 false); // not autodetected
1770}
1771
1772void RenderView::DebuggerOutput(const std::wstring& out) {
1773 Send(new ViewHostMsg_DebuggerOutput(routing_id_, out));
1774}
1775
1776WebView* RenderView::CreateWebView(WebView* webview, bool user_gesture) {
[email protected]0aa55312008-10-17 21:53:081777 // Check to make sure we aren't overloading on popups.
1778 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups)
1779 return NULL;
1780
[email protected]634a6f92008-12-01 21:39:311781 // This window can't be closed from a window.close() call until we receive a
1782 // message from the Browser process explicitly allowing it.
1783 popup_notification_visible_ = true;
1784
initial.commit09911bf2008-07-26 23:55:291785 int32 routing_id = MSG_ROUTING_NONE;
[email protected]6c8afae52009-01-22 02:24:571786
[email protected]18bcc3c2009-01-27 21:39:151787 ModalDialogEvent modal_dialog_event;
[email protected]6c8afae52009-01-22 02:24:571788 render_thread_->Send(
[email protected]15787f8f2008-10-17 15:29:031789 new ViewHostMsg_CreateWindow(routing_id_, user_gesture, &routing_id,
1790 &modal_dialog_event));
initial.commit09911bf2008-07-26 23:55:291791 if (routing_id == MSG_ROUTING_NONE) {
initial.commit09911bf2008-07-26 23:55:291792 return NULL;
1793 }
1794
1795 // The WebView holds a reference to this new RenderView
1796 const WebPreferences& prefs = webview->GetPreferences();
[email protected]6c8afae52009-01-22 02:24:571797 base::WaitableEvent* waitable_event = new base::WaitableEvent
1798#if defined(OS_WIN)
[email protected]18bcc3c2009-01-27 21:39:151799 (modal_dialog_event.event);
[email protected]6c8afae52009-01-22 02:24:571800#else
1801 (true, false);
1802#endif
[email protected]81a34412009-01-05 19:17:241803 RenderView* view = RenderView::Create(render_thread_,
[email protected]1c4947f2009-01-15 22:25:111804 NULL, waitable_event, routing_id_,
[email protected]0aa55312008-10-17 21:53:081805 prefs, shared_popup_counter_,
1806 routing_id);
[email protected]ed4bf2d2009-05-05 00:10:061807 view->opened_by_user_gesture_ = user_gesture;
initial.commit09911bf2008-07-26 23:55:291808
1809 // Copy over the alternate error page URL so we can have alt error pages in
1810 // the new render view (we don't need the browser to send the URL back down).
1811 view->alternate_error_page_url_ = alternate_error_page_url_;
1812
1813 return view->webview();
1814}
1815
[email protected]0ebf3872008-11-07 21:35:031816WebWidget* RenderView::CreatePopupWidget(WebView* webview,
[email protected]cfd727f2009-01-09 20:21:111817 bool activatable) {
[email protected]8085dbc82008-09-26 22:53:441818 RenderWidget* widget = RenderWidget::Create(routing_id_,
[email protected]81a34412009-01-05 19:17:241819 render_thread_,
[email protected]cfd727f2009-01-09 20:21:111820 activatable);
initial.commit09911bf2008-07-26 23:55:291821 return widget->webwidget();
1822}
1823
1824WebPluginDelegate* RenderView::CreatePluginDelegate(
1825 WebView* webview,
1826 const GURL& url,
1827 const std::string& mime_type,
1828 const std::string& clsid,
1829 std::string* actual_mime_type) {
[email protected]ffeba6d2009-04-27 20:43:261830#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]6273e2e72009-04-17 00:13:551831 if (!PluginChannelHost::IsListening())
1832 return NULL;
1833
[email protected]ffeba6d2009-04-27 20:43:261834#if !defined(OS_LINUX) // In-proc plugins aren't supported on Linux.
[email protected]88a1fb47a2009-03-13 00:18:061835 if (RenderProcess::current()->in_process_plugins()) {
[email protected]690a99c2009-01-06 16:48:451836 FilePath path;
[email protected]81a34412009-01-05 19:17:241837 render_thread_->Send(
initial.commit09911bf2008-07-26 23:55:291838 new ViewHostMsg_GetPluginPath(url, mime_type, clsid, &path,
1839 actual_mime_type));
[email protected]690a99c2009-01-06 16:48:451840 if (path.value().empty())
initial.commit09911bf2008-07-26 23:55:291841 return NULL;
1842
1843 std::string mime_type_to_use;
1844 if (actual_mime_type && !actual_mime_type->empty())
1845 mime_type_to_use = *actual_mime_type;
1846 else
1847 mime_type_to_use = mime_type;
1848
[email protected]b94d3322009-02-12 19:49:041849 return WebPluginDelegate::Create(path,
1850 mime_type_to_use,
1851 gfx::NativeViewFromId(host_window_));
initial.commit09911bf2008-07-26 23:55:291852 }
[email protected]ffeba6d2009-04-27 20:43:261853#endif
initial.commit09911bf2008-07-26 23:55:291854
1855 WebPluginDelegateProxy* proxy =
1856 WebPluginDelegateProxy::Create(url, mime_type, clsid, this);
1857 if (!proxy)
1858 return NULL;
1859
1860 // We hold onto the proxy so we can poke it when we are painting. See our
1861 // DidPaint implementation below.
1862 plugin_delegates_.push_back(proxy);
1863
1864 return proxy;
[email protected]6c8afae52009-01-22 02:24:571865#else
[email protected]157e5d22009-04-23 18:43:351866 // TODO(port): Plugins currently not supported
1867 NOTIMPLEMENTED();
1868 return NULL;
[email protected]6c8afae52009-01-22 02:24:571869#endif
initial.commit09911bf2008-07-26 23:55:291870}
1871
[email protected]ec9212f2008-12-18 21:40:361872webkit_glue::WebMediaPlayerDelegate* RenderView::CreateMediaPlayerDelegate() {
[email protected]3579c4d2009-05-01 23:25:361873#if defined(OS_WIN)
[email protected]d43ed912009-02-03 04:52:531874 return new WebMediaPlayerDelegateImpl(this);
[email protected]3579c4d2009-05-01 23:25:361875#else
1876 // TODO(port)
1877 NOTIMPLEMENTED();
1878 return NULL;
1879#endif
[email protected]ec9212f2008-12-18 21:40:361880}
1881
initial.commit09911bf2008-07-26 23:55:291882void RenderView::OnMissingPluginStatus(WebPluginDelegate* delegate,
1883 int status) {
[email protected]6c8afae52009-01-22 02:24:571884#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291885 if (first_default_plugin_ == NULL) {
1886 // Show the InfoBar for the first available plugin.
1887 if (status == default_plugin::MISSING_PLUGIN_AVAILABLE) {
1888 first_default_plugin_ = delegate;
1889 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1890 }
1891 } else {
1892 // Closes the InfoBar if user clicks on the plugin (instead of the InfoBar)
1893 // to start the download/install.
1894 if (status == default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD) {
1895 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1896 }
1897 }
[email protected]6c8afae52009-01-22 02:24:571898#else
1899 // TODO(port): plugins current not supported
1900 NOTIMPLEMENTED();
1901#endif
initial.commit09911bf2008-07-26 23:55:291902}
1903
[email protected]eb47a132009-03-04 00:39:561904WebWorker* RenderView::CreateWebWorker(WebWorkerClient* client) {
1905#if defined(OS_WIN)
[email protected]ec775ef2009-05-01 21:20:471906 return new WebWorkerProxy(client, RenderThread::current(), routing_id_);
[email protected]eb47a132009-03-04 00:39:561907#else
1908 // TODO(port): out of process workers
1909 NOTIMPLEMENTED();
1910 return NULL;
1911#endif
1912}
1913
initial.commit09911bf2008-07-26 23:55:291914void RenderView::OpenURL(WebView* webview, const GURL& url,
[email protected]c0588052008-10-27 23:01:501915 const GURL& referrer,
initial.commit09911bf2008-07-26 23:55:291916 WindowOpenDisposition disposition) {
[email protected]c0588052008-10-27 23:01:501917 Send(new ViewHostMsg_OpenURL(routing_id_, url, referrer, disposition));
initial.commit09911bf2008-07-26 23:55:291918}
1919
[email protected]1d522202009-04-04 01:56:421920void RenderView::DidContentsSizeChange(WebWidget* webwidget,
1921 int new_width,
1922 int new_height) {
1923 // TODO(rafaelw): This is a temporary solution. Only the ExtensionView wants
1924 // this notification at the moment. It isn't clean to test for ExtensionView
1925 // by examining the enabled_bindings. This needs to be generalized as it
1926 // becomes clear what extension toolbars need.
1927 if (BindingsPolicy::is_extension_enabled(enabled_bindings_)) {
1928 int width = webview()->GetMainFrame()->GetContentsPreferredWidth();
1929 Send(new ViewHostMsg_DidContentsPreferredWidthChange(routing_id_, width));
1930 }
1931}
1932
initial.commit09911bf2008-07-26 23:55:291933// We are supposed to get a single call to Show for a newly created RenderView
1934// that was created via RenderView::CreateWebView. So, we wait until this
1935// point to dispatch the ShowView message.
1936//
1937// This method provides us with the information about how to display the newly
1938// created RenderView (i.e., as a constrained popup or as a new tab).
1939//
1940void RenderView::Show(WebWidget* webwidget, WindowOpenDisposition disposition) {
1941 DCHECK(!did_show_) << "received extraneous Show call";
1942 DCHECK(opener_id_ != MSG_ROUTING_NONE);
1943
1944 if (did_show_)
1945 return;
1946 did_show_ = true;
1947
1948 // NOTE: initial_pos_ may still have its default values at this point, but
1949 // that's okay. It'll be ignored if disposition is not NEW_POPUP, or the
1950 // browser process will impose a default position otherwise.
[email protected]35f7d212009-04-29 21:19:271951 Send(new ViewHostMsg_ShowView(opener_id_, routing_id_, disposition,
[email protected]ed4bf2d2009-05-05 00:10:061952 initial_pos_, opened_by_user_gesture_));
initial.commit09911bf2008-07-26 23:55:291953}
1954
[email protected]634a6f92008-12-01 21:39:311955void RenderView::CloseWidgetSoon(WebWidget* webwidget) {
1956 if (popup_notification_visible_ == false)
1957 RenderWidget::CloseWidgetSoon(webwidget);
1958}
1959
initial.commit09911bf2008-07-26 23:55:291960void RenderView::RunModal(WebWidget* webwidget) {
1961 DCHECK(did_show_) << "should already have shown the view";
1962
1963 IPC::SyncMessage* msg = new ViewHostMsg_RunModal(routing_id_);
1964
[email protected]1c4947f2009-01-15 22:25:111965 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291966 Send(msg);
1967}
1968
1969void RenderView::SyncNavigationState() {
1970 if (!webview())
1971 return;
1972
initial.commit09911bf2008-07-26 23:55:291973 std::string state;
[email protected]606843fa2008-12-02 19:08:561974 if (!webview()->GetMainFrame()->GetCurrentHistoryState(&state))
initial.commit09911bf2008-07-26 23:55:291975 return;
[email protected]606843fa2008-12-02 19:08:561976 Send(new ViewHostMsg_UpdateState(routing_id_, page_id_, state));
initial.commit09911bf2008-07-26 23:55:291977}
1978
1979void RenderView::ShowContextMenu(WebView* webview,
[email protected]124646932009-01-28 18:39:021980 ContextNode node,
initial.commit09911bf2008-07-26 23:55:291981 int x,
1982 int y,
1983 const GURL& link_url,
1984 const GURL& image_url,
1985 const GURL& page_url,
1986 const GURL& frame_url,
1987 const std::wstring& selection_text,
1988 const std::wstring& misspelled_word,
[email protected]6aa376b2008-09-23 18:49:521989 int edit_flags,
[email protected]c9825a42009-05-01 22:51:501990 const std::string& security_info,
1991 const std::string& frame_charset) {
[email protected]e09ba552009-02-05 03:26:291992 ContextMenuParams params;
[email protected]124646932009-01-28 18:39:021993 params.node = node;
initial.commit09911bf2008-07-26 23:55:291994 params.x = x;
1995 params.y = y;
1996 params.image_url = image_url;
1997 params.link_url = link_url;
[email protected]e6c79812009-04-22 22:31:421998 params.unfiltered_link_url = link_url;
initial.commit09911bf2008-07-26 23:55:291999 params.page_url = page_url;
2000 params.frame_url = frame_url;
2001 params.selection_text = selection_text;
2002 params.misspelled_word = misspelled_word;
[email protected]be645db2009-02-06 20:36:332003 params.spellcheck_enabled =
[email protected]bbbd545c2008-12-15 20:18:042004 webview->GetFocusedFrame()->SpellCheckEnabled();
initial.commit09911bf2008-07-26 23:55:292005 params.edit_flags = edit_flags;
[email protected]6aa376b2008-09-23 18:49:522006 params.security_info = security_info;
[email protected]c9825a42009-05-01 22:51:502007 params.frame_charset = frame_charset;
initial.commit09911bf2008-07-26 23:55:292008 Send(new ViewHostMsg_ContextMenu(routing_id_, params));
2009}
2010
[email protected]e80c73b2009-04-07 23:24:582011void RenderView::StartDragging(WebView* webview,
2012 const WebDragData& drag_data) {
2013 Send(new ViewHostMsg_StartDragging(routing_id_, WebDropData(drag_data)));
initial.commit09911bf2008-07-26 23:55:292014}
2015
2016void RenderView::TakeFocus(WebView* webview, bool reverse) {
2017 Send(new ViewHostMsg_TakeFocus(routing_id_, reverse));
2018}
2019
2020void RenderView::DidDownloadImage(int id,
2021 const GURL& image_url,
2022 bool errored,
2023 const SkBitmap& image) {
2024 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, errored,
2025 image));
2026}
2027
2028
2029void RenderView::OnDownloadImage(int id,
2030 const GURL& image_url,
2031 int image_size) {
[email protected]f11ca0732009-04-11 00:09:342032
2033 bool data_image_failed = false;
2034 if (image_url.SchemeIs("data")) {
2035 SkBitmap data_image = ImageFromDataUrl(image_url);
2036 data_image_failed = data_image.empty();
2037 if (!data_image_failed) {
2038 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, false,
2039 data_image));
2040 }
2041 }
2042
2043 if (data_image_failed || !webview()->DownloadImage(id, image_url, image_size))
initial.commit09911bf2008-07-26 23:55:292044 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, true,
2045 SkBitmap()));
2046}
2047
[email protected]f11ca0732009-04-11 00:09:342048SkBitmap RenderView::ImageFromDataUrl(const GURL& url) const {
2049 std::string mime_type, char_set, data;
2050 if (net::DataURL::Parse(url, &mime_type, &char_set, &data) && !data.empty()) {
2051 // Decode the favicon using WebKit's image decoder.
2052 webkit_glue::ImageDecoder decoder(gfx::Size(kFavIconSize, kFavIconSize));
2053 const unsigned char* src_data =
2054 reinterpret_cast<const unsigned char*>(&data[0]);
2055
2056 return decoder.Decode(src_data, data.size());
2057 }
2058 return SkBitmap();
2059}
2060
initial.commit09911bf2008-07-26 23:55:292061void RenderView::OnGetApplicationInfo(int page_id) {
2062 webkit_glue::WebApplicationInfo app_info;
2063 if (page_id == page_id_)
2064 webkit_glue::GetApplicationInfo(webview(), &app_info);
2065
2066 // Prune out any data URLs in the set of icons. The browser process expects
2067 // any icon with a data URL to have originated from a favicon. We don't want
2068 // to decode arbitrary data URLs in the browser process. See
2069 // http://b/issue?id=1162972
2070 for (size_t i = 0; i < app_info.icons.size(); ++i) {
[email protected]6de74452009-02-25 18:04:592071 if (app_info.icons[i].url.SchemeIs(chrome::kDataScheme)) {
initial.commit09911bf2008-07-26 23:55:292072 app_info.icons.erase(app_info.icons.begin() + i);
2073 --i;
2074 }
2075 }
2076
2077 Send(new ViewHostMsg_DidGetApplicationInfo(routing_id_, page_id, app_info));
2078}
2079
2080GURL RenderView::GetAlternateErrorPageURL(const GURL& failedURL,
2081 ErrorPageType error_type) {
2082 if (failedURL.SchemeIsSecure()) {
2083 // If the URL that failed was secure, then the embedding web page was not
2084 // expecting a network attacker to be able to manipulate its contents. As
2085 // we fetch alternate error pages over HTTP, we would be allowing a network
2086 // attacker to manipulate the contents of the response if we tried to use
2087 // the link doctor here.
2088 return GURL::EmptyGURL();
2089 }
2090
2091 // Grab the base URL from the browser process.
2092 if (!alternate_error_page_url_.is_valid())
2093 return GURL::EmptyGURL();
2094
2095 // Strip query params from the failed URL.
2096 GURL::Replacements remove_params;
2097 remove_params.ClearUsername();
2098 remove_params.ClearPassword();
2099 remove_params.ClearQuery();
2100 remove_params.ClearRef();
2101 const GURL url_to_send = failedURL.ReplaceComponents(remove_params);
2102
2103 // Construct the query params to send to link doctor.
2104 std::string params(alternate_error_page_url_.query());
2105 params.append("&url=");
2106 params.append(EscapeQueryParamValue(url_to_send.spec()));
2107 params.append("&sourceid=chrome");
2108 params.append("&error=");
2109 switch (error_type) {
2110 case DNS_ERROR:
2111 params.append("dnserror");
2112 break;
2113
2114 case HTTP_404:
2115 params.append("http404");
2116 break;
2117
[email protected]5df266ac2008-10-15 19:50:132118 case CONNECTION_ERROR:
[email protected]e1f934b2009-01-26 20:41:332119 params.append("connectionfailure");
[email protected]5df266ac2008-10-15 19:50:132120 break;
2121
initial.commit09911bf2008-07-26 23:55:292122 default:
2123 NOTREACHED() << "unknown ErrorPageType";
2124 }
2125
2126 // OK, build the final url to return.
2127 GURL::Replacements link_doctor_params;
2128 link_doctor_params.SetQueryStr(params);
2129 GURL url = alternate_error_page_url_.ReplaceComponents(link_doctor_params);
2130 return url;
2131}
2132
[email protected]7ea066a2009-04-06 20:21:592133void RenderView::OnFind(int request_id,
2134 const string16& search_text,
2135 const WebKit::WebFindOptions& options) {
initial.commit09911bf2008-07-26 23:55:292136 WebFrame* main_frame = webview()->GetMainFrame();
2137 WebFrame* frame_after_main = webview()->GetNextFrameAfter(main_frame, true);
2138 WebFrame* focused_frame = webview()->GetFocusedFrame();
2139 WebFrame* search_frame = focused_frame; // start searching focused frame.
2140
2141 bool multi_frame = (frame_after_main != main_frame);
2142
2143 // If we have multiple frames, we don't want to wrap the search within the
2144 // frame, so we check here if we only have main_frame in the chain.
2145 bool wrap_within_frame = !multi_frame;
2146
[email protected]b3f2b912009-04-09 16:18:522147 WebRect selection_rect;
initial.commit09911bf2008-07-26 23:55:292148 bool result = false;
2149
2150 do {
[email protected]7ea066a2009-04-06 20:21:592151 result = search_frame->Find(
2152 request_id, search_text, options, wrap_within_frame, &selection_rect);
initial.commit09911bf2008-07-26 23:55:292153
2154 if (!result) {
2155 // don't leave text selected as you move to the next frame.
2156 search_frame->ClearSelection();
2157
2158 // Find the next frame, but skip the invisible ones.
2159 do {
2160 // What is the next frame to search? (we might be going backwards). Note
2161 // that we specify wrap=true so that search_frame never becomes NULL.
[email protected]7ea066a2009-04-06 20:21:592162 search_frame = options.forward ?
initial.commit09911bf2008-07-26 23:55:292163 webview()->GetNextFrameAfter(search_frame, true) :
2164 webview()->GetPreviousFrameBefore(search_frame, true);
2165 } while (!search_frame->Visible() && search_frame != focused_frame);
2166
[email protected]884db412008-11-24 23:46:502167 // Make sure selection doesn't affect the search operation in new frame.
initial.commit09911bf2008-07-26 23:55:292168 search_frame->ClearSelection();
2169
2170 // If we have multiple frames and we have wrapped back around to the
2171 // focused frame, we need to search it once more allowing wrap within
2172 // the frame, otherwise it will report 'no match' if the focused frame has
2173 // reported matches, but no frames after the focused_frame contain a
2174 // match for the search word(s).
2175 if (multi_frame && search_frame == focused_frame) {
[email protected]7ea066a2009-04-06 20:21:592176 result = search_frame->Find(
2177 request_id, search_text, options, true, // Force wrapping.
2178 &selection_rect);
initial.commit09911bf2008-07-26 23:55:292179 }
2180 }
2181
2182 // TODO(jcampan): http://b/issue?id=1157486 Remove StoreForFocus call once
2183 // we have the fix for 792423.
2184 search_frame->GetView()->StoreFocusForFrame(search_frame);
2185 webview()->SetFocusedFrame(search_frame);
2186 } while (!result && search_frame != focused_frame);
2187
2188 // Make sure we don't leave any frame focused or the focus won't be restored
2189 // properly in WebViewImpl::SetFocus(). Note that we are talking here about
2190 // focused on the SelectionController, not FocusController.
2191 // webview()->GetFocusedFrame() will still return the last focused frame (as
2192 // it queries the FocusController).
2193 // TODO(jcampan): http://b/issue?id=1157486 Remove next line once we have the
2194 // fix for 792423.
2195 webview()->SetFocusedFrame(NULL);
2196
[email protected]7ea066a2009-04-06 20:21:592197 if (options.findNext) {
[email protected]4f3dc372009-02-24 00:10:292198 // Force the main_frame to report the actual count.
[email protected]7ea066a2009-04-06 20:21:592199 main_frame->IncreaseMatchCount(0, request_id);
[email protected]4f3dc372009-02-24 00:10:292200 } else {
2201 // If nothing is found, set result to "0 of 0", otherwise, set it to
2202 // "-1 of 1" to indicate that we found at least one item, but we don't know
2203 // yet what is active.
2204 int ordinal = result ? -1 : 0; // -1 here means, we might know more later.
2205 int match_count = result ? 1 : 0; // 1 here means possibly more coming.
initial.commit09911bf2008-07-26 23:55:292206
[email protected]4f3dc372009-02-24 00:10:292207 // If we find no matches then this will be our last status update.
2208 // Otherwise the scoping effort will send more results.
2209 bool final_status_update = !result;
initial.commit09911bf2008-07-26 23:55:292210
[email protected]4f3dc372009-02-24 00:10:292211 // Send the search result over to the browser process.
[email protected]4f999132009-03-31 18:08:402212 Send(new ViewHostMsg_Find_Reply(routing_id_,
[email protected]7ea066a2009-04-06 20:21:592213 request_id,
[email protected]4f3dc372009-02-24 00:10:292214 match_count,
2215 selection_rect,
2216 ordinal,
2217 final_status_update));
initial.commit09911bf2008-07-26 23:55:292218
initial.commit09911bf2008-07-26 23:55:292219 // Scoping effort begins, starting with the mainframe.
2220 search_frame = main_frame;
2221
2222 main_frame->ResetMatchCount();
2223
2224 do {
2225 // Cancel all old scoping requests before starting a new one.
2226 search_frame->CancelPendingScopingEffort();
2227
2228 // We don't start another scoping effort unless at least one match has
2229 // been found.
2230 if (result) {
2231 // Start new scoping request. If the scoping function determines that it
2232 // needs to scope, it will defer until later.
[email protected]7ea066a2009-04-06 20:21:592233 search_frame->ScopeStringMatches(request_id,
2234 search_text,
2235 options,
initial.commit09911bf2008-07-26 23:55:292236 true); // reset the tickmarks
2237 }
2238
2239 // Iterate to the next frame. The frame will not necessarily scope, for
2240 // example if it is not visible.
2241 search_frame = webview()->GetNextFrameAfter(search_frame, true);
2242 } while (search_frame != main_frame);
2243 }
2244}
2245
2246void RenderView::ReportFindInPageMatchCount(int count, int request_id,
2247 bool final_update) {
2248 // If we have a message that has been queued up, then we should just replace
2249 // it. The ACK from the browser will make sure it gets sent when the browser
2250 // wants it.
2251 if (queued_find_reply_message_.get()) {
2252 IPC::Message* msg = new ViewHostMsg_Find_Reply(
2253 routing_id_,
2254 request_id,
2255 count,
[email protected]b3f2b912009-04-09 16:18:522256 gfx::Rect(),
initial.commit09911bf2008-07-26 23:55:292257 -1, // Don't update active match ordinal.
2258 final_update);
2259 queued_find_reply_message_.reset(msg);
2260 } else {
2261 // Send the search result over to the browser process.
2262 Send(new ViewHostMsg_Find_Reply(
2263 routing_id_,
2264 request_id,
2265 count,
[email protected]b3f2b912009-04-09 16:18:522266 gfx::Rect(),
initial.commit09911bf2008-07-26 23:55:292267 -1, // // Don't update active match ordinal.
2268 final_update));
2269 }
2270}
2271
2272void RenderView::ReportFindInPageSelection(int request_id,
2273 int active_match_ordinal,
[email protected]b3f2b912009-04-09 16:18:522274 const WebRect& selection_rect) {
initial.commit09911bf2008-07-26 23:55:292275 // Send the search result over to the browser process.
2276 Send(new ViewHostMsg_Find_Reply(routing_id_,
2277 request_id,
2278 -1,
2279 selection_rect,
2280 active_match_ordinal,
2281 false));
2282}
2283
[email protected]ed4bf2d2009-05-05 00:10:062284bool RenderView::WasOpenedByUserGesture() const {
initial.commit09911bf2008-07-26 23:55:292285 return opened_by_user_gesture_;
2286}
2287
2288void RenderView::SpellCheck(const std::wstring& word, int& misspell_location,
2289 int& misspell_length) {
2290 Send(new ViewHostMsg_SpellCheck(routing_id_, word, &misspell_location,
2291 &misspell_length));
2292}
2293
2294void RenderView::SetInputMethodState(bool enabled) {
2295 // Save the updated IME status and mark the input focus has been updated.
2296 // The IME status is to be sent to a browser process next time when
2297 // the input caret is rendered.
[email protected]9f23f592008-11-17 08:36:342298 if (!ime_control_busy_) {
2299 ime_control_updated_ = true;
2300 ime_control_new_state_ = enabled;
2301 }
initial.commit09911bf2008-07-26 23:55:292302}
2303
2304void RenderView::ScriptedPrint(WebFrame* frame) {
[email protected]6c8afae52009-01-22 02:24:572305#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292306 // Retrieve the default print settings to calculate the expected number of
2307 // pages.
2308 ViewMsg_Print_Params default_settings;
2309 IPC::SyncMessage* msg =
2310 new ViewHostMsg_GetDefaultPrintSettings(routing_id_, &default_settings);
2311 if (Send(msg)) {
2312 msg = NULL;
[email protected]378f0e822009-04-28 15:27:122313 // Check if the printer returned any settings, if the settings is empty, we
2314 // can safely assume there are no printer drivers configured. So we safely
2315 // terminate.
2316 if (default_settings.IsEmpty()) {
2317 RunJavaScriptAlert(frame,
2318 l10n_util::GetString(IDS_DEFAULT_PRINTER_NOT_FOUND_WARNING_TITLE));
2319 return;
2320 }
2321
initial.commit09911bf2008-07-26 23:55:292322 // Continue only if the settings are valid.
2323 if (default_settings.dpi && default_settings.document_cookie) {
[email protected]88a3ecc2009-03-19 17:36:222324 int expected_pages_count = 0;
2325 gfx::Size canvas_size;
2326 canvas_size.set_width(
2327 printing::ConvertUnit(default_settings.printable_size.width(),
2328 static_cast<int>(default_settings.dpi),
2329 default_settings.desired_dpi));
2330 canvas_size.set_height(
2331 printing::ConvertUnit(default_settings.printable_size.height(),
2332 static_cast<int>(default_settings.dpi),
2333 default_settings.desired_dpi));
2334 frame->BeginPrint(canvas_size, &expected_pages_count);
initial.commit09911bf2008-07-26 23:55:292335 DCHECK(expected_pages_count);
[email protected]88a3ecc2009-03-19 17:36:222336 frame->EndPrint();
initial.commit09911bf2008-07-26 23:55:292337
2338 // Ask the browser to show UI to retrieve the final print settings.
2339 ViewMsg_PrintPages_Params print_settings;
2340 // host_window_ may be NULL at this point if the current window is a popup
2341 // and the print() command has been issued from the parent. The receiver
2342 // of this message has to deal with this.
2343 msg = new ViewHostMsg_ScriptedPrint(routing_id_,
2344 host_window_,
2345 default_settings.document_cookie,
2346 expected_pages_count,
2347 &print_settings);
2348 if (Send(msg)) {
2349 msg = NULL;
2350
2351 // If the settings are invalid, early quit.
2352 if (print_settings.params.dpi &&
2353 print_settings.params.document_cookie) {
2354 // Render the printed pages. It will implicitly revert the document to
2355 // display CSS media type.
2356 PrintPages(print_settings, frame);
2357 // All went well.
2358 return;
2359 } else {
2360 // The user cancelled.
2361 }
2362 } else {
2363 // Send() failed.
2364 NOTREACHED();
2365 }
2366 } else {
2367 // The user cancelled.
2368 }
2369 } else {
2370 // Send() failed.
2371 NOTREACHED();
2372 }
2373 // TODO(maruel): bug 1123882 Alert the user that printing failed.
[email protected]6c8afae52009-01-22 02:24:572374#else // defined(OS_WIN)
2375 // TODO(port): print not implemented
2376 NOTIMPLEMENTED();
2377#endif
initial.commit09911bf2008-07-26 23:55:292378}
2379
2380void RenderView::WebInspectorOpened(int num_resources) {
2381 Send(new ViewHostMsg_InspectElement_Reply(routing_id_, num_resources));
2382}
2383
2384void RenderView::UserMetricsRecordAction(const std::wstring& action) {
2385 Send(new ViewHostMsg_UserMetricsRecordAction(routing_id_, action));
2386}
2387
2388void RenderView::DnsPrefetch(const std::vector<std::string>& host_names) {
2389 Send(new ViewHostMsg_DnsPrefetch(host_names));
2390}
2391
[email protected]630e26b2008-10-14 22:55:172392void RenderView::OnZoom(int function) {
2393 static const bool kZoomIsTextOnly = false;
2394 switch (function) {
2395 case PageZoom::SMALLER:
2396 webview()->ZoomOut(kZoomIsTextOnly);
initial.commit09911bf2008-07-26 23:55:292397 break;
[email protected]630e26b2008-10-14 22:55:172398 case PageZoom::STANDARD:
2399 webview()->ResetZoom();
initial.commit09911bf2008-07-26 23:55:292400 break;
[email protected]630e26b2008-10-14 22:55:172401 case PageZoom::LARGER:
2402 webview()->ZoomIn(kZoomIsTextOnly);
initial.commit09911bf2008-07-26 23:55:292403 break;
2404 default:
2405 NOTREACHED();
2406 }
2407}
2408
[email protected]ea8c7452009-04-02 20:47:062409void RenderView::OnInsertText(const string16& text) {
[email protected]00d7e622009-04-21 23:06:052410 WebTextInput* text_input = webview()->GetMainFrame()->GetTextInput();
2411 if (text_input)
2412 text_input->InsertText(UTF16ToUTF8(text));
[email protected]ea8c7452009-04-02 20:47:062413}
2414
[email protected]e38f40152008-09-12 23:08:302415void RenderView::OnSetPageEncoding(const std::wstring& encoding_name) {
initial.commit09911bf2008-07-26 23:55:292416 webview()->SetPageEncoding(encoding_name);
2417}
2418
2419void RenderView::OnPasswordFormsSeen(WebView* webview,
2420 const std::vector<PasswordForm>& forms) {
2421 Send(new ViewHostMsg_PasswordFormsSeen(routing_id_, forms));
2422}
2423
[email protected]8d0f15c2008-11-11 01:01:092424void RenderView::OnAutofillFormSubmitted(WebView* webview,
2425 const AutofillForm& form) {
2426 Send(new ViewHostMsg_AutofillFormSubmitted(routing_id_, form));
2427}
2428
[email protected]81cf6f72009-05-04 22:18:292429WebHistoryItem* RenderView::GetHistoryEntryAtOffset(int offset) {
2430 // Our history list is kept in the browser process on the UI thread. Since
2431 // we can't make a sync IPC call to that thread without risking deadlock,
2432 // we use a trick: construct a fake history item of the form:
2433 // history://go/OFFSET
2434 // When WebCore tells us to navigate to it, we tell the browser process to
2435 // do a back/forward navigation instead.
2436
2437 GURL url(StringPrintf("%s://go/%d", kBackForwardNavigationScheme, offset));
2438 history_navigation_item_ = WebHistoryItem::Create(url, L"", "", NULL);
2439 return history_navigation_item_.get();
2440}
2441
2442void RenderView::GoToEntryAtOffset(int offset) {
[email protected]f46aff62008-10-16 07:58:052443 history_back_list_count_ += offset;
2444 history_forward_list_count_ -= offset;
2445
initial.commit09911bf2008-07-26 23:55:292446 Send(new ViewHostMsg_GoToEntryAtOffset(routing_id_, offset));
2447}
2448
2449int RenderView::GetHistoryBackListCount() {
2450 return history_back_list_count_;
2451}
2452
2453int RenderView::GetHistoryForwardListCount() {
2454 return history_forward_list_count_;
2455}
2456
2457void RenderView::OnNavStateChanged(WebView* webview) {
[email protected]81a34412009-01-05 19:17:242458 if (!nav_state_sync_timer_.IsRunning()) {
2459 nav_state_sync_timer_.Start(
2460 TimeDelta::FromSeconds(delay_seconds_for_form_state_sync_), this,
2461 &RenderView::SyncNavigationState);
2462 }
initial.commit09911bf2008-07-26 23:55:292463}
2464
2465void RenderView::SetTooltipText(WebView* webview,
2466 const std::wstring& tooltip_text) {
2467 Send(new ViewHostMsg_SetTooltipText(routing_id_, tooltip_text));
2468}
2469
[email protected]2e417c82009-04-02 22:30:262470void RenderView::DidChangeSelection(bool is_empty_selection) {
2471#if defined(OS_LINUX)
2472 if (!is_empty_selection) {
[email protected]dbadbcc2009-04-09 00:57:102473 Send(new ViewHostMsg_SelectionChanged(routing_id_,
2474 webview()->GetMainFrame()->GetSelection(false)));
[email protected]2e417c82009-04-02 22:30:262475 }
2476#endif
2477}
2478
2479
initial.commit09911bf2008-07-26 23:55:292480void RenderView::DownloadUrl(const GURL& url, const GURL& referrer) {
2481 Send(new ViewHostMsg_DownloadUrl(routing_id_, url, referrer));
2482}
2483
[email protected]611cad42009-03-16 18:51:342484WebDevToolsAgentDelegate* RenderView::GetWebDevToolsAgentDelegate() {
[email protected]b75b7d072009-04-06 13:47:002485 return devtools_agent_.get();
[email protected]611cad42009-03-16 18:51:342486}
2487
[email protected]ea8c7452009-04-02 20:47:062488void RenderView::PasteFromSelectionClipboard() {
2489 Send(new ViewHostMsg_PasteFromSelectionClipboard(routing_id_));
2490}
2491
initial.commit09911bf2008-07-26 23:55:292492WebFrame* RenderView::GetChildFrame(const std::wstring& frame_xpath) const {
2493 WebFrame* web_frame;
2494 if (frame_xpath.empty()) {
2495 web_frame = webview()->GetMainFrame();
2496 } else {
2497 web_frame = webview()->GetMainFrame()->GetChildFrame(frame_xpath);
2498 }
2499
2500 return web_frame;
2501}
2502
[email protected]f29acf52008-11-03 20:08:332503void RenderView::EvaluateScript(const std::wstring& frame_xpath,
2504 const std::wstring& script) {
initial.commit09911bf2008-07-26 23:55:292505 WebFrame* web_frame = GetChildFrame(frame_xpath);
2506 if (!web_frame)
2507 return;
2508
[email protected]4f999132009-03-31 18:08:402509 web_frame->ExecuteScript(WebScriptSource(WideToUTF16Hack(script)));
initial.commit09911bf2008-07-26 23:55:292510}
2511
[email protected]1810e132009-03-24 23:35:482512void RenderView::InsertCSS(const std::wstring& frame_xpath,
2513 const std::string& css) {
2514 WebFrame* web_frame = GetChildFrame(frame_xpath);
2515 if (!web_frame)
2516 return;
2517
2518 web_frame->InsertCSSStyles(css);
2519}
2520
initial.commit09911bf2008-07-26 23:55:292521void RenderView::OnScriptEvalRequest(const std::wstring& frame_xpath,
2522 const std::wstring& jscript) {
[email protected]f29acf52008-11-03 20:08:332523 EvaluateScript(frame_xpath, jscript);
initial.commit09911bf2008-07-26 23:55:292524}
2525
[email protected]1810e132009-03-24 23:35:482526void RenderView::OnCSSInsertRequest(const std::wstring& frame_xpath,
2527 const std::string& css) {
2528 InsertCSS(frame_xpath, css);
2529}
2530
[email protected]7ea066a2009-04-06 20:21:592531void RenderView::OnAddMessageToConsole(
2532 const string16& frame_xpath,
2533 const string16& message,
2534 const WebConsoleMessage::Level& level) {
2535 WebFrame* web_frame = GetChildFrame(UTF16ToWideHack(frame_xpath));
[email protected]0dea3ea2009-03-31 23:30:592536 if (web_frame)
[email protected]7ea066a2009-04-06 20:21:592537 web_frame->AddMessageToConsole(WebConsoleMessage(level, message));
initial.commit09911bf2008-07-26 23:55:292538}
2539
[email protected]6c8afae52009-01-22 02:24:572540#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292541void RenderView::OnDebugAttach() {
initial.commit09911bf2008-07-26 23:55:292542 Send(new ViewHostMsg_DidDebugAttach(routing_id_));
2543 // Tell the plugin host to stop accepting messages in order to avoid
2544 // hangs while the renderer is paused.
2545 // TODO(1243929): It might be an improvement to add more plumbing to do this
2546 // when the renderer is actually paused vs. just the debugger being attached.
2547 PluginChannelHost::SetListening(false);
2548}
2549
2550void RenderView::OnDebugDetach() {
2551 // Tell the plugin host to start accepting plugin messages again.
2552 PluginChannelHost::SetListening(true);
2553}
[email protected]6c8afae52009-01-22 02:24:572554#else // defined(OS_WIN)
2555// TODO(port): plugins not yet supported
2556void RenderView::OnDebugAttach() { NOTIMPLEMENTED(); }
2557void RenderView::OnDebugDetach() { NOTIMPLEMENTED(); }
2558#endif
initial.commit09911bf2008-07-26 23:55:292559
[email protected]81e63782009-02-27 19:35:092560void RenderView::OnAllowBindings(int enabled_bindings_flags) {
2561 enabled_bindings_ |= enabled_bindings_flags;
initial.commit09911bf2008-07-26 23:55:292562}
2563
2564void RenderView::OnSetDOMUIProperty(const std::string& name,
2565 const std::string& value) {
[email protected]81e63782009-02-27 19:35:092566 DCHECK(BindingsPolicy::is_dom_ui_enabled(enabled_bindings_));
initial.commit09911bf2008-07-26 23:55:292567 dom_ui_bindings_.SetProperty(name, value);
2568}
2569
2570void RenderView::OnReservePageIDRange(int size_of_range) {
2571 next_page_id_ += size_of_range + 1;
2572}
2573
[email protected]e80c73b2009-04-07 23:24:582574void RenderView::OnDragSourceEndedOrMoved(const gfx::Point& client_point,
2575 const gfx::Point& screen_point,
initial.commit09911bf2008-07-26 23:55:292576 bool ended) {
2577 if (ended)
[email protected]e80c73b2009-04-07 23:24:582578 webview()->DragSourceEndedAt(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292579 else
[email protected]e80c73b2009-04-07 23:24:582580 webview()->DragSourceMovedTo(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292581}
2582
2583void RenderView::OnDragSourceSystemDragEnded() {
2584 webview()->DragSourceSystemDragEnded();
2585}
2586
2587void RenderView::OnUploadFileRequest(const ViewMsg_UploadFile_Params& p) {
2588 webkit_glue::FileUploadData* f = new webkit_glue::FileUploadData;
2589 f->file_path = p.file_path;
2590 f->form_name = p.form;
2591 f->file_name = p.file;
2592 f->submit_name = p.submit;
2593
2594 // Build the other form values map.
2595 if (!p.other_values.empty()) {
2596 std::vector<std::wstring> e;
2597 std::vector<std::wstring> kvp;
2598 std::vector<std::wstring>::iterator i;
2599
2600 SplitString(p.other_values, L'\n', &e);
2601 for (i = e.begin(); i != e.end(); ++i) {
2602 SplitString(*i, L'=', &kvp);
2603 if (kvp.size() == 2)
2604 f->other_form_values[kvp[0]] = kvp[1];
2605 kvp.clear();
2606 }
2607 }
2608
2609 pending_upload_data_.reset(f);
2610 ProcessPendingUpload();
2611}
2612
2613void RenderView::ProcessPendingUpload() {
2614 webkit_glue::FileUploadData* f = pending_upload_data_.get();
2615 if (f && webview() && webkit_glue::FillFormToUploadFile(webview(), *f))
2616 ResetPendingUpload();
2617}
2618
2619void RenderView::ResetPendingUpload() {
2620 pending_upload_data_.reset();
2621}
2622
2623void RenderView::OnFormFill(const FormData& form) {
2624 webkit_glue::FillForm(this->webview(), form);
2625}
2626
2627void RenderView::OnFillPasswordForm(
2628 const PasswordFormDomManager::FillData& form_data) {
2629 webkit_glue::FillPasswordForm(this->webview(), form_data);
2630}
2631
2632void RenderView::OnDragTargetDragEnter(const WebDropData& drop_data,
[email protected]e80c73b2009-04-07 23:24:582633 const gfx::Point& client_point,
2634 const gfx::Point& screen_point) {
2635 bool is_drop_target = webview()->DragTargetDragEnter(
2636 drop_data.ToDragData(),
2637 drop_data.identity,
2638 client_point,
2639 screen_point);
initial.commit09911bf2008-07-26 23:55:292640
2641 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target));
2642}
2643
[email protected]e80c73b2009-04-07 23:24:582644void RenderView::OnDragTargetDragOver(const gfx::Point& client_point,
2645 const gfx::Point& screen_point) {
2646 bool is_drop_target =
2647 webview()->DragTargetDragOver(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292648
2649 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target));
2650}
2651
2652void RenderView::OnDragTargetDragLeave() {
2653 webview()->DragTargetDragLeave();
2654}
2655
[email protected]e80c73b2009-04-07 23:24:582656void RenderView::OnDragTargetDrop(const gfx::Point& client_point,
2657 const gfx::Point& screen_point) {
2658 webview()->DragTargetDrop(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292659}
2660
2661void RenderView::OnUpdateWebPreferences(const WebPreferences& prefs) {
2662 webview()->SetPreferences(prefs);
2663}
2664
2665void RenderView::OnSetAltErrorPageURL(const GURL& url) {
2666 alternate_error_page_url_ = url;
2667}
2668
2669void RenderView::DidPaint() {
2670 PluginDelegateList::iterator it = plugin_delegates_.begin();
2671 while (it != plugin_delegates_.end()) {
2672 (*it)->FlushGeometryUpdates();
2673 ++it;
2674 }
2675}
2676
2677void RenderView::OnInstallMissingPlugin() {
2678 // This could happen when the first default plugin is deleted.
2679 if (first_default_plugin_ == NULL)
2680 return;
2681 first_default_plugin_->InstallMissingPlugin();
2682}
2683
[email protected]b62d1a8c2009-01-13 23:54:572684void RenderView::OnFileChooserResponse(
[email protected]561abe62009-04-06 18:08:342685 const std::vector<FilePath>& file_names) {
[email protected]8029f5672009-03-20 22:33:362686 // This could happen if we navigated to a different page before the user
2687 // closed the chooser.
2688 if (!file_chooser_.get())
2689 return;
2690
[email protected]b62d1a8c2009-01-13 23:54:572691 file_chooser_->OnFileChoose(file_names);
initial.commit09911bf2008-07-26 23:55:292692 file_chooser_.reset();
2693}
2694
2695void RenderView::OnEnableViewSourceMode() {
2696 if (!webview())
2697 return;
2698 WebFrame* main_frame = webview()->GetMainFrame();
2699 if (!main_frame)
2700 return;
2701
2702 main_frame->SetInViewSourceMode(true);
2703}
2704
2705void RenderView::OnUpdateBackForwardListCount(int back_list_count,
2706 int forward_list_count) {
2707 history_back_list_count_ = back_list_count;
2708 history_forward_list_count_ = forward_list_count;
2709}
2710
[email protected]266eb6f2008-09-30 23:56:502711void RenderView::OnGetAccessibilityInfo(
[email protected]6a983b42009-03-20 20:12:252712 const webkit_glue::WebAccessibility::InParams& in_params,
2713 webkit_glue::WebAccessibility::OutParams* out_params) {
[email protected]6c8afae52009-01-22 02:24:572714#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:252715 if (!web_accessibility_manager_.get()) {
2716 web_accessibility_manager_.reset(
2717 webkit_glue::WebAccessibilityManager::Create());
2718 }
[email protected]266eb6f2008-09-30 23:56:502719
[email protected]6a983b42009-03-20 20:12:252720 if (!web_accessibility_manager_->GetAccObjInfo(webview(), in_params,
2721 out_params)) {
[email protected]266eb6f2008-09-30 23:56:502722 return;
2723 }
[email protected]6c8afae52009-01-22 02:24:572724#else // defined(OS_WIN)
2725 // TODO(port): accessibility not yet implemented
2726 NOTIMPLEMENTED();
2727#endif
[email protected]266eb6f2008-09-30 23:56:502728}
2729
[email protected]6a983b42009-03-20 20:12:252730void RenderView::OnClearAccessibilityInfo(int acc_obj_id, bool clear_all) {
[email protected]6c8afae52009-01-22 02:24:572731#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:252732 if (!web_accessibility_manager_.get()) {
[email protected]266eb6f2008-09-30 23:56:502733 // If accessibility is not activated, ignore clearing message.
2734 return;
2735 }
[email protected]6a983b42009-03-20 20:12:252736 if (!web_accessibility_manager_->ClearAccObjMap(acc_obj_id, clear_all))
[email protected]266eb6f2008-09-30 23:56:502737 return;
[email protected]6c8afae52009-01-22 02:24:572738#else // defined(OS_WIN)
2739 // TODO(port): accessibility not yet implemented
2740 NOTIMPLEMENTED();
2741#endif
[email protected]266eb6f2008-09-30 23:56:502742}
2743
initial.commit09911bf2008-07-26 23:55:292744void RenderView::OnGetAllSavableResourceLinksForCurrentPage(
2745 const GURL& page_url) {
2746 // Prepare list to storage all savable resource links.
2747 std::vector<GURL> resources_list;
2748 std::vector<GURL> referrers_list;
2749 std::vector<GURL> frames_list;
2750 webkit_glue::SavableResourcesResult result(&resources_list,
2751 &referrers_list,
2752 &frames_list);
2753
2754 if (!webkit_glue::GetAllSavableResourceLinksForCurrentPage(webview(),
2755 page_url,
2756 &result)) {
2757 // If something is wrong when collecting all savable resource links,
2758 // send empty list to embedder(browser) to tell it failed.
2759 referrers_list.clear();
2760 resources_list.clear();
2761 frames_list.clear();
2762 }
2763
2764 // Send result of all savable resource links to embedder.
2765 Send(new ViewHostMsg_SendCurrentPageAllSavableResourceLinks(routing_id_,
2766 resources_list,
2767 referrers_list,
2768 frames_list));
2769}
2770
2771void RenderView::OnGetSerializedHtmlDataForCurrentPageWithLocalLinks(
[email protected]f6b48532009-02-12 01:56:322772 const std::vector<GURL>& links,
[email protected]fde6714d12009-02-18 22:39:312773 const std::vector<FilePath>& local_paths,
2774 const FilePath& local_directory_name) {
initial.commit09911bf2008-07-26 23:55:292775 webkit_glue::DomSerializer dom_serializer(webview()->GetMainFrame(),
2776 true,
2777 this,
2778 links,
2779 local_paths,
2780 local_directory_name);
2781 dom_serializer.SerializeDom();
2782}
2783
2784void RenderView::DidSerializeDataForFrame(const GURL& frame_url,
2785 const std::string& data, PageSavingSerializationStatus status) {
2786 Send(new ViewHostMsg_SendSerializedHtmlData(routing_id_,
2787 frame_url, data, static_cast<int32>(status)));
2788}
2789
[email protected]04b4a6c2008-08-02 00:44:472790void RenderView::OnMsgShouldClose() {
initial.commit09911bf2008-07-26 23:55:292791 bool should_close = webview()->ShouldClose();
[email protected]04b4a6c2008-08-02 00:44:472792 Send(new ViewHostMsg_ShouldClose_ACK(routing_id_, should_close));
initial.commit09911bf2008-07-26 23:55:292793}
2794
2795void RenderView::OnClosePage(int new_render_process_host_id,
[email protected]04b4a6c2008-08-02 00:44:472796 int new_request_id) {
initial.commit09911bf2008-07-26 23:55:292797 // TODO(creis): We'd rather use webview()->Close() here, but that currently
2798 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs
2799 // in the onunload handler from appearing. For now, we're bypassing that and
2800 // calling the FrameLoader's CloseURL method directly. This should be
2801 // revisited to avoid having two ways to close a page. Having a single way
2802 // to close that can run onunload is also useful for fixing
2803 // http://b/issue?id=753080.
2804 WebFrame* main_frame = webview()->GetMainFrame();
2805 if (main_frame)
2806 main_frame->ClosePage();
2807
2808 Send(new ViewHostMsg_ClosePage_ACK(routing_id_,
2809 new_render_process_host_id,
[email protected]04b4a6c2008-08-02 00:44:472810 new_request_id));
initial.commit09911bf2008-07-26 23:55:292811}
2812
2813void RenderView::OnThemeChanged() {
[email protected]6c8afae52009-01-22 02:24:572814#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292815 gfx::NativeTheme::instance()->CloseHandles();
2816 gfx::Rect view_rect(0, 0, size_.width(), size_.height());
2817 DidInvalidateRect(webwidget_, view_rect);
[email protected]6c8afae52009-01-22 02:24:572818#else // defined(OS_WIN)
2819 // TODO(port): we don't support theming on non-Windows platforms yet
2820 NOTIMPLEMENTED();
2821#endif
initial.commit09911bf2008-07-26 23:55:292822}
2823
[email protected]f46aff62008-10-16 07:58:052824void RenderView::DidAddHistoryItem() {
[email protected]f8901082008-10-31 23:34:032825 // We don't want to update the history length for the start page
2826 // navigation.
2827 WebFrame* main_frame = webview()->GetMainFrame();
2828 DCHECK(main_frame != NULL);
2829
2830 WebDataSource* ds = main_frame->GetDataSource();
2831 DCHECK(ds != NULL);
2832
2833 const WebRequest& request = ds->GetRequest();
2834 RenderViewExtraRequestData* extra_data =
2835 static_cast<RenderViewExtraRequestData*>(request.GetExtraData());
2836
2837 if (extra_data && extra_data->transition_type == PageTransition::START_PAGE)
2838 return;
2839
[email protected]f46aff62008-10-16 07:58:052840 history_back_list_count_++;
2841 history_forward_list_count_ = 0;
2842}
2843
[email protected]28790922009-03-09 19:48:372844void RenderView::OnMessageFromExternalHost(const std::string& message,
2845 const std::string& origin,
2846 const std::string& target) {
[email protected]3ac14a052008-08-15 21:22:152847 if (message.empty())
2848 return;
2849
[email protected]28790922009-03-09 19:48:372850 external_host_bindings_.ForwardMessageFromExternalHost(message, origin,
2851 target);
[email protected]3ac14a052008-08-15 21:22:152852}
2853
[email protected]0aa55312008-10-17 21:53:082854void RenderView::OnDisassociateFromPopupCount() {
2855 if (decrement_shared_popup_at_destruction_)
2856 shared_popup_counter_->data--;
2857 shared_popup_counter_ = new SharedRenderViewCounter(0);
2858 decrement_shared_popup_at_destruction_ = false;
2859}
2860
initial.commit09911bf2008-07-26 23:55:292861std::string RenderView::GetAltHTMLForTemplate(
2862 const DictionaryValue& error_strings, int template_resource_id) const {
2863 const StringPiece template_html(
2864 ResourceBundle::GetSharedInstance().GetRawDataResource(
2865 template_resource_id));
2866
2867 if (template_html.empty()) {
2868 NOTREACHED() << "unable to load template. ID: " << template_resource_id;
2869 return "";
2870 }
2871 // "t" is the id of the templates root node.
2872 return jstemplate_builder::GetTemplateHtml(
2873 template_html, &error_strings, "t");
2874}
[email protected]0e79b9e2009-02-13 04:20:482875
2876MessageLoop* RenderView::GetMessageLoopForIO() {
2877 // Assume that we have only one RenderThread in the process and the owner loop
2878 // of RenderThread is an IO message loop.
[email protected]8930d472009-02-21 08:05:282879 if (RenderThread::current())
2880 return RenderThread::current()->owner_loop();
[email protected]0e79b9e2009-02-13 04:20:482881 return NULL;
2882}
[email protected]6f56d482009-02-20 05:02:562883
[email protected]30f75e62009-02-25 22:01:002884void RenderView::OnMoveOrResizeStarted() {
2885 if (webview())
2886 webview()->HideAutofillPopup();
2887}
2888
[email protected]30f75e62009-02-25 22:01:002889void RenderView::OnResize(const gfx::Size& new_size,
2890 const gfx::Rect& resizer_rect) {
2891 if (webview())
2892 webview()->HideAutofillPopup();
2893 RenderWidget::OnResize(new_size, resizer_rect);
2894}
[email protected]0aa477bd2009-03-23 22:21:432895
[email protected]05d478752009-04-08 23:38:162896void RenderView::OnClearFocusedNode() {
2897 if (webview())
2898 webview()->ClearFocusedNode();
2899}
2900
[email protected]699ab0d2009-04-23 23:19:142901void RenderView::OnSetBackground(const SkBitmap& background) {
2902 if (webview())
2903 webview()->SetIsTransparent(!background.empty());
2904
2905 SetBackground(background);
2906}
2907
[email protected]309d7a282009-03-24 09:18:272908void RenderView::SendExtensionRequest(const std::string& name,
2909 const std::string& args,
2910 int callback_id,
2911 WebFrame* callback_frame) {
[email protected]309d7a282009-03-24 09:18:272912 if (callback_id != -1) {
2913 DCHECK(callback_frame) << "Callback specified without frame";
2914 pending_extension_callbacks_.AddWithID(callback_frame, callback_id);
2915 }
2916
2917 Send(new ViewHostMsg_ExtensionRequest(routing_id_, name, args, callback_id));
2918}
2919
2920void RenderView::OnExtensionResponse(int callback_id,
2921 const std::string& response) {
2922 WebFrame* web_frame = pending_extension_callbacks_.Lookup(callback_id);
2923 if (!web_frame)
2924 return; // The frame went away.
2925
[email protected]a1a0df02009-04-09 08:18:042926 ExtensionProcessBindings::ExecuteCallbackInFrame(web_frame, callback_id,
2927 response);
[email protected]309d7a282009-03-24 09:18:272928 pending_extension_callbacks_.Remove(callback_id);
2929}
[email protected]c20210e62009-04-03 21:39:262930
[email protected]e7e4f3c2009-04-21 15:24:082931// Dump all load time histograms.
[email protected]c20210e62009-04-03 21:39:262932//
[email protected]e7e4f3c2009-04-21 15:24:082933// There are 7 histograms measuring various times.
[email protected]c20210e62009-04-03 21:39:262934// The time points we keep are
2935// request: time document was requested by user
2936// start: time load of document started
2937// finishDoc: main document loaded, before onload()
2938// finish: after onload() and all resources are loaded
[email protected]e7e4f3c2009-04-21 15:24:082939// firstLayout: first layout performed
[email protected]c20210e62009-04-03 21:39:262940// The times that we histogram are
2941// requestToStart,
2942// startToFinishDoc,
2943// finishDocToFinish,
2944// startToFinish,
2945// requestToFinish,
[email protected]e7e4f3c2009-04-21 15:24:082946// requestToFirstLayout
2947// startToFirstLayout
[email protected]c20210e62009-04-03 21:39:262948//
[email protected]e7e4f3c2009-04-21 15:24:082949// It's possible for the request time not to be set, if a client
2950// redirect had been done (the user never requested the page)
2951// Also, it's possible to load a page without ever laying it out
2952// so firstLayout can be 0.
[email protected]c20210e62009-04-03 21:39:262953void RenderView::DumpLoadHistograms() const {
2954 WebFrame* main_frame = webview()->GetMainFrame();
2955 WebDataSource* ds = main_frame->GetDataSource();
[email protected]c20210e62009-04-03 21:39:262956 Time request_time = ds->GetRequestTime();
2957 Time start_load_time = ds->GetStartLoadTime();
2958 Time finish_document_load_time = ds->GetFinishDocumentLoadTime();
2959 Time finish_load_time = ds->GetFinishLoadTime();
[email protected]e7e4f3c2009-04-21 15:24:082960 Time first_layout_time = ds->GetFirstLayoutTime();
[email protected]c20210e62009-04-03 21:39:262961 TimeDelta request_to_start = start_load_time - request_time;
2962 TimeDelta start_to_finish_doc = finish_document_load_time - start_load_time;
[email protected]e7e4f3c2009-04-21 15:24:082963 TimeDelta finish_doc_to_finish =
2964 finish_load_time - finish_document_load_time;
[email protected]c20210e62009-04-03 21:39:262965 TimeDelta start_to_finish = finish_load_time - start_load_time;
2966 TimeDelta request_to_finish = finish_load_time - start_load_time;
[email protected]e7e4f3c2009-04-21 15:24:082967 TimeDelta request_to_first_layout = first_layout_time - request_time;
2968 TimeDelta start_to_first_layout = first_layout_time - start_load_time;
[email protected]c20210e62009-04-03 21:39:262969
[email protected]e7e4f3c2009-04-21 15:24:082970 // Client side redirects will have no request time
2971 if (request_time.ToInternalValue() != 0) {
2972 UMA_HISTOGRAM_TIMES("Renderer.All.RequestToStart", request_to_start);
2973 UMA_HISTOGRAM_TIMES("Renderer.All.RequestToFinish", request_to_finish);
2974 if (request_to_first_layout.ToInternalValue() >= 0) {
2975 UMA_HISTOGRAM_TIMES(
2976 "Renderer.All.RequestToFirstLayout", request_to_first_layout);
2977 }
2978 }
[email protected]c20210e62009-04-03 21:39:262979 UMA_HISTOGRAM_TIMES("Renderer.All.StartToFinishDoc", start_to_finish_doc);
2980 UMA_HISTOGRAM_TIMES("Renderer.All.FinishDocToFinish", finish_doc_to_finish);
2981 UMA_HISTOGRAM_TIMES("Renderer.All.StartToFinish", start_to_finish);
[email protected]e7e4f3c2009-04-21 15:24:082982 if (start_to_first_layout.ToInternalValue() >= 0) {
2983 UMA_HISTOGRAM_TIMES(
2984 "Renderer.All.StartToFirstLayout", start_to_first_layout);
[email protected]c20210e62009-04-03 21:39:262985 }
2986}