blob: 11fea1d90bbd04d2f8028f9876349ade8accbb63 [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
11#include "base/command_line.h"
[email protected]bb063b72009-03-27 23:18:5012#include "base/compiler_specific.h"
initial.commit09911bf2008-07-26 23:55:2913#include "base/gfx/png_encoder.h"
[email protected]18bcc3c2009-01-27 21:39:1514#include "base/gfx/native_widget_types.h"
initial.commit09911bf2008-07-26 23:55:2915#include "base/string_piece.h"
16#include "base/string_util.h"
[email protected]6c8afae52009-01-22 02:24:5717#include "build/build_config.h"
[email protected]81e63782009-02-27 19:35:0918#include "chrome/common/bindings_policy.h"
initial.commit09911bf2008-07-26 23:55:2919#include "chrome/common/chrome_switches.h"
initial.commit09911bf2008-07-26 23:55:2920#include "chrome/common/gfx/favicon_size.h"
21#include "chrome/common/gfx/color_utils.h"
22#include "chrome/common/jstemplate_builder.h"
23#include "chrome/common/l10n_util.h"
[email protected]2e4bdcdc2009-03-27 23:07:3024#include "chrome/common/message_box_flags.h"
[email protected]630e26b2008-10-14 22:55:1725#include "chrome/common/page_zoom.h"
[email protected]e09ba552009-02-05 03:26:2926#include "chrome/common/render_messages.h"
initial.commit09911bf2008-07-26 23:55:2927#include "chrome/common/resource_bundle.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"
71#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),
199 disable_popup_blocking_(false),
200 has_unload_listener_(false),
201 decrement_shared_popup_at_destruction_(false),
[email protected]81a34412009-01-05 19:17:24202 form_field_autofill_request_id_(0),
203 popup_notification_visible_(false),
204 delay_seconds_for_form_state_sync_(kDefaultDelaySecondsForFormStateSync) {
initial.commit09911bf2008-07-26 23:55:29205}
206
207RenderView::~RenderView() {
[email protected]0aa55312008-10-17 21:53:08208 if (decrement_shared_popup_at_destruction_)
209 shared_popup_counter_->data--;
210
initial.commit09911bf2008-07-26 23:55:29211 // Clear any back-pointers that might still be held by plugins.
212 PluginDelegateList::iterator it = plugin_delegates_.begin();
213 while (it != plugin_delegates_.end()) {
214 (*it)->DropRenderView();
215 it = plugin_delegates_.erase(it);
216 }
217
[email protected]81a34412009-01-05 19:17:24218 render_thread_->RemoveFilter(debug_message_handler_);
[email protected]5fb88962009-04-16 19:03:25219 render_thread_->RemoveFilter(audio_message_filter_);
initial.commit09911bf2008-07-26 23:55:29220}
221
222/*static*/
[email protected]0aa55312008-10-17 21:53:08223RenderView* RenderView::Create(
[email protected]81a34412009-01-05 19:17:24224 RenderThreadBase* render_thread,
[email protected]18bcc3c2009-01-27 21:39:15225 gfx::NativeViewId parent_hwnd,
[email protected]1c4947f2009-01-15 22:25:11226 base::WaitableEvent* modal_dialog_event,
[email protected]0aa55312008-10-17 21:53:08227 int32 opener_id,
228 const WebPreferences& webkit_prefs,
229 SharedRenderViewCounter* counter,
230 int32 routing_id) {
initial.commit09911bf2008-07-26 23:55:29231 DCHECK(routing_id != MSG_ROUTING_NONE);
[email protected]81a34412009-01-05 19:17:24232 scoped_refptr<RenderView> view = new RenderView(render_thread);
initial.commit09911bf2008-07-26 23:55:29233 view->Init(parent_hwnd,
234 modal_dialog_event,
235 opener_id,
236 webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08237 counter,
initial.commit09911bf2008-07-26 23:55:29238 routing_id); // adds reference
239 return view;
240}
241
242/*static*/
243void RenderView::SetNextPageID(int32 next_page_id) {
244 // This method should only be called during process startup, and the given
245 // page id had better not exceed our current next page id!
246 DCHECK(next_page_id_ == 1);
247 DCHECK(next_page_id >= next_page_id_);
248 next_page_id_ = next_page_id;
249}
250
251void RenderView::PluginDestroyed(WebPluginDelegateProxy* proxy) {
252 PluginDelegateList::iterator it =
253 std::find(plugin_delegates_.begin(), plugin_delegates_.end(), proxy);
254 DCHECK(it != plugin_delegates_.end());
255 plugin_delegates_.erase(it);
256 // If the plugin is deleted, we need to clear our reference in case user
257 // clicks the info bar to install. Unfortunately we are getting
258 // PluginDestroyed in single process mode. However, that is not a huge
259 // concern.
[email protected]6c8afae52009-01-22 02:24:57260#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29261 if (proxy == first_default_plugin_)
262 first_default_plugin_ = NULL;
[email protected]6c8afae52009-01-22 02:24:57263#else
264 // TODO(port): because of the headers that we aren't including, the compiler
265 // has only seen a forward decl, not the subclass relation. Thus it doesn't
266 // know that the two pointer types compared above are comparable. Once we
267 // port and include the headers this problem should go away.
268 NOTIMPLEMENTED();
269#endif
initial.commit09911bf2008-07-26 23:55:29270}
271
[email protected]690a99c2009-01-06 16:48:45272void RenderView::PluginCrashed(const FilePath& plugin_path) {
initial.commit09911bf2008-07-26 23:55:29273 Send(new ViewHostMsg_CrashedPlugin(routing_id_, plugin_path));
274}
275
276
277void RenderView::JSOutOfMemory() {
278 Send(new ViewHostMsg_JSOutOfMemory(routing_id_));
279}
280
[email protected]18bcc3c2009-01-27 21:39:15281void RenderView::Init(gfx::NativeViewId parent_hwnd,
[email protected]1c4947f2009-01-15 22:25:11282 base::WaitableEvent* modal_dialog_event,
initial.commit09911bf2008-07-26 23:55:29283 int32 opener_id,
284 const WebPreferences& webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08285 SharedRenderViewCounter* counter,
initial.commit09911bf2008-07-26 23:55:29286 int32 routing_id) {
287 DCHECK(!webview());
288
289 if (opener_id != MSG_ROUTING_NONE)
290 opener_id_ = opener_id;
291
[email protected]0aa55312008-10-17 21:53:08292 if (counter) {
293 shared_popup_counter_ = counter;
294 shared_popup_counter_->data++;
295 decrement_shared_popup_at_destruction_ = true;
296 } else {
297 shared_popup_counter_ = new SharedRenderViewCounter(0);
298 decrement_shared_popup_at_destruction_ = false;
299 }
300
[email protected]90ca3692009-04-09 16:09:43301 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
302
303 bool dev_tools_enabled = command_line.HasSwitch(
304 switches::kEnableOutOfProcessDevTools);
305 if (dev_tools_enabled)
306 devtools_agent_.reset(new DevToolsAgent(routing_id, this));
[email protected]9b9d7282009-04-08 14:13:04307
[email protected]c5b3b5e2009-02-13 06:41:11308 webwidget_ = WebView::Create(this, webkit_prefs);
initial.commit09911bf2008-07-26 23:55:29309
[email protected]2e417c82009-04-02 22:30:26310#if defined(OS_LINUX)
311 // We have to enable ourselves as the editor delegate on linux so we can copy
312 // text selections to the X clipboard.
313 webview()->SetUseEditorDelegate(true);
314#endif
315
initial.commit09911bf2008-07-26 23:55:29316 // Don't let WebCore keep a B/F list - we have our own.
317 // We let it keep 1 entry because FrameLoader::goToItem expects an item in the
318 // backForwardList, which is used only in ASSERTs.
319 webview()->SetBackForwardListSize(1);
320
321 routing_id_ = routing_id;
[email protected]81a34412009-01-05 19:17:24322 render_thread_->AddRoute(routing_id_, this);
initial.commit09911bf2008-07-26 23:55:29323 // Take a reference on behalf of the RenderThread. This will be balanced
324 // when we receive ViewMsg_Close.
325 AddRef();
326
327 // If this is a popup, we must wait for the CreatingNew_ACK message before
328 // completing initialization. Otherwise, we can finish it now.
329 if (opener_id == MSG_ROUTING_NONE) {
330 did_show_ = true;
331 CompleteInit(parent_hwnd);
332 }
333
334 host_window_ = parent_hwnd;
[email protected]1c4947f2009-01-15 22:25:11335 modal_dialog_event_.reset(modal_dialog_event);
initial.commit09911bf2008-07-26 23:55:29336
[email protected]81e63782009-02-27 19:35:09337 if (command_line.HasSwitch(switches::kDomAutomationController))
338 enabled_bindings_ |= BindingsPolicy::DOM_AUTOMATION;
initial.commit09911bf2008-07-26 23:55:29339 disable_popup_blocking_ =
340 command_line.HasSwitch(switches::kDisablePopupBlocking);
341
342 debug_message_handler_ = new DebugMessageHandler(this);
[email protected]81a34412009-01-05 19:17:24343 render_thread_->AddFilter(debug_message_handler_);
[email protected]5fb88962009-04-16 19:03:25344
345 audio_message_filter_ = new AudioMessageFilter(routing_id_);
346 render_thread_->AddFilter(audio_message_filter_);
initial.commit09911bf2008-07-26 23:55:29347}
348
349void RenderView::OnMessageReceived(const IPC::Message& message) {
[email protected]f8b6b6f2009-03-10 16:48:26350 WebFrame* main_frame = webview() ? webview()->GetMainFrame() : NULL;
351 renderer_logging::ScopedActiveRenderingURLSetter url_setter(
352 main_frame ? main_frame->GetURL() : GURL());
[email protected]f8b6b6f2009-03-10 16:48:26353
[email protected]b2abac72009-02-26 12:39:28354 // If this is developer tools renderer intercept tools messages first.
[email protected]e4ac5df2009-03-17 15:33:11355 if (devtools_client_.get() && devtools_client_->OnMessageReceived(message))
[email protected]b2abac72009-02-26 12:39:28356 return;
[email protected]b4b967e2009-04-22 11:33:05357 if (devtools_agent_.get() && devtools_agent_->OnMessageReceived(message))
358 return;
[email protected]b2abac72009-02-26 12:39:28359
initial.commit09911bf2008-07-26 23:55:29360 IPC_BEGIN_MESSAGE_MAP(RenderView, message)
initial.commit09911bf2008-07-26 23:55:29361 IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)
initial.commit09911bf2008-07-26 23:55:29362 IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)
363 IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
364 IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
365 IPC_MESSAGE_HANDLER(ViewMsg_LoadAlternateHTMLText, OnLoadAlternateHTMLText)
366 IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
367 IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)
368 IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)
369 IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)
370 IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)
371 IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)
372 IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)
[email protected]bbbd545c2008-12-15 20:18:04373 IPC_MESSAGE_HANDLER(ViewMsg_ToggleSpellCheck, OnToggleSpellCheck)
initial.commit09911bf2008-07-26 23:55:29374 IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)
375 IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)
376 IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
377 IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
[email protected]630e26b2008-10-14 22:55:17378 IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
[email protected]ea8c7452009-04-02 20:47:06379 IPC_MESSAGE_HANDLER(ViewMsg_InsertText, OnInsertText)
initial.commit09911bf2008-07-26 23:55:29380 IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
381 IPC_MESSAGE_HANDLER(ViewMsg_InspectElement, OnInspectElement)
382 IPC_MESSAGE_HANDLER(ViewMsg_ShowJavaScriptConsole, OnShowJavaScriptConsole)
[email protected]b2abac72009-02-26 12:39:28383 IPC_MESSAGE_HANDLER(ViewMsg_SetupDevToolsClient, OnSetupDevToolsClient)
initial.commit09911bf2008-07-26 23:55:29384 IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)
385 IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
[email protected]1810e132009-03-24 23:35:48386 IPC_MESSAGE_HANDLER(ViewMsg_CSSInsertRequest, OnCSSInsertRequest)
initial.commit09911bf2008-07-26 23:55:29387 IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)
388 IPC_MESSAGE_HANDLER(ViewMsg_DebugAttach, OnDebugAttach)
[email protected]88010e082008-08-29 11:07:40389 IPC_MESSAGE_HANDLER(ViewMsg_DebugDetach, OnDebugDetach)
initial.commit09911bf2008-07-26 23:55:29390 IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)
391 IPC_MESSAGE_HANDLER(ViewMsg_UploadFile, OnUploadFileRequest)
392 IPC_MESSAGE_HANDLER(ViewMsg_FormFill, OnFormFill)
393 IPC_MESSAGE_HANDLER(ViewMsg_FillPasswordForm, OnFillPasswordForm)
394 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)
395 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)
396 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)
397 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)
[email protected]18cb2572008-08-21 20:34:45398 IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)
initial.commit09911bf2008-07-26 23:55:29399 IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)
[email protected]266eb6f2008-09-30 23:56:50400 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved,
401 OnDragSourceEndedOrMoved)
initial.commit09911bf2008-07-26 23:55:29402 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,
403 OnDragSourceSystemDragEnded)
404 IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)
405 IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)
406 IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)
407 IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
408 IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)
409 IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)
410 IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
411 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)
412 IPC_MESSAGE_HANDLER(ViewMsg_UpdateBackForwardListCount,
413 OnUpdateBackForwardListCount)
414 IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,
415 OnGetAllSavableResourceLinksForCurrentPage)
[email protected]f09c7182009-03-10 12:54:04416 IPC_MESSAGE_HANDLER(
417 ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,
418 OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)
initial.commit09911bf2008-07-26 23:55:29419 IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)
[email protected]266eb6f2008-09-30 23:56:50420 IPC_MESSAGE_HANDLER(ViewMsg_GetAccessibilityInfo, OnGetAccessibilityInfo)
421 IPC_MESSAGE_HANDLER(ViewMsg_ClearAccessibilityInfo,
422 OnClearAccessibilityInfo)
initial.commit09911bf2008-07-26 23:55:29423 IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose)
424 IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
425 IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)
[email protected]18cb2572008-08-21 20:34:45426 IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,
427 OnMessageFromExternalHost)
[email protected]0aa55312008-10-17 21:53:08428 IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
429 OnDisassociateFromPopupCount)
[email protected]0ebf3872008-11-07 21:35:03430 IPC_MESSAGE_HANDLER(ViewMsg_AutofillSuggestions,
431 OnReceivedAutofillSuggestions)
[email protected]634a6f92008-12-01 21:39:31432 IPC_MESSAGE_HANDLER(ViewMsg_PopupNotificationVisiblityChanged,
433 OnPopupNotificationVisiblityChanged)
[email protected]30f75e62009-02-25 22:01:00434 IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
[email protected]309d7a282009-03-24 09:18:27435 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionResponse, OnExtensionResponse)
[email protected]05d478752009-04-08 23:38:16436 IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
[email protected]699ab0d2009-04-23 23:19:14437 IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
[email protected]634a6f92008-12-01 21:39:31438
initial.commit09911bf2008-07-26 23:55:29439 // Have the super handle all other messages.
440 IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))
441 IPC_END_MESSAGE_MAP()
442}
443
initial.commit09911bf2008-07-26 23:55:29444void RenderView::SendThumbnail() {
445 WebFrame* main_frame = webview()->GetMainFrame();
446 if (!main_frame)
447 return;
448
449 // get the URL for this page
450 GURL url(main_frame->GetURL());
451 if (url.is_empty())
452 return;
453
454 if (size_.IsEmpty())
455 return; // Don't create an empty thumbnail!
456
457 ThumbnailScore score;
458 SkBitmap thumbnail;
[email protected]b6e4bec2008-11-12 01:17:15459 if (!CaptureThumbnail(main_frame, kThumbnailWidth, kThumbnailHeight,
460 &thumbnail, &score))
461 return;
462
initial.commit09911bf2008-07-26 23:55:29463 // send the thumbnail message to the browser process
[email protected]674741932009-02-04 23:44:46464 Send(new ViewHostMsg_Thumbnail(routing_id_, url, score, thumbnail));
initial.commit09911bf2008-07-26 23:55:29465}
466
initial.commit09911bf2008-07-26 23:55:29467void RenderView::PrintPage(const ViewMsg_PrintPage_Params& params,
[email protected]88a3ecc2009-03-19 17:36:22468 const gfx::Size& canvas_size,
initial.commit09911bf2008-07-26 23:55:29469 WebFrame* frame) {
[email protected]6c8afae52009-01-22 02:24:57470#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29471 // Generate a memory-based EMF file. The EMF will use the current screen's
472 // DPI.
473 gfx::Emf emf;
474
475 emf.CreateDc(NULL, NULL);
476 HDC hdc = emf.hdc();
477 DCHECK(hdc);
[email protected]21f527e2008-12-17 23:29:40478 skia::PlatformDeviceWin::InitializeDC(hdc);
[email protected]0e92fa32009-03-31 20:39:33479 // Since WebKit extends the page width depending on the magical shrink
[email protected]0dea3ea2009-03-31 23:30:59480 // factor we make sure the canvas covers the worst case scenario
[email protected]0e92fa32009-03-31 20:39:33481 // (x2.0 currently). PrintContext will then set the correct clipping region.
482 int size_x = static_cast<int>(canvas_size.width() * params.params.max_shrink);
483 int size_y = static_cast<int>(canvas_size.height() *
484 params.params.max_shrink);
[email protected]88a3ecc2009-03-19 17:36:22485 // Calculate the dpi adjustment.
486 float shrink = static_cast<float>(canvas_size.width()) /
487 params.params.printable_size.width();
initial.commit09911bf2008-07-26 23:55:29488#if 0
489 // TODO(maruel): This code is kept for testing until the 100% GDI drawing
490 // code is stable. maruels use this code's output as a reference when the
491 // GDI drawing code fails.
492
493 // Mix of Skia and GDI based.
[email protected]88a3ecc2009-03-19 17:36:22494 skia::PlatformCanvasWin canvas(size_x, size_y, true);
initial.commit09911bf2008-07-26 23:55:29495 canvas.drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode);
[email protected]88a3ecc2009-03-19 17:36:22496 float webkit_shrink = frame->PrintPage(params.page_number, &canvas);
497 if (shrink <= 0) {
initial.commit09911bf2008-07-26 23:55:29498 NOTREACHED() << "Printing page " << params.page_number << " failed.";
[email protected]88a3ecc2009-03-19 17:36:22499 } else {
500 // Update the dpi adjustment with the "page shrink" calculated in webkit.
501 shrink /= webkit_shrink;
initial.commit09911bf2008-07-26 23:55:29502 }
503
504 // Create a BMP v4 header that we can serialize.
505 BITMAPV4HEADER bitmap_header;
[email protected]88a3ecc2009-03-19 17:36:22506 gfx::CreateBitmapV4Header(size_x, size_y, &bitmap_header);
initial.commit09911bf2008-07-26 23:55:29507 const SkBitmap& src_bmp = canvas.getDevice()->accessBitmap(true);
508 SkAutoLockPixels src_lock(src_bmp);
509 int retval = StretchDIBits(hdc,
510 0,
511 0,
[email protected]88a3ecc2009-03-19 17:36:22512 size_x, size_y,
initial.commit09911bf2008-07-26 23:55:29513 0, 0,
[email protected]88a3ecc2009-03-19 17:36:22514 size_x, size_y,
initial.commit09911bf2008-07-26 23:55:29515 src_bmp.getPixels(),
516 reinterpret_cast<BITMAPINFO*>(&bitmap_header),
517 DIB_RGB_COLORS,
518 SRCCOPY);
519 DCHECK(retval != GDI_ERROR);
520#else
521 // 100% GDI based.
[email protected]88a3ecc2009-03-19 17:36:22522 skia::VectorCanvas canvas(hdc, size_x, size_y);
523 float webkit_shrink = frame->PrintPage(params.page_number, &canvas);
524 if (shrink <= 0) {
initial.commit09911bf2008-07-26 23:55:29525 NOTREACHED() << "Printing page " << params.page_number << " failed.";
[email protected]88a3ecc2009-03-19 17:36:22526 } else {
527 // Update the dpi adjustment with the "page shrink" calculated in webkit.
528 shrink /= webkit_shrink;
initial.commit09911bf2008-07-26 23:55:29529 }
530#endif
531
532 // Done printing. Close the device context to retrieve the compiled EMF.
533 if (!emf.CloseDc()) {
534 NOTREACHED() << "EMF failed";
535 }
536
537 // Get the size of the compiled EMF.
538 unsigned buf_size = emf.GetDataSize();
539 DCHECK(buf_size > 128);
540 ViewHostMsg_DidPrintPage_Params page_params;
541 page_params.data_size = 0;
542 page_params.emf_data_handle = NULL;
543 page_params.page_number = params.page_number;
544 page_params.document_cookie = params.params.document_cookie;
545 page_params.actual_shrink = shrink;
[email protected]176aa482008-11-14 03:25:15546 base::SharedMemory shared_buf;
initial.commit09911bf2008-07-26 23:55:29547
548 // http://msdn2.microsoft.com/en-us/library/ms535522.aspx
549 // Windows 2000/XP: When a page in a spooled file exceeds approximately 350
550 // MB, it can fail to print and not send an error message.
551 if (buf_size < 350*1024*1024) {
552 // Allocate a shared memory buffer to hold the generated EMF data.
553 if (shared_buf.Create(L"", false, false, buf_size) &&
554 shared_buf.Map(buf_size)) {
555 // Copy the bits into shared memory.
556 if (emf.GetData(shared_buf.memory(), buf_size)) {
557 page_params.emf_data_handle = shared_buf.handle();
558 page_params.data_size = buf_size;
559 } else {
560 NOTREACHED() << "GetData() failed";
561 }
562 shared_buf.Unmap();
563 } else {
564 NOTREACHED() << "Buffer allocation failed";
565 }
566 } else {
567 NOTREACHED() << "Buffer too large: " << buf_size;
568 }
569 emf.CloseEmf();
570 if (Send(new ViewHostMsg_DuplicateSection(routing_id_,
571 page_params.emf_data_handle,
572 &page_params.emf_data_handle))) {
573 Send(new ViewHostMsg_DidPrintPage(routing_id_, page_params));
574 }
[email protected]6c8afae52009-01-22 02:24:57575#else // defined(OS_WIN)
576 // TODO(port) implement printing
577 NOTIMPLEMENTED();
578#endif
initial.commit09911bf2008-07-26 23:55:29579}
580
[email protected]068637222009-01-29 16:58:07581void RenderView::OnPrintPages() {
initial.commit09911bf2008-07-26 23:55:29582 DCHECK(webview());
[email protected]068637222009-01-29 16:58:07583 if (webview()) {
584 // The renderer own the control flow as if it was a window.print() call.
585 ScriptedPrint(webview()->GetMainFrame());
initial.commit09911bf2008-07-26 23:55:29586 }
initial.commit09911bf2008-07-26 23:55:29587}
588
589void RenderView::PrintPages(const ViewMsg_PrintPages_Params& params,
590 WebFrame* frame) {
[email protected]88a3ecc2009-03-19 17:36:22591 int page_count = 0;
592 gfx::Size canvas_size;
593 canvas_size.set_width(
594 printing::ConvertUnit(params.params.printable_size.width(),
595 static_cast<int>(params.params.dpi),
596 params.params.desired_dpi));
597 canvas_size.set_height(
598 printing::ConvertUnit(params.params.printable_size.height(),
599 static_cast<int>(params.params.dpi),
600 params.params.desired_dpi));
601 frame->BeginPrint(canvas_size, &page_count);
initial.commit09911bf2008-07-26 23:55:29602 Send(new ViewHostMsg_DidGetPrintedPagesCount(routing_id_,
603 params.params.document_cookie,
[email protected]88a3ecc2009-03-19 17:36:22604 page_count));
605 if (page_count) {
initial.commit09911bf2008-07-26 23:55:29606 ViewMsg_PrintPage_Params page_params;
607 page_params.params = params.params;
608 if (params.pages.empty()) {
[email protected]88a3ecc2009-03-19 17:36:22609 for (int i = 0; i < page_count; ++i) {
initial.commit09911bf2008-07-26 23:55:29610 page_params.page_number = i;
[email protected]88a3ecc2009-03-19 17:36:22611 PrintPage(page_params, canvas_size, frame);
initial.commit09911bf2008-07-26 23:55:29612 }
613 } else {
614 for (size_t i = 0; i < params.pages.size(); ++i) {
615 page_params.page_number = params.pages[i];
[email protected]88a3ecc2009-03-19 17:36:22616 PrintPage(page_params, canvas_size, frame);
initial.commit09911bf2008-07-26 23:55:29617 }
618 }
619 }
[email protected]88a3ecc2009-03-19 17:36:22620 frame->EndPrint();
initial.commit09911bf2008-07-26 23:55:29621}
622
623void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) {
624 if (load_id != page_id_)
625 return; // this capture call is no longer relevant due to navigation
626 if (load_id == last_indexed_page_id_)
627 return; // we already indexed this page
628
629 if (!webview())
630 return;
631
632 WebFrame* main_frame = webview()->GetMainFrame();
633 if (!main_frame)
634 return;
635
636 // Don't index/capture pages that are in view source mode.
637 if (main_frame->GetInViewSourceMode())
638 return;
639
640 // Don't index/capture pages that failed to load. This only checks the top
641 // level frame so the thumbnail may contain a frame that failed to load.
642 WebDataSource* ds = main_frame->GetDataSource();
643 if (ds && ds->HasUnreachableURL())
644 return;
645
646 if (!preliminary_capture)
647 last_indexed_page_id_ = load_id;
648
649 // get the URL for this page
650 GURL url(main_frame->GetURL());
651 if (url.is_empty())
652 return;
653
654 // full text
655 std::wstring contents;
656 CaptureText(main_frame, &contents);
657 if (contents.size()) {
658 // Send the text to the browser for indexing.
659 Send(new ViewHostMsg_PageContents(url, load_id, contents));
660 }
661
662 // thumbnail
663 SendThumbnail();
664}
665
666void RenderView::CaptureText(WebFrame* frame, std::wstring* contents) {
667 contents->clear();
668 if (!frame)
669 return;
670
[email protected]0faf0bd92008-09-09 20:53:27671 // Don't index any https pages. People generally don't want their bank
672 // accounts, etc. indexed on their computer, especially since some of these
673 // things are not marked cachable.
674 // TODO(brettw) we may want to consider more elaborate heuristics such as
675 // the cachability of the page. We may also want to consider subframes (this
676 // test will still index subframes if the subframe is SSL).
677 if (frame->GetURL().SchemeIsSecure())
678 return;
679
initial.commit09911bf2008-07-26 23:55:29680#ifdef TIME_TEXT_RETRIEVAL
681 double begin = time_util::GetHighResolutionTimeNow();
682#endif
683
684 // get the contents of the frame
685 frame->GetContentAsPlainText(kMaxIndexChars, contents);
686
687#ifdef TIME_TEXT_RETRIEVAL
688 double end = time_util::GetHighResolutionTimeNow();
689 char buf[128];
690 sprintf_s(buf, "%d chars retrieved for indexing in %gms\n",
691 contents.size(), (end - begin)*1000);
692 OutputDebugStringA(buf);
693#endif
694
695 // When the contents are clipped to the maximum, we don't want to have a
696 // partial word indexed at the end that might have been clipped. Therefore,
697 // terminate the string at the last space to ensure no words are clipped.
698 if (contents->size() == kMaxIndexChars) {
699 size_t last_space_index = contents->find_last_of(kWhitespaceWide);
700 if (last_space_index == std::wstring::npos)
701 return; // don't index if we got a huge block of text with no spaces
702 contents->resize(last_space_index);
703 }
704}
705
[email protected]b6e4bec2008-11-12 01:17:15706bool RenderView::CaptureThumbnail(WebFrame* frame,
initial.commit09911bf2008-07-26 23:55:29707 int w,
708 int h,
709 SkBitmap* thumbnail,
710 ThumbnailScore* score) {
711#ifdef TIME_BITMAP_RETRIEVAL
712 double begin = time_util::GetHighResolutionTimeNow();
713#endif
714
[email protected]21f527e2008-12-17 23:29:40715 scoped_ptr<skia::BitmapPlatformDevice> device;
[email protected]b6e4bec2008-11-12 01:17:15716 if (!frame->CaptureImage(&device, true))
717 return false;
718
719 const SkBitmap& src_bmp = device->accessBitmap(false);
initial.commit09911bf2008-07-26 23:55:29720
721 SkRect dest_rect;
722 dest_rect.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
723 float dest_aspect = dest_rect.width() / dest_rect.height();
724
725 // Get the src rect so that we can preserve the aspect ratio while filling
726 // the destination.
727 SkIRect src_rect;
728 if (src_bmp.width() < dest_rect.width() ||
729 src_bmp.height() < dest_rect.height()) {
730 // Source image is smaller: we clip the part of source image within the
731 // dest rect, and then stretch it to fill the dest rect. We don't respect
732 // the aspect ratio in this case.
733 src_rect.set(0, 0, static_cast<S16CPU>(dest_rect.width()),
734 static_cast<S16CPU>(dest_rect.height()));
735 score->good_clipping = false;
736 } else {
737 float src_aspect = static_cast<float>(src_bmp.width()) / src_bmp.height();
738 if (src_aspect > dest_aspect) {
739 // Wider than tall, clip horizontally: we center the smaller thumbnail in
740 // the wider screen.
741 S16CPU new_width = static_cast<S16CPU>(src_bmp.height() * dest_aspect);
742 S16CPU x_offset = (src_bmp.width() - new_width) / 2;
743 src_rect.set(x_offset, 0, new_width + x_offset, src_bmp.height());
744 score->good_clipping = false;
745 } else {
746 src_rect.set(0, 0, src_bmp.width(),
747 static_cast<S16CPU>(src_bmp.width() / dest_aspect));
748 score->good_clipping = true;
749 }
750 }
751
[email protected]b3f2b912009-04-09 16:18:52752 score->at_top = (frame->ScrollOffset().height == 0);
initial.commit09911bf2008-07-26 23:55:29753
754 SkBitmap subset;
[email protected]b6e4bec2008-11-12 01:17:15755 device->accessBitmap(false).extractSubset(&subset, src_rect);
initial.commit09911bf2008-07-26 23:55:29756
757 // Resample the subset that we want to get it the right size.
[email protected]465b34b72008-12-12 20:19:14758 *thumbnail = skia::ImageOperations::Resize(
759 subset, skia::ImageOperations::RESIZE_LANCZOS3, w, h);
initial.commit09911bf2008-07-26 23:55:29760
761 score->boring_score = CalculateBoringScore(thumbnail);
762
763#ifdef TIME_BITMAP_RETRIEVAL
764 double end = time_util::GetHighResolutionTimeNow();
765 char buf[128];
766 sprintf_s(buf, "thumbnail in %gms\n", (end - begin) * 1000);
767 OutputDebugStringA(buf);
768#endif
[email protected]b6e4bec2008-11-12 01:17:15769 return true;
initial.commit09911bf2008-07-26 23:55:29770}
771
772double RenderView::CalculateBoringScore(SkBitmap* bitmap) {
773 int histogram[256] = {0};
774 color_utils::BuildLumaHistogram(bitmap, histogram);
775
776 int color_count = *std::max_element(histogram, histogram + 256);
777 int pixel_count = bitmap->width() * bitmap->height();
778 return static_cast<double>(color_count) / pixel_count;
779}
780
781void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {
782 if (!webview())
783 return;
784
[email protected]f8b6b6f2009-03-10 16:48:26785 renderer_logging::ScopedActiveRenderingURLSetter url_setter(params.url);
[email protected]f8b6b6f2009-03-10 16:48:26786
initial.commit09911bf2008-07-26 23:55:29787 AboutHandler::MaybeHandle(params.url);
788
789 bool is_reload = params.reload;
790
791 WebFrame* main_frame = webview()->GetMainFrame();
[email protected]606843fa2008-12-02 19:08:56792 if (is_reload && !main_frame->HasCurrentHistoryState()) {
initial.commit09911bf2008-07-26 23:55:29793 // We cannot reload if we do not have any history state. This happens, for
794 // example, when recovering from a crash. Our workaround here is a bit of
795 // a hack since it means that reload after a crashed tab does not cause an
796 // end-to-end cache validation.
797 is_reload = false;
798 }
799
800 WebRequestCachePolicy cache_policy;
801 if (is_reload) {
802 cache_policy = WebRequestReloadIgnoringCacheData;
803 } else if (params.page_id != -1 || main_frame->GetInViewSourceMode()) {
804 cache_policy = WebRequestReturnCacheDataElseLoad;
805 } else {
806 cache_policy = WebRequestUseProtocolCachePolicy;
807 }
808
809 scoped_ptr<WebRequest> request(WebRequest::Create(params.url));
810 request->SetCachePolicy(cache_policy);
811 request->SetExtraData(new RenderViewExtraRequestData(
[email protected]c20210e62009-04-03 21:39:26812 params.page_id, params.transition, params.request_time));
initial.commit09911bf2008-07-26 23:55:29813
814 // If we are reloading, then WebKit will use the state of the current page.
815 // Otherwise, we give it the state to navigate to.
816 if (!is_reload)
817 request->SetHistoryState(params.state);
818
[email protected]4c6f2c92008-10-28 20:26:15819 if (params.referrer.is_valid()) {
[email protected]8e3c1a72008-11-25 01:13:32820 request->SetHttpHeaderValue("Referer",
821 params.referrer.spec());
[email protected]c0588052008-10-27 23:01:50822 }
823
initial.commit09911bf2008-07-26 23:55:29824 main_frame->LoadRequest(request.get());
825}
826
827// Stop loading the current page
828void RenderView::OnStop() {
829 if (webview())
830 webview()->StopLoading();
831}
832
833void RenderView::OnLoadAlternateHTMLText(const std::string& html_contents,
834 bool new_navigation,
835 const GURL& display_url,
836 const std::string& security_info) {
837 if (!webview())
838 return;
839
840 scoped_ptr<WebRequest> request(WebRequest::Create(
841 GURL(kUnreachableWebDataURL)));
842 request->SetSecurityInfo(security_info);
843
844 webview()->GetMainFrame()->LoadAlternateHTMLString(request.get(),
845 html_contents,
846 display_url,
847 !new_navigation);
848}
849
850void RenderView::OnCopyImageAt(int x, int y) {
851 webview()->CopyImageAt(x, y);
852}
853
854void RenderView::OnInspectElement(int x, int y) {
855 webview()->InspectElement(x, y);
856}
857
858void RenderView::OnShowJavaScriptConsole() {
859 webview()->ShowJavaScriptConsole();
860}
861
[email protected]b2abac72009-02-26 12:39:28862void RenderView::OnSetupDevToolsClient() {
[email protected]e4ac5df2009-03-17 15:33:11863 DCHECK(!devtools_client_.get());
864 devtools_client_.reset(new DevToolsClient(this));
[email protected]b2abac72009-02-26 12:39:28865}
866
initial.commit09911bf2008-07-26 23:55:29867void RenderView::OnStopFinding(bool clear_selection) {
868 WebView* view = webview();
869 if (!view)
870 return;
871
872 if (clear_selection)
873 view->GetFocusedFrame()->ClearSelection();
874
875 WebFrame* frame = view->GetMainFrame();
876 while (frame) {
[email protected]65134c432008-09-26 21:47:20877 frame->StopFinding(clear_selection);
initial.commit09911bf2008-07-26 23:55:29878 frame = view->GetNextFrameAfter(frame, false);
879 }
880}
881
882void RenderView::OnFindReplyAck() {
883 // Check if there is any queued up request waiting to be sent.
884 if (queued_find_reply_message_.get()) {
885 // Send the search result over to the browser process.
886 Send(queued_find_reply_message_.get());
887 queued_find_reply_message_.release();
888 }
889}
890
891void RenderView::OnUpdateTargetURLAck() {
892 // Check if there is a targeturl waiting to be sent.
893 if (target_url_status_ == TARGET_PENDING) {
894 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_,
895 pending_target_url_));
896 }
897
898 target_url_status_ = TARGET_NONE;
899}
900
901void RenderView::OnUndo() {
902 if (!webview())
903 return;
904
905 webview()->GetFocusedFrame()->Undo();
906}
907
908void RenderView::OnRedo() {
909 if (!webview())
910 return;
911
912 webview()->GetFocusedFrame()->Redo();
913}
914
915void RenderView::OnCut() {
916 if (!webview())
917 return;
918
919 webview()->GetFocusedFrame()->Cut();
920}
921
922void RenderView::OnCopy() {
923 if (!webview())
924 return;
925
926 webview()->GetFocusedFrame()->Copy();
927}
928
929void RenderView::OnPaste() {
930 if (!webview())
931 return;
932
933 webview()->GetFocusedFrame()->Paste();
934}
935
936void RenderView::OnReplace(const std::wstring& text) {
937 if (!webview())
938 return;
939
940 webview()->GetFocusedFrame()->Replace(text);
941}
942
[email protected]bbbd545c2008-12-15 20:18:04943void RenderView::OnToggleSpellCheck() {
944 if (!webview())
945 return;
946
947 webview()->GetFocusedFrame()->ToggleSpellCheck();
948}
949
initial.commit09911bf2008-07-26 23:55:29950void RenderView::OnDelete() {
951 if (!webview())
952 return;
953
954 webview()->GetFocusedFrame()->Delete();
955}
956
957void RenderView::OnSelectAll() {
958 if (!webview())
959 return;
960
961 webview()->GetFocusedFrame()->SelectAll();
962}
963
964void RenderView::OnSetInitialFocus(bool reverse) {
965 if (!webview())
966 return;
967 webview()->SetInitialFocus(reverse);
968}
969
970///////////////////////////////////////////////////////////////////////////////
971
972// Tell the embedding application that the URL of the active page has changed
973void RenderView::UpdateURL(WebFrame* frame) {
974 WebDataSource* ds = frame->GetDataSource();
975 DCHECK(ds);
976
977 const WebRequest& request = ds->GetRequest();
978 const WebRequest& initial_request = ds->GetInitialRequest();
979 const WebResponse& response = ds->GetResponse();
980
981 // We don't hold a reference to the extra data. The request's reference will
982 // be sufficient because we won't modify it during our call. MAY BE NULL.
983 RenderViewExtraRequestData* extra_data =
984 static_cast<RenderViewExtraRequestData*>(request.GetExtraData());
985
986 ViewHostMsg_FrameNavigate_Params params;
[email protected]2e39d2e2009-02-19 18:41:31987 params.http_status_code = response.GetHttpStatusCode();
initial.commit09911bf2008-07-26 23:55:29988 params.is_post = false;
989 params.page_id = page_id_;
[email protected]8a3422c92008-09-24 17:42:42990 params.is_content_filtered = response.IsContentFiltered();
initial.commit09911bf2008-07-26 23:55:29991 if (!request.GetSecurityInfo().empty()) {
992 // SSL state specified in the request takes precedence over the one in the
993 // response.
994 // So far this is only intended for error pages that are not expected to be
995 // over ssl, so we should not get any clash.
996 DCHECK(response.GetSecurityInfo().empty());
997 params.security_info = request.GetSecurityInfo();
998 } else {
999 params.security_info = response.GetSecurityInfo();
1000 }
1001
1002 // Set the URL to be displayed in the browser UI to the user.
1003 if (ds->HasUnreachableURL()) {
1004 params.url = ds->GetUnreachableURL();
1005 } else {
1006 params.url = request.GetURL();
1007 }
1008
1009 params.redirects = ds->GetRedirectChain();
1010 params.should_update_history = !ds->HasUnreachableURL();
1011
1012 const SearchableFormData* searchable_form_data =
1013 frame->GetDataSource()->GetSearchableFormData();
1014 if (searchable_form_data) {
1015 params.searchable_form_url = searchable_form_data->url();
1016 params.searchable_form_element_name = searchable_form_data->element_name();
1017 params.searchable_form_encoding = searchable_form_data->encoding();
1018 }
1019
1020 const PasswordForm* password_form_data =
1021 frame->GetDataSource()->GetPasswordFormData();
1022 if (password_form_data)
1023 params.password_form = *password_form_data;
1024
1025 params.gesture = navigation_gesture_;
1026 navigation_gesture_ = NavigationGestureUnknown;
1027
1028 if (webview()->GetMainFrame() == frame) {
1029 // Top-level navigation.
1030
1031 // Update contents MIME type for main frame.
[email protected]9d806f52009-03-12 22:50:541032 params.contents_mime_type = ds->GetResponse().GetMimeType();
initial.commit09911bf2008-07-26 23:55:291033
1034 // We assume top level navigations initiated by the renderer are link
1035 // clicks.
1036 params.transition = extra_data ?
1037 extra_data->transition_type : PageTransition::LINK;
1038 if (!PageTransition::IsMainFrame(params.transition)) {
1039 // If the main frame does a load, it should not be reported as a subframe
1040 // navigation. This can occur in the following case:
1041 // 1. You're on a site with frames.
1042 // 2. You do a subframe navigation. This is stored with transition type
1043 // MANUAL_SUBFRAME.
1044 // 3. You navigate to some non-frame site, say, google.com.
1045 // 4. You navigate back to the page from step 2. Since it was initially
1046 // MANUAL_SUBFRAME, it will be that same transition type here.
1047 // We don't want that, because any navigation that changes the toplevel
1048 // frame should be tracked as a toplevel navigation (this allows us to
1049 // update the URL bar, etc).
1050 params.transition = PageTransition::LINK;
1051 }
1052
1053 if (params.transition == PageTransition::LINK &&
1054 frame->GetDataSource()->IsFormSubmit()) {
1055 params.transition = PageTransition::FORM_SUBMIT;
1056 }
1057
1058 // If we have a valid consumed client redirect source,
1059 // the page contained a client redirect (meta refresh, document.loc...),
1060 // so we set the referrer and transition to match.
1061 if (completed_client_redirect_src_.is_valid()) {
[email protected]77e09a92008-08-01 18:11:041062 DCHECK(completed_client_redirect_src_ == params.redirects[0]);
initial.commit09911bf2008-07-26 23:55:291063 params.referrer = completed_client_redirect_src_;
1064 params.transition = static_cast<PageTransition::Type>(
1065 params.transition | PageTransition::CLIENT_REDIRECT);
1066 } else {
1067 // Bug 654101: the referrer will be empty on https->http transitions. It
1068 // would be nice if we could get the real referrer from somewhere.
1069 params.referrer = GURL(initial_request.GetHttpReferrer());
1070 }
1071
[email protected]8e3c1a72008-11-25 01:13:321072 std::string method = request.GetHttpMethod();
1073 if (method == "POST")
initial.commit09911bf2008-07-26 23:55:291074 params.is_post = true;
1075
1076 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
1077 } else {
1078 // Subframe navigation: the type depends on whether this navigation
1079 // generated a new session history entry. When they do generate a session
1080 // history entry, it means the user initiated the navigation and we should
1081 // mark it as such. This test checks if this is the first time UpdateURL
1082 // has been called since WillNavigateToURL was called to initiate the load.
1083 if (page_id_ > last_page_id_sent_to_browser_)
1084 params.transition = PageTransition::MANUAL_SUBFRAME;
1085 else
1086 params.transition = PageTransition::AUTO_SUBFRAME;
1087
1088 // The browser should never initiate a subframe navigation.
1089 DCHECK(!extra_data);
1090 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
1091 }
1092
1093 last_page_id_sent_to_browser_ =
1094 std::max(last_page_id_sent_to_browser_, page_id_);
1095
1096 // If we end up reusing this WebRequest (for example, due to a #ref click),
1097 // we don't want the transition type to persist.
1098 if (extra_data)
1099 extra_data->transition_type = PageTransition::LINK; // Just clear it.
[email protected]266eb6f2008-09-30 23:56:501100
[email protected]6c8afae52009-01-22 02:24:571101#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:251102 if (web_accessibility_manager_.get()) {
[email protected]be645db2009-02-06 20:36:331103 // Clear accessibility info cache.
[email protected]6a983b42009-03-20 20:12:251104 web_accessibility_manager_->ClearAccObjMap(-1, true);
[email protected]266eb6f2008-09-30 23:56:501105 }
[email protected]6c8afae52009-01-22 02:24:571106#else
[email protected]7d926f92009-03-03 14:26:541107 // TODO(port): accessibility not yet implemented. See http://crbug.com/8288.
[email protected]6c8afae52009-01-22 02:24:571108#endif
initial.commit09911bf2008-07-26 23:55:291109}
1110
1111// Tell the embedding application that the title of the active page has changed
1112void RenderView::UpdateTitle(WebFrame* frame, const std::wstring& title) {
1113 // Ignore all but top level navigations...
1114 if (webview()->GetMainFrame() == frame)
1115 Send(new ViewHostMsg_UpdateTitle(routing_id_, page_id_, title));
1116}
1117
1118void RenderView::UpdateEncoding(WebFrame* frame,
[email protected]e38f40152008-09-12 23:08:301119 const std::wstring& encoding_name) {
initial.commit09911bf2008-07-26 23:55:291120 // Only update main frame's encoding_name.
1121 if (webview()->GetMainFrame() == frame &&
1122 last_encoding_name_ != encoding_name) {
[email protected]e38f40152008-09-12 23:08:301123 // Save the encoding name for later comparing.
initial.commit09911bf2008-07-26 23:55:291124 last_encoding_name_ = encoding_name;
1125
[email protected]e38f40152008-09-12 23:08:301126 Send(new ViewHostMsg_UpdateEncoding(routing_id_, last_encoding_name_));
initial.commit09911bf2008-07-26 23:55:291127 }
1128}
1129
[email protected]f4d34b52008-11-24 23:05:011130// Sends the previous session history state to the browser so it will be saved
1131// before we navigate to a new page. This must be called *before* the page ID
1132// has been updated so we know what it was.
initial.commit09911bf2008-07-26 23:55:291133void RenderView::UpdateSessionHistory(WebFrame* frame) {
1134 // If we have a valid page ID at this point, then it corresponds to the page
1135 // we are navigating away from. Otherwise, this is the first navigation, so
1136 // there is no past session history to record.
1137 if (page_id_ == -1)
1138 return;
1139
initial.commit09911bf2008-07-26 23:55:291140 std::string state;
[email protected]606843fa2008-12-02 19:08:561141 if (!webview()->GetMainFrame()->GetPreviousHistoryState(&state))
initial.commit09911bf2008-07-26 23:55:291142 return;
[email protected]606843fa2008-12-02 19:08:561143 Send(new ViewHostMsg_UpdateState(routing_id_, page_id_, state));
initial.commit09911bf2008-07-26 23:55:291144}
1145
1146///////////////////////////////////////////////////////////////////////////////
1147// WebViewDelegate
1148
1149void RenderView::DidStartLoading(WebView* webview) {
1150 if (is_loading_) {
1151 DLOG(WARNING) << "DidStartLoading called while loading";
1152 return;
1153 }
1154
1155 is_loading_ = true;
1156 // Clear the pointer so that we can assign it only when there is an unknown
1157 // plugin on a page.
1158 first_default_plugin_ = NULL;
1159
1160 Send(new ViewHostMsg_DidStartLoading(routing_id_, page_id_));
1161}
1162
1163void RenderView::DidStopLoading(WebView* webview) {
1164 if (!is_loading_) {
1165 DLOG(WARNING) << "DidStopLoading called while not loading";
1166 return;
1167 }
1168
1169 is_loading_ = false;
1170
1171 // NOTE: For now we're doing the safest thing, and sending out notification
1172 // when done loading. This currently isn't an issue as the favicon is only
1173 // displayed when done loading. Ideally we would send notification when
1174 // finished parsing the head, but webkit doesn't support that yet.
1175 // The feed discovery code would also benefit from access to the head.
1176 GURL favicon_url(webview->GetMainFrame()->GetFavIconURL());
1177 if (!favicon_url.is_empty())
1178 Send(new ViewHostMsg_UpdateFavIconURL(routing_id_, page_id_, favicon_url));
1179
1180 AddGURLSearchProvider(webview->GetMainFrame()->GetOSDDURL(),
1181 true); // autodetected
1182
1183 Send(new ViewHostMsg_DidStopLoading(routing_id_, page_id_));
1184
1185 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1186 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo, page_id_,
1187 false),
1188 kDelayForCaptureMs);
1189
1190 // The page is loaded. Try to process the file we need to upload if any.
1191 ProcessPendingUpload();
1192
1193 // Since the page is done loading, we are sure we don't need to try
1194 // again.
1195 ResetPendingUpload();
1196}
1197
1198void RenderView::DidStartProvisionalLoadForFrame(
1199 WebView* webview,
1200 WebFrame* frame,
1201 NavigationGesture gesture) {
[email protected]77e09a92008-08-01 18:11:041202 if (webview->GetMainFrame() == frame) {
initial.commit09911bf2008-07-26 23:55:291203 navigation_gesture_ = gesture;
[email protected]266eb6f2008-09-30 23:56:501204
[email protected]77e09a92008-08-01 18:11:041205 // Make sure redirect tracking state is clear for the new load.
1206 completed_client_redirect_src_ = GURL();
1207 }
initial.commit09911bf2008-07-26 23:55:291208
[email protected]c20210e62009-04-03 21:39:261209 WebDataSource* ds = frame->GetProvisionalDataSource();
1210 if (ds) {
1211 const WebRequest& req = ds->GetRequest();
1212 RenderViewExtraRequestData* extra_data =
1213 static_cast<RenderViewExtraRequestData*>(req.GetExtraData());
1214 if (extra_data) {
1215 ds->SetRequestTime(extra_data->request_time);
1216 }
1217 }
initial.commit09911bf2008-07-26 23:55:291218 Send(new ViewHostMsg_DidStartProvisionalLoadForFrame(
1219 routing_id_, webview->GetMainFrame() == frame,
1220 frame->GetProvisionalDataSource()->GetRequest().GetURL()));
1221}
1222
1223bool RenderView::DidLoadResourceFromMemoryCache(WebView* webview,
1224 const WebRequest& request,
1225 const WebResponse& response,
1226 WebFrame* frame) {
1227 // Let the browser know we loaded a resource from the memory cache. This
1228 // message is needed to display the correct SSL indicators.
1229 Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(routing_id_,
[email protected]ffc45862009-03-17 06:11:081230 request.GetURL(), frame->GetSecurityOrigin(),
1231 frame->GetTop()->GetSecurityOrigin(),
1232 response.GetSecurityInfo()));
initial.commit09911bf2008-07-26 23:55:291233
1234 return false;
1235}
1236
1237void RenderView::DidReceiveProvisionalLoadServerRedirect(WebView* webview,
1238 WebFrame* frame) {
1239 if (frame == webview->GetMainFrame()) {
1240 // Received a redirect on the main frame.
1241 WebDataSource* data_source =
1242 webview->GetMainFrame()->GetProvisionalDataSource();
1243 if (!data_source) {
1244 // Should only be invoked when we have a data source.
1245 NOTREACHED();
1246 return;
1247 }
1248 const std::vector<GURL>& redirects = data_source->GetRedirectChain();
1249 if (redirects.size() >= 2) {
1250 Send(new ViewHostMsg_DidRedirectProvisionalLoad(
1251 routing_id_, page_id_, redirects[redirects.size() - 2],
1252 redirects[redirects.size() - 1]));
1253 }
1254 }
1255}
1256
1257void RenderView::DidFailProvisionalLoadWithError(WebView* webview,
1258 const WebError& error,
1259 WebFrame* frame) {
1260 // Notify the browser that we failed a provisional load with an error.
1261 //
1262 // Note: It is important this notification occur before DidStopLoading so the
1263 // SSL manager can react to the provisional load failure before being
1264 // notified the load stopped.
1265 //
1266 WebDataSource* ds = frame->GetProvisionalDataSource();
1267 DCHECK(ds);
1268
1269 const WebRequest& failed_request = ds->GetRequest();
1270
1271 bool show_repost_interstitial =
1272 (error.GetErrorCode() == net::ERR_CACHE_MISS &&
1273 LowerCaseEqualsASCII(failed_request.GetHttpMethod(), "post"));
1274 Send(new ViewHostMsg_DidFailProvisionalLoadWithError(
1275 routing_id_, frame == webview->GetMainFrame(),
1276 error.GetErrorCode(), error.GetFailedURL(),
1277 show_repost_interstitial));
1278
initial.commit09911bf2008-07-26 23:55:291279 // Don't display an error page if this is simply a cancelled load. Aside
1280 // from being dumb, WebCore doesn't expect it and it will cause a crash.
1281 if (error.GetErrorCode() == net::ERR_ABORTED)
1282 return;
1283
1284 // If this is a failed back/forward/reload navigation, then we need to do a
1285 // 'replace' load. This is necessary to avoid messing up session history.
1286 // Otherwise, we do a normal load, which simulates a 'go' navigation as far
1287 // as session history is concerned.
1288 RenderViewExtraRequestData* extra_data =
1289 static_cast<RenderViewExtraRequestData*>(failed_request.GetExtraData());
1290 bool replace = extra_data && !extra_data->is_new_navigation();
1291
[email protected]5df266ac2008-10-15 19:50:131292 // Use the alternate error page service if this is a DNS failure or
1293 // connection failure. ERR_CONNECTION_FAILED can be dropped once we no longer
1294 // use winhttp.
1295 int ec = error.GetErrorCode();
1296 if (ec == net::ERR_NAME_NOT_RESOLVED ||
1297 ec == net::ERR_CONNECTION_FAILED ||
1298 ec == net::ERR_CONNECTION_REFUSED ||
1299 ec == net::ERR_ADDRESS_UNREACHABLE ||
1300 ec == net::ERR_TIMED_OUT) {
1301 const GURL& failed_url = error.GetFailedURL();
1302 const GURL& error_page_url = GetAlternateErrorPageURL(failed_url,
1303 ec == net::ERR_NAME_NOT_RESOLVED ? WebViewDelegate::DNS_ERROR
1304 : WebViewDelegate::CONNECTION_ERROR);
1305 if (error_page_url.is_valid()) {
1306 // Ask the WebFrame to fetch the alternate error page for us.
1307 frame->LoadAlternateHTMLErrorPage(&failed_request, error, error_page_url,
1308 replace, GURL(kUnreachableWebDataURL));
1309 return;
1310 }
initial.commit09911bf2008-07-26 23:55:291311 }
[email protected]5df266ac2008-10-15 19:50:131312
[email protected]be645db2009-02-06 20:36:331313 // Fallback to a local error page.
[email protected]5df266ac2008-10-15 19:50:131314 LoadNavigationErrorPage(frame, &failed_request, error, std::string(),
1315 replace);
initial.commit09911bf2008-07-26 23:55:291316}
1317
1318void RenderView::LoadNavigationErrorPage(WebFrame* frame,
1319 const WebRequest* failed_request,
1320 const WebError& error,
1321 const std::string& html,
1322 bool replace) {
1323 const GURL& failed_url = error.GetFailedURL();
1324
1325 std::string alt_html;
1326 if (html.empty()) {
1327 // Use a local error page.
1328 int resource_id;
1329 DictionaryValue error_strings;
1330 if (error.GetErrorCode() == net::ERR_CACHE_MISS &&
1331 LowerCaseEqualsASCII(failed_request->GetHttpMethod(), "post")) {
1332 GetFormRepostErrorValues(failed_url, &error_strings);
1333 resource_id = IDR_ERROR_NO_DETAILS_HTML;
1334 } else {
1335 GetLocalizedErrorValues(error, &error_strings);
1336 resource_id = IDR_NET_ERROR_HTML;
1337 }
[email protected]8e50b602009-03-03 22:59:431338 error_strings.SetString(L"textdirection",
1339 (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) ?
1340 L"rtl" : L"ltr");
initial.commit09911bf2008-07-26 23:55:291341
1342 alt_html = GetAltHTMLForTemplate(error_strings, resource_id);
1343 } else {
1344 alt_html = html;
1345 }
1346
1347 // Use a data: URL as the site URL to prevent against XSS attacks.
1348 scoped_ptr<WebRequest> request(failed_request->Clone());
1349 request->SetURL(GURL(kUnreachableWebDataURL));
1350
1351 frame->LoadAlternateHTMLString(request.get(), alt_html, failed_url,
1352 replace);
1353}
1354
1355void RenderView::DidCommitLoadForFrame(WebView *webview, WebFrame* frame,
1356 bool is_new_navigation) {
1357 const WebRequest& request =
1358 webview->GetMainFrame()->GetDataSource()->GetRequest();
1359 RenderViewExtraRequestData* extra_data =
1360 static_cast<RenderViewExtraRequestData*>(request.GetExtraData());
1361
1362 if (is_new_navigation) {
1363 // When we perform a new navigation, we need to update the previous session
1364 // history entry with state for the page we are leaving.
1365 UpdateSessionHistory(frame);
1366
1367 // We bump our Page ID to correspond with the new session history entry.
1368 page_id_ = next_page_id_++;
1369
1370 MessageLoop::current()->PostDelayedTask(FROM_HERE,
1371 method_factory_.NewRunnableMethod(&RenderView::CapturePageInfo,
1372 page_id_, true),
1373 kDelayForForcedCaptureMs);
1374 } else {
1375 // Inspect the extra_data on the main frame (set in our Navigate method) to
1376 // see if the navigation corresponds to a session history navigation...
1377 // Note: |frame| may or may not be the toplevel frame, but for the case
1378 // of capturing session history, the first committed frame suffices. We
1379 // keep track of whether we've seen this commit before so that only capture
1380 // session history once per navigation.
[email protected]f4d34b52008-11-24 23:05:011381 //
1382 // Note that we need to check if the page ID changed. In the case of a
1383 // reload, the page ID doesn't change, and UpdateSessionHistory gets the
1384 // previous URL and the current page ID, which would be wrong.
initial.commit09911bf2008-07-26 23:55:291385 if (extra_data && !extra_data->is_new_navigation() &&
[email protected]f4d34b52008-11-24 23:05:011386 !extra_data->request_committed &&
1387 page_id_ != extra_data->pending_page_id()) {
initial.commit09911bf2008-07-26 23:55:291388 // This is a successful session history navigation!
1389 UpdateSessionHistory(frame);
initial.commit09911bf2008-07-26 23:55:291390 page_id_ = extra_data->pending_page_id();
1391 }
1392 }
1393
1394 // Remember that we've already processed this request, so we don't update
1395 // the session history again. We do this regardless of whether this is
1396 // a session history navigation, because if we attempted a session history
1397 // navigation without valid HistoryItem state, WebCore will think it is a
1398 // new navigation.
1399 if (extra_data)
1400 extra_data->request_committed = true;
1401
1402 UpdateURL(frame);
1403
1404 // If this committed load was initiated by a client redirect, we're
1405 // at the last stop now, so clear it.
1406 completed_client_redirect_src_ = GURL();
1407
1408 // Check whether we have new encoding name.
1409 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
1410}
1411
1412void RenderView::DidReceiveTitle(WebView* webview,
1413 const std::wstring& title,
1414 WebFrame* frame) {
1415 UpdateTitle(frame, title);
1416
1417 // Also check whether we have new encoding name.
1418 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
1419}
1420
1421void RenderView::DidFinishLoadForFrame(WebView* webview, WebFrame* frame) {
[email protected]c20210e62009-04-03 21:39:261422 if (webview->GetMainFrame() == frame) {
1423 const GURL& url = frame->GetURL();
1424 if (url.SchemeIs("http") || url.SchemeIs("https"))
1425 DumpLoadHistograms();
1426 }
initial.commit09911bf2008-07-26 23:55:291427}
1428
1429void RenderView::DidFailLoadWithError(WebView* webview,
1430 const WebError& error,
1431 WebFrame* frame) {
1432}
1433
1434void RenderView::DidFinishDocumentLoadForFrame(WebView* webview,
1435 WebFrame* frame) {
1436 // Check whether we have new encoding name.
1437 UpdateEncoding(frame, webview->GetMainFrameEncodingName());
[email protected]1e0f70402008-10-16 23:57:471438
[email protected]8930d472009-02-21 08:05:281439 if (RenderThread::current()) // Will be NULL during unit tests.
1440 RenderThread::current()->user_script_slave()->InjectScripts(
[email protected]0afe8272009-02-14 04:15:161441 frame, UserScript::DOCUMENT_END);
initial.commit09911bf2008-07-26 23:55:291442}
1443
1444void RenderView::DidHandleOnloadEventsForFrame(WebView* webview,
1445 WebFrame* frame) {
1446}
1447
1448void RenderView::DidChangeLocationWithinPageForFrame(WebView* webview,
1449 WebFrame* frame,
1450 bool is_new_navigation) {
1451 DidCommitLoadForFrame(webview, frame, is_new_navigation);
[email protected]9d806f52009-03-12 22:50:541452 const string16& title =
[email protected]de56f3782008-10-01 22:31:351453 webview->GetMainFrame()->GetDataSource()->GetPageTitle();
[email protected]9d806f52009-03-12 22:50:541454 UpdateTitle(frame, UTF16ToWideHack(title));
initial.commit09911bf2008-07-26 23:55:291455}
1456
1457void RenderView::DidReceiveIconForFrame(WebView* webview,
1458 WebFrame* frame) {
1459}
1460
1461void RenderView::WillPerformClientRedirect(WebView* webview,
1462 WebFrame* frame,
1463 const GURL& src_url,
1464 const GURL& dest_url,
1465 unsigned int delay_seconds,
1466 unsigned int fire_date) {
1467}
1468
1469void RenderView::DidCancelClientRedirect(WebView* webview,
1470 WebFrame* frame) {
1471}
1472
[email protected]309d7a282009-03-24 09:18:271473void RenderView::WillCloseFrame(WebView* view, WebFrame* frame) {
1474 // Remove all the pending extension callbacks for this frame.
1475 if (pending_extension_callbacks_.IsEmpty())
1476 return;
1477
1478 std::vector<int> orphaned_callbacks;
1479 for (IDMap<WebFrame>::const_iterator iter =
1480 pending_extension_callbacks_.begin();
1481 iter != pending_extension_callbacks_.end(); ++iter) {
1482 if (iter->second == frame)
1483 orphaned_callbacks.push_back(iter->first);
1484 }
1485
1486 for (std::vector<int>::const_iterator iter = orphaned_callbacks.begin();
1487 iter != orphaned_callbacks.end(); ++iter) {
1488 pending_extension_callbacks_.Remove(*iter);
1489 }
1490}
1491
initial.commit09911bf2008-07-26 23:55:291492void RenderView::DidCompleteClientRedirect(WebView* webview,
1493 WebFrame* frame,
1494 const GURL& source) {
1495 if (webview->GetMainFrame() == frame)
1496 completed_client_redirect_src_ = source;
1497}
1498
[email protected]5b35a6b2009-03-16 19:58:081499void RenderView::WillSendRequest(WebView* webview,
1500 uint32 identifier,
1501 WebRequest* request) {
1502 request->SetRequestorID(routing_id_);
1503}
1504
initial.commit09911bf2008-07-26 23:55:291505void RenderView::BindDOMAutomationController(WebFrame* webframe) {
1506 dom_automation_controller_.set_message_sender(this);
1507 dom_automation_controller_.set_routing_id(routing_id_);
1508 dom_automation_controller_.BindToJavascript(webframe,
1509 L"domAutomationController");
1510}
1511
1512void RenderView::WindowObjectCleared(WebFrame* webframe) {
1513 external_js_object_.set_render_view(this);
1514 external_js_object_.BindToJavascript(webframe, L"external");
[email protected]81e63782009-02-27 19:35:091515 if (BindingsPolicy::is_dom_automation_enabled(enabled_bindings_))
initial.commit09911bf2008-07-26 23:55:291516 BindDOMAutomationController(webframe);
[email protected]81e63782009-02-27 19:35:091517 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_)) {
initial.commit09911bf2008-07-26 23:55:291518 dom_ui_bindings_.set_message_sender(this);
1519 dom_ui_bindings_.set_routing_id(routing_id_);
1520 dom_ui_bindings_.BindToJavascript(webframe, L"chrome");
1521 }
[email protected]81e63782009-02-27 19:35:091522 if (BindingsPolicy::is_external_host_enabled(enabled_bindings_)) {
[email protected]18cb2572008-08-21 20:34:451523 external_host_bindings_.set_message_sender(this);
1524 external_host_bindings_.set_routing_id(routing_id_);
1525 external_host_bindings_.BindToJavascript(webframe, L"externalHost");
1526 }
initial.commit09911bf2008-07-26 23:55:291527}
1528
[email protected]0afe8272009-02-14 04:15:161529void RenderView::DocumentElementAvailable(WebFrame* frame) {
[email protected]4b8323b2009-04-17 18:45:441530 // TODO(mpcomplete): remove this before Chrome extensions ship.
1531 // HACK. This is a temporary workaround to allow cross-origin XHR for Chrome
1532 // extensions. It grants full access to every origin, when we really want
1533 // to be able to restrict them more specifically.
[email protected]d959ce22009-04-15 21:03:421534 if (frame->GetURL().SchemeIs(chrome::kExtensionScheme))
[email protected]4b8323b2009-04-17 18:45:441535 frame->GrantUniversalAccess();
[email protected]d959ce22009-04-15 21:03:421536
[email protected]8930d472009-02-21 08:05:281537 if (RenderThread::current()) // Will be NULL during unit tests.
1538 RenderThread::current()->user_script_slave()->InjectScripts(
[email protected]0afe8272009-02-14 04:15:161539 frame, UserScript::DOCUMENT_START);
1540}
1541
initial.commit09911bf2008-07-26 23:55:291542WindowOpenDisposition RenderView::DispositionForNavigationAction(
1543 WebView* webview,
1544 WebFrame* frame,
1545 const WebRequest* request,
1546 WebNavigationType type,
1547 WindowOpenDisposition disposition,
1548 bool is_redirect) {
1549 // Webkit is asking whether to navigate to a new URL.
1550 // This is fine normally, except if we're showing UI from one security
1551 // context and they're trying to navigate to a different context.
1552 const GURL& url = request->GetURL();
1553 // We only care about navigations that are within the current tab (as opposed
1554 // to, for example, opening a new window).
1555 // But we sometimes navigate to about:blank to clear a tab, and we want to
1556 // still allow that.
[email protected]6de74452009-02-25 18:04:591557 if (disposition == CURRENT_TAB && !(url.SchemeIs(chrome::kAboutScheme))) {
initial.commit09911bf2008-07-26 23:55:291558 // GetExtraData is NULL when we did not issue the request ourselves (see
1559 // OnNavigate), and so such a request may correspond to a link-click,
1560 // script, or drag-n-drop initiated navigation.
1561 if (frame == webview->GetMainFrame() && !request->GetExtraData()) {
1562 // When we received such unsolicited navigations, we sometimes want to
1563 // punt them up to the browser to handle.
[email protected]81e63782009-02-27 19:35:091564 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_) ||
initial.commit09911bf2008-07-26 23:55:291565 frame->GetInViewSourceMode() ||
[email protected]6de74452009-02-25 18:04:591566 url.SchemeIs(chrome::kViewSourceScheme)) {
[email protected]c0588052008-10-27 23:01:501567 OpenURL(webview, url, GURL(), disposition);
initial.commit09911bf2008-07-26 23:55:291568 return IGNORE_ACTION; // Suppress the load here.
[email protected]50b691c2008-10-31 19:08:351569 } else if (url.SchemeIs(kBackForwardNavigationScheme)) {
1570 std::string offset_str = url.ExtractFileName();
1571 int offset;
1572 if (StringToInt(offset_str, &offset)) {
[email protected]0c0383772008-11-04 00:48:311573 GoToEntryAtOffset(offset);
[email protected]50b691c2008-10-31 19:08:351574 return IGNORE_ACTION; // The browser process handles this one.
1575 }
initial.commit09911bf2008-07-26 23:55:291576 }
1577 }
1578 }
1579
1580 // Detect when a page is "forking" a new tab that can be safely rendered in
1581 // its own process. This is done by sites like Gmail that try to open links
1582 // in new windows without script connections back to the original page. We
1583 // treat such cases as browser navigations (in which we will create a new
1584 // renderer for a cross-site navigation), rather than WebKit navigations.
1585 //
1586 // We use the following heuristic to decide whether to fork a new page in its
1587 // own process:
1588 // The parent page must open a new tab to about:blank, set the new tab's
1589 // window.opener to null, and then redirect the tab to a cross-site URL using
1590 // JavaScript.
1591 bool is_fork =
1592 // Must start from a tab showing about:blank, which is later redirected.
[email protected]6aad4bd2009-02-26 22:55:171593 frame->GetURL() == GURL("about:blank") &&
initial.commit09911bf2008-07-26 23:55:291594 // Must be the first real navigation of the tab.
1595 GetHistoryBackListCount() < 1 &&
1596 GetHistoryForwardListCount() < 1 &&
1597 // The parent page must have set the child's window.opener to null before
1598 // redirecting to the desired URL.
1599 frame->GetOpener() == NULL &&
1600 // Must be a top-level frame.
1601 frame->GetParent() == NULL &&
1602 // Must not have issued the request from this page. GetExtraData is NULL
1603 // when the navigation is being done by something outside the page.
1604 !request->GetExtraData() &&
1605 // Must be targeted at the current tab.
1606 disposition == CURRENT_TAB &&
1607 // Must be a JavaScript navigation, which appears as "other".
1608 type == WebNavigationTypeOther;
1609 if (is_fork) {
1610 // Open the URL via the browser, not via WebKit.
[email protected]c0588052008-10-27 23:01:501611 OpenURL(webview, url, GURL(), disposition);
initial.commit09911bf2008-07-26 23:55:291612 return IGNORE_ACTION;
1613 }
1614
1615 return disposition;
1616}
1617
[email protected]a455d3812009-03-05 20:18:071618void RenderView::RunJavaScriptAlert(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291619 const std::wstring& message) {
[email protected]478ff2ed2009-04-21 23:49:181620 RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptAlert,
initial.commit09911bf2008-07-26 23:55:291621 message,
1622 std::wstring(),
[email protected]a455d3812009-03-05 20:18:071623 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291624 NULL);
1625}
1626
[email protected]a455d3812009-03-05 20:18:071627bool RenderView::RunJavaScriptConfirm(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291628 const std::wstring& message) {
[email protected]478ff2ed2009-04-21 23:49:181629 return RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptConfirm,
initial.commit09911bf2008-07-26 23:55:291630 message,
1631 std::wstring(),
[email protected]a455d3812009-03-05 20:18:071632 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291633 NULL);
1634}
1635
[email protected]a455d3812009-03-05 20:18:071636bool RenderView::RunJavaScriptPrompt(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291637 const std::wstring& message,
1638 const std::wstring& default_value,
1639 std::wstring* result) {
[email protected]478ff2ed2009-04-21 23:49:181640 return RunJavaScriptMessage(MessageBoxFlags::kIsJavascriptPrompt,
initial.commit09911bf2008-07-26 23:55:291641 message,
1642 default_value,
[email protected]a455d3812009-03-05 20:18:071643 webframe->GetURL(),
initial.commit09911bf2008-07-26 23:55:291644 result);
1645}
1646
1647bool RenderView::RunJavaScriptMessage(int type,
1648 const std::wstring& message,
1649 const std::wstring& default_value,
[email protected]a455d3812009-03-05 20:18:071650 const GURL& frame_url,
initial.commit09911bf2008-07-26 23:55:291651 std::wstring* result) {
1652 bool success = false;
1653 std::wstring result_temp;
1654 if (!result)
1655 result = &result_temp;
1656 IPC::SyncMessage* msg = new ViewHostMsg_RunJavaScriptMessage(
[email protected]a455d3812009-03-05 20:18:071657 routing_id_, message, default_value, frame_url, type, &success, result);
initial.commit09911bf2008-07-26 23:55:291658
[email protected]1c4947f2009-01-15 22:25:111659 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291660 Send(msg);
1661
1662 return success;
1663}
1664
1665void RenderView::AddGURLSearchProvider(const GURL& osd_url, bool autodetected) {
1666 if (!osd_url.is_empty())
1667 Send(new ViewHostMsg_PageHasOSDD(routing_id_, page_id_, osd_url,
1668 autodetected));
1669}
1670
[email protected]4604d1f42009-03-13 21:52:321671void RenderView::UpdateFeedList(scoped_refptr<FeedList> feedlist) {
1672 ViewHostMsg_UpdateFeedList_Params params;
1673 params.page_id = page_id_;
1674 params.feedlist = feedlist;
1675 Send(new ViewHostMsg_UpdateFeedList(routing_id_, params));
1676}
1677
[email protected]a455d3812009-03-05 20:18:071678bool RenderView::RunBeforeUnloadConfirm(WebFrame* webframe,
initial.commit09911bf2008-07-26 23:55:291679 const std::wstring& message) {
1680 bool success = false;
1681 // This is an ignored return value, but is included so we can accept the same
1682 // response as RunJavaScriptMessage.
1683 std::wstring ignored_result;
1684 IPC::SyncMessage* msg = new ViewHostMsg_RunBeforeUnloadConfirm(
[email protected]a455d3812009-03-05 20:18:071685 routing_id_, webframe->GetURL(), message, &success, &ignored_result);
initial.commit09911bf2008-07-26 23:55:291686
[email protected]1c4947f2009-01-15 22:25:111687 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291688 Send(msg);
1689
1690 return success;
1691}
1692
[email protected]0ebf3872008-11-07 21:35:031693void RenderView::QueryFormFieldAutofill(const std::wstring& field_name,
1694 const std::wstring& text,
1695 int64 node_id) {
1696 static int message_id_counter = 0;
1697 form_field_autofill_request_id_ = message_id_counter++;
1698 Send(new ViewHostMsg_QueryFormFieldAutofill(routing_id_,
1699 field_name, text,
1700 node_id,
1701 form_field_autofill_request_id_));
1702}
1703
[email protected]4d2b6fb2009-03-20 22:28:171704void RenderView::RemoveStoredAutofillEntry(const std::wstring& name,
1705 const std::wstring& value) {
1706 Send(new ViewHostMsg_RemoveAutofillEntry(routing_id_, name, value));
1707}
1708
[email protected]0ebf3872008-11-07 21:35:031709void RenderView::OnReceivedAutofillSuggestions(
1710 int64 node_id,
1711 int request_id,
[email protected]8d0f15c2008-11-11 01:01:091712 const std::vector<std::wstring>& suggestions,
[email protected]0ebf3872008-11-07 21:35:031713 int default_suggestion_index) {
1714 if (!webview() || request_id != form_field_autofill_request_id_)
1715 return;
1716
1717 webview()->AutofillSuggestionsForNode(node_id, suggestions,
1718 default_suggestion_index);
1719}
1720
[email protected]634a6f92008-12-01 21:39:311721void RenderView::OnPopupNotificationVisiblityChanged(bool visible) {
1722 popup_notification_visible_ = visible;
1723}
1724
initial.commit09911bf2008-07-26 23:55:291725void RenderView::ShowModalHTMLDialog(const GURL& url, int width, int height,
1726 const std::string& json_arguments,
1727 std::string* json_retval) {
1728 IPC::SyncMessage* msg = new ViewHostMsg_ShowModalHTMLDialog(
1729 routing_id_, url, width, height, json_arguments, json_retval);
1730
[email protected]1c4947f2009-01-15 22:25:111731 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291732 Send(msg);
1733}
1734
1735uint32 RenderView::GetCPBrowsingContext() {
1736 uint32 context = 0;
1737 Send(new ViewHostMsg_GetCPBrowsingContext(&context));
1738 return context;
1739}
1740
1741// Tell the browser to display a destination link.
1742void RenderView::UpdateTargetURL(WebView* webview, const GURL& url) {
1743 if (url != target_url_) {
1744 if (target_url_status_ == TARGET_INFLIGHT ||
1745 target_url_status_ == TARGET_PENDING) {
1746 // If we have a request in-flight, save the URL to be sent when we
1747 // receive an ACK to the in-flight request. We can happily overwrite
1748 // any existing pending sends.
1749 pending_target_url_ = url;
1750 target_url_status_ = TARGET_PENDING;
1751 } else {
1752 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_, url));
1753 target_url_ = url;
1754 target_url_status_ = TARGET_INFLIGHT;
1755 }
1756 }
1757}
1758
[email protected]b62d1a8c2009-01-13 23:54:571759void RenderView::RunFileChooser(bool multi_select,
[email protected]b949f1112009-04-12 20:03:081760 const string16& title,
1761 const FilePath& default_filename,
initial.commit09911bf2008-07-26 23:55:291762 WebFileChooserCallback* file_chooser) {
1763 if (file_chooser_.get()) {
1764 // TODO(brettw): bug 1235154: This should be a synchronous message to deal
1765 // with the fact that web pages can programatically trigger this. With the
1766 // asnychronous messages, we can get an additional call when one is pending,
1767 // which this test is for. For now, we just ignore the additional file
1768 // chooser request. WebKit doesn't do anything to expect the callback, so
1769 // we can just ignore calling it.
1770 delete file_chooser;
1771 return;
1772 }
1773 file_chooser_.reset(file_chooser);
[email protected]b62d1a8c2009-01-13 23:54:571774 Send(new ViewHostMsg_RunFileChooser(routing_id_, multi_select, title,
[email protected]b949f1112009-04-12 20:03:081775 default_filename));
initial.commit09911bf2008-07-26 23:55:291776}
1777
1778void RenderView::AddMessageToConsole(WebView* webview,
1779 const std::wstring& message,
1780 unsigned int line_no,
1781 const std::wstring& source_id) {
1782 Send(new ViewHostMsg_AddMessageToConsole(routing_id_, message,
1783 static_cast<int32>(line_no),
1784 source_id));
1785}
1786
1787void RenderView::AddSearchProvider(const std::string& url) {
1788 AddGURLSearchProvider(GURL(url),
1789 false); // not autodetected
1790}
1791
1792void RenderView::DebuggerOutput(const std::wstring& out) {
1793 Send(new ViewHostMsg_DebuggerOutput(routing_id_, out));
1794}
1795
1796WebView* RenderView::CreateWebView(WebView* webview, bool user_gesture) {
[email protected]0aa55312008-10-17 21:53:081797 // Check to make sure we aren't overloading on popups.
1798 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups)
1799 return NULL;
1800
[email protected]634a6f92008-12-01 21:39:311801 // This window can't be closed from a window.close() call until we receive a
1802 // message from the Browser process explicitly allowing it.
1803 popup_notification_visible_ = true;
1804
initial.commit09911bf2008-07-26 23:55:291805 int32 routing_id = MSG_ROUTING_NONE;
[email protected]6c8afae52009-01-22 02:24:571806
[email protected]18bcc3c2009-01-27 21:39:151807 ModalDialogEvent modal_dialog_event;
[email protected]6c8afae52009-01-22 02:24:571808 render_thread_->Send(
[email protected]15787f8f2008-10-17 15:29:031809 new ViewHostMsg_CreateWindow(routing_id_, user_gesture, &routing_id,
1810 &modal_dialog_event));
initial.commit09911bf2008-07-26 23:55:291811 if (routing_id == MSG_ROUTING_NONE) {
initial.commit09911bf2008-07-26 23:55:291812 return NULL;
1813 }
1814
1815 // The WebView holds a reference to this new RenderView
1816 const WebPreferences& prefs = webview->GetPreferences();
[email protected]6c8afae52009-01-22 02:24:571817 base::WaitableEvent* waitable_event = new base::WaitableEvent
1818#if defined(OS_WIN)
[email protected]18bcc3c2009-01-27 21:39:151819 (modal_dialog_event.event);
[email protected]6c8afae52009-01-22 02:24:571820#else
1821 (true, false);
1822#endif
[email protected]81a34412009-01-05 19:17:241823 RenderView* view = RenderView::Create(render_thread_,
[email protected]1c4947f2009-01-15 22:25:111824 NULL, waitable_event, routing_id_,
[email protected]0aa55312008-10-17 21:53:081825 prefs, shared_popup_counter_,
1826 routing_id);
initial.commit09911bf2008-07-26 23:55:291827 view->set_opened_by_user_gesture(user_gesture);
1828
1829 // Copy over the alternate error page URL so we can have alt error pages in
1830 // the new render view (we don't need the browser to send the URL back down).
1831 view->alternate_error_page_url_ = alternate_error_page_url_;
1832
1833 return view->webview();
1834}
1835
[email protected]0ebf3872008-11-07 21:35:031836WebWidget* RenderView::CreatePopupWidget(WebView* webview,
[email protected]cfd727f2009-01-09 20:21:111837 bool activatable) {
[email protected]8085dbc82008-09-26 22:53:441838 RenderWidget* widget = RenderWidget::Create(routing_id_,
[email protected]81a34412009-01-05 19:17:241839 render_thread_,
[email protected]cfd727f2009-01-09 20:21:111840 activatable);
initial.commit09911bf2008-07-26 23:55:291841 return widget->webwidget();
1842}
1843
1844WebPluginDelegate* RenderView::CreatePluginDelegate(
1845 WebView* webview,
1846 const GURL& url,
1847 const std::string& mime_type,
1848 const std::string& clsid,
1849 std::string* actual_mime_type) {
[email protected]ffeba6d2009-04-27 20:43:261850#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]6273e2e72009-04-17 00:13:551851 if (!PluginChannelHost::IsListening())
1852 return NULL;
1853
[email protected]ffeba6d2009-04-27 20:43:261854#if !defined(OS_LINUX) // In-proc plugins aren't supported on Linux.
[email protected]88a1fb47a2009-03-13 00:18:061855 if (RenderProcess::current()->in_process_plugins()) {
[email protected]690a99c2009-01-06 16:48:451856 FilePath path;
[email protected]81a34412009-01-05 19:17:241857 render_thread_->Send(
initial.commit09911bf2008-07-26 23:55:291858 new ViewHostMsg_GetPluginPath(url, mime_type, clsid, &path,
1859 actual_mime_type));
[email protected]690a99c2009-01-06 16:48:451860 if (path.value().empty())
initial.commit09911bf2008-07-26 23:55:291861 return NULL;
1862
1863 std::string mime_type_to_use;
1864 if (actual_mime_type && !actual_mime_type->empty())
1865 mime_type_to_use = *actual_mime_type;
1866 else
1867 mime_type_to_use = mime_type;
1868
[email protected]b94d3322009-02-12 19:49:041869 return WebPluginDelegate::Create(path,
1870 mime_type_to_use,
1871 gfx::NativeViewFromId(host_window_));
initial.commit09911bf2008-07-26 23:55:291872 }
[email protected]ffeba6d2009-04-27 20:43:261873#endif
initial.commit09911bf2008-07-26 23:55:291874
1875 WebPluginDelegateProxy* proxy =
1876 WebPluginDelegateProxy::Create(url, mime_type, clsid, this);
1877 if (!proxy)
1878 return NULL;
1879
1880 // We hold onto the proxy so we can poke it when we are painting. See our
1881 // DidPaint implementation below.
1882 plugin_delegates_.push_back(proxy);
1883
1884 return proxy;
[email protected]6c8afae52009-01-22 02:24:571885#else
[email protected]157e5d22009-04-23 18:43:351886 // TODO(port): Plugins currently not supported
1887 NOTIMPLEMENTED();
1888 return NULL;
[email protected]6c8afae52009-01-22 02:24:571889#endif
initial.commit09911bf2008-07-26 23:55:291890}
1891
[email protected]ec9212f2008-12-18 21:40:361892webkit_glue::WebMediaPlayerDelegate* RenderView::CreateMediaPlayerDelegate() {
[email protected]be645db2009-02-06 20:36:331893#if defined(OS_WIN)
[email protected]d43ed912009-02-03 04:52:531894 return new WebMediaPlayerDelegateImpl(this);
[email protected]be645db2009-02-06 20:36:331895#else
1896 // TODO(port)
1897 NOTIMPLEMENTED();
1898 return NULL;
1899#endif
[email protected]ec9212f2008-12-18 21:40:361900}
1901
initial.commit09911bf2008-07-26 23:55:291902void RenderView::OnMissingPluginStatus(WebPluginDelegate* delegate,
1903 int status) {
[email protected]6c8afae52009-01-22 02:24:571904#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:291905 if (first_default_plugin_ == NULL) {
1906 // Show the InfoBar for the first available plugin.
1907 if (status == default_plugin::MISSING_PLUGIN_AVAILABLE) {
1908 first_default_plugin_ = delegate;
1909 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1910 }
1911 } else {
1912 // Closes the InfoBar if user clicks on the plugin (instead of the InfoBar)
1913 // to start the download/install.
1914 if (status == default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD) {
1915 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1916 }
1917 }
[email protected]6c8afae52009-01-22 02:24:571918#else
1919 // TODO(port): plugins current not supported
1920 NOTIMPLEMENTED();
1921#endif
initial.commit09911bf2008-07-26 23:55:291922}
1923
[email protected]eb47a132009-03-04 00:39:561924WebWorker* RenderView::CreateWebWorker(WebWorkerClient* client) {
1925#if defined(OS_WIN)
[email protected]fd0995032009-03-24 02:01:111926 return new WebWorkerProxy(client, routing_id_);
[email protected]eb47a132009-03-04 00:39:561927#else
1928 // TODO(port): out of process workers
1929 NOTIMPLEMENTED();
1930 return NULL;
1931#endif
1932}
1933
initial.commit09911bf2008-07-26 23:55:291934void RenderView::OpenURL(WebView* webview, const GURL& url,
[email protected]c0588052008-10-27 23:01:501935 const GURL& referrer,
initial.commit09911bf2008-07-26 23:55:291936 WindowOpenDisposition disposition) {
[email protected]c0588052008-10-27 23:01:501937 Send(new ViewHostMsg_OpenURL(routing_id_, url, referrer, disposition));
initial.commit09911bf2008-07-26 23:55:291938}
1939
[email protected]1d522202009-04-04 01:56:421940void RenderView::DidContentsSizeChange(WebWidget* webwidget,
1941 int new_width,
1942 int new_height) {
1943 // TODO(rafaelw): This is a temporary solution. Only the ExtensionView wants
1944 // this notification at the moment. It isn't clean to test for ExtensionView
1945 // by examining the enabled_bindings. This needs to be generalized as it
1946 // becomes clear what extension toolbars need.
1947 if (BindingsPolicy::is_extension_enabled(enabled_bindings_)) {
1948 int width = webview()->GetMainFrame()->GetContentsPreferredWidth();
1949 Send(new ViewHostMsg_DidContentsPreferredWidthChange(routing_id_, width));
1950 }
1951}
1952
initial.commit09911bf2008-07-26 23:55:291953// We are supposed to get a single call to Show for a newly created RenderView
1954// that was created via RenderView::CreateWebView. So, we wait until this
1955// point to dispatch the ShowView message.
1956//
1957// This method provides us with the information about how to display the newly
1958// created RenderView (i.e., as a constrained popup or as a new tab).
1959//
1960void RenderView::Show(WebWidget* webwidget, WindowOpenDisposition disposition) {
1961 DCHECK(!did_show_) << "received extraneous Show call";
1962 DCHECK(opener_id_ != MSG_ROUTING_NONE);
1963
1964 if (did_show_)
1965 return;
1966 did_show_ = true;
1967
1968 // NOTE: initial_pos_ may still have its default values at this point, but
1969 // that's okay. It'll be ignored if disposition is not NEW_POPUP, or the
1970 // browser process will impose a default position otherwise.
1971 Send(new ViewHostMsg_ShowView(
1972 opener_id_, routing_id_, disposition, initial_pos_,
1973 WasOpenedByUserGestureHelper()));
1974}
1975
[email protected]634a6f92008-12-01 21:39:311976void RenderView::CloseWidgetSoon(WebWidget* webwidget) {
1977 if (popup_notification_visible_ == false)
1978 RenderWidget::CloseWidgetSoon(webwidget);
1979}
1980
initial.commit09911bf2008-07-26 23:55:291981void RenderView::RunModal(WebWidget* webwidget) {
1982 DCHECK(did_show_) << "should already have shown the view";
1983
1984 IPC::SyncMessage* msg = new ViewHostMsg_RunModal(routing_id_);
1985
[email protected]1c4947f2009-01-15 22:25:111986 msg->set_pump_messages_event(modal_dialog_event_.get());
initial.commit09911bf2008-07-26 23:55:291987 Send(msg);
1988}
1989
1990void RenderView::SyncNavigationState() {
1991 if (!webview())
1992 return;
1993
initial.commit09911bf2008-07-26 23:55:291994 std::string state;
[email protected]606843fa2008-12-02 19:08:561995 if (!webview()->GetMainFrame()->GetCurrentHistoryState(&state))
initial.commit09911bf2008-07-26 23:55:291996 return;
[email protected]606843fa2008-12-02 19:08:561997 Send(new ViewHostMsg_UpdateState(routing_id_, page_id_, state));
initial.commit09911bf2008-07-26 23:55:291998}
1999
2000void RenderView::ShowContextMenu(WebView* webview,
[email protected]124646932009-01-28 18:39:022001 ContextNode node,
initial.commit09911bf2008-07-26 23:55:292002 int x,
2003 int y,
2004 const GURL& link_url,
2005 const GURL& image_url,
2006 const GURL& page_url,
2007 const GURL& frame_url,
2008 const std::wstring& selection_text,
2009 const std::wstring& misspelled_word,
[email protected]6aa376b2008-09-23 18:49:522010 int edit_flags,
2011 const std::string& security_info) {
[email protected]e09ba552009-02-05 03:26:292012 ContextMenuParams params;
[email protected]124646932009-01-28 18:39:022013 params.node = node;
initial.commit09911bf2008-07-26 23:55:292014 params.x = x;
2015 params.y = y;
2016 params.image_url = image_url;
2017 params.link_url = link_url;
[email protected]e6c79812009-04-22 22:31:422018 params.unfiltered_link_url = link_url;
initial.commit09911bf2008-07-26 23:55:292019 params.page_url = page_url;
2020 params.frame_url = frame_url;
2021 params.selection_text = selection_text;
2022 params.misspelled_word = misspelled_word;
[email protected]be645db2009-02-06 20:36:332023 params.spellcheck_enabled =
[email protected]bbbd545c2008-12-15 20:18:042024 webview->GetFocusedFrame()->SpellCheckEnabled();
initial.commit09911bf2008-07-26 23:55:292025 params.edit_flags = edit_flags;
[email protected]6aa376b2008-09-23 18:49:522026 params.security_info = security_info;
initial.commit09911bf2008-07-26 23:55:292027 Send(new ViewHostMsg_ContextMenu(routing_id_, params));
2028}
2029
[email protected]e80c73b2009-04-07 23:24:582030void RenderView::StartDragging(WebView* webview,
2031 const WebDragData& drag_data) {
2032 Send(new ViewHostMsg_StartDragging(routing_id_, WebDropData(drag_data)));
initial.commit09911bf2008-07-26 23:55:292033}
2034
2035void RenderView::TakeFocus(WebView* webview, bool reverse) {
2036 Send(new ViewHostMsg_TakeFocus(routing_id_, reverse));
2037}
2038
2039void RenderView::DidDownloadImage(int id,
2040 const GURL& image_url,
2041 bool errored,
2042 const SkBitmap& image) {
2043 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, errored,
2044 image));
2045}
2046
2047
2048void RenderView::OnDownloadImage(int id,
2049 const GURL& image_url,
2050 int image_size) {
[email protected]f11ca0732009-04-11 00:09:342051
2052 bool data_image_failed = false;
2053 if (image_url.SchemeIs("data")) {
2054 SkBitmap data_image = ImageFromDataUrl(image_url);
2055 data_image_failed = data_image.empty();
2056 if (!data_image_failed) {
2057 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, false,
2058 data_image));
2059 }
2060 }
2061
2062 if (data_image_failed || !webview()->DownloadImage(id, image_url, image_size))
initial.commit09911bf2008-07-26 23:55:292063 Send(new ViewHostMsg_DidDownloadImage(routing_id_, id, image_url, true,
2064 SkBitmap()));
2065}
2066
[email protected]f11ca0732009-04-11 00:09:342067SkBitmap RenderView::ImageFromDataUrl(const GURL& url) const {
2068 std::string mime_type, char_set, data;
2069 if (net::DataURL::Parse(url, &mime_type, &char_set, &data) && !data.empty()) {
2070 // Decode the favicon using WebKit's image decoder.
2071 webkit_glue::ImageDecoder decoder(gfx::Size(kFavIconSize, kFavIconSize));
2072 const unsigned char* src_data =
2073 reinterpret_cast<const unsigned char*>(&data[0]);
2074
2075 return decoder.Decode(src_data, data.size());
2076 }
2077 return SkBitmap();
2078}
2079
initial.commit09911bf2008-07-26 23:55:292080void RenderView::OnGetApplicationInfo(int page_id) {
2081 webkit_glue::WebApplicationInfo app_info;
2082 if (page_id == page_id_)
2083 webkit_glue::GetApplicationInfo(webview(), &app_info);
2084
2085 // Prune out any data URLs in the set of icons. The browser process expects
2086 // any icon with a data URL to have originated from a favicon. We don't want
2087 // to decode arbitrary data URLs in the browser process. See
2088 // http://b/issue?id=1162972
2089 for (size_t i = 0; i < app_info.icons.size(); ++i) {
[email protected]6de74452009-02-25 18:04:592090 if (app_info.icons[i].url.SchemeIs(chrome::kDataScheme)) {
initial.commit09911bf2008-07-26 23:55:292091 app_info.icons.erase(app_info.icons.begin() + i);
2092 --i;
2093 }
2094 }
2095
2096 Send(new ViewHostMsg_DidGetApplicationInfo(routing_id_, page_id, app_info));
2097}
2098
2099GURL RenderView::GetAlternateErrorPageURL(const GURL& failedURL,
2100 ErrorPageType error_type) {
2101 if (failedURL.SchemeIsSecure()) {
2102 // If the URL that failed was secure, then the embedding web page was not
2103 // expecting a network attacker to be able to manipulate its contents. As
2104 // we fetch alternate error pages over HTTP, we would be allowing a network
2105 // attacker to manipulate the contents of the response if we tried to use
2106 // the link doctor here.
2107 return GURL::EmptyGURL();
2108 }
2109
2110 // Grab the base URL from the browser process.
2111 if (!alternate_error_page_url_.is_valid())
2112 return GURL::EmptyGURL();
2113
2114 // Strip query params from the failed URL.
2115 GURL::Replacements remove_params;
2116 remove_params.ClearUsername();
2117 remove_params.ClearPassword();
2118 remove_params.ClearQuery();
2119 remove_params.ClearRef();
2120 const GURL url_to_send = failedURL.ReplaceComponents(remove_params);
2121
2122 // Construct the query params to send to link doctor.
2123 std::string params(alternate_error_page_url_.query());
2124 params.append("&url=");
2125 params.append(EscapeQueryParamValue(url_to_send.spec()));
2126 params.append("&sourceid=chrome");
2127 params.append("&error=");
2128 switch (error_type) {
2129 case DNS_ERROR:
2130 params.append("dnserror");
2131 break;
2132
2133 case HTTP_404:
2134 params.append("http404");
2135 break;
2136
[email protected]5df266ac2008-10-15 19:50:132137 case CONNECTION_ERROR:
[email protected]e1f934b2009-01-26 20:41:332138 params.append("connectionfailure");
[email protected]5df266ac2008-10-15 19:50:132139 break;
2140
initial.commit09911bf2008-07-26 23:55:292141 default:
2142 NOTREACHED() << "unknown ErrorPageType";
2143 }
2144
2145 // OK, build the final url to return.
2146 GURL::Replacements link_doctor_params;
2147 link_doctor_params.SetQueryStr(params);
2148 GURL url = alternate_error_page_url_.ReplaceComponents(link_doctor_params);
2149 return url;
2150}
2151
[email protected]7ea066a2009-04-06 20:21:592152void RenderView::OnFind(int request_id,
2153 const string16& search_text,
2154 const WebKit::WebFindOptions& options) {
initial.commit09911bf2008-07-26 23:55:292155 WebFrame* main_frame = webview()->GetMainFrame();
2156 WebFrame* frame_after_main = webview()->GetNextFrameAfter(main_frame, true);
2157 WebFrame* focused_frame = webview()->GetFocusedFrame();
2158 WebFrame* search_frame = focused_frame; // start searching focused frame.
2159
2160 bool multi_frame = (frame_after_main != main_frame);
2161
2162 // If we have multiple frames, we don't want to wrap the search within the
2163 // frame, so we check here if we only have main_frame in the chain.
2164 bool wrap_within_frame = !multi_frame;
2165
[email protected]b3f2b912009-04-09 16:18:522166 WebRect selection_rect;
initial.commit09911bf2008-07-26 23:55:292167 bool result = false;
2168
2169 do {
[email protected]7ea066a2009-04-06 20:21:592170 result = search_frame->Find(
2171 request_id, search_text, options, wrap_within_frame, &selection_rect);
initial.commit09911bf2008-07-26 23:55:292172
2173 if (!result) {
2174 // don't leave text selected as you move to the next frame.
2175 search_frame->ClearSelection();
2176
2177 // Find the next frame, but skip the invisible ones.
2178 do {
2179 // What is the next frame to search? (we might be going backwards). Note
2180 // that we specify wrap=true so that search_frame never becomes NULL.
[email protected]7ea066a2009-04-06 20:21:592181 search_frame = options.forward ?
initial.commit09911bf2008-07-26 23:55:292182 webview()->GetNextFrameAfter(search_frame, true) :
2183 webview()->GetPreviousFrameBefore(search_frame, true);
2184 } while (!search_frame->Visible() && search_frame != focused_frame);
2185
[email protected]884db412008-11-24 23:46:502186 // Make sure selection doesn't affect the search operation in new frame.
initial.commit09911bf2008-07-26 23:55:292187 search_frame->ClearSelection();
2188
2189 // If we have multiple frames and we have wrapped back around to the
2190 // focused frame, we need to search it once more allowing wrap within
2191 // the frame, otherwise it will report 'no match' if the focused frame has
2192 // reported matches, but no frames after the focused_frame contain a
2193 // match for the search word(s).
2194 if (multi_frame && search_frame == focused_frame) {
[email protected]7ea066a2009-04-06 20:21:592195 result = search_frame->Find(
2196 request_id, search_text, options, true, // Force wrapping.
2197 &selection_rect);
initial.commit09911bf2008-07-26 23:55:292198 }
2199 }
2200
2201 // TODO(jcampan): http://b/issue?id=1157486 Remove StoreForFocus call once
2202 // we have the fix for 792423.
2203 search_frame->GetView()->StoreFocusForFrame(search_frame);
2204 webview()->SetFocusedFrame(search_frame);
2205 } while (!result && search_frame != focused_frame);
2206
2207 // Make sure we don't leave any frame focused or the focus won't be restored
2208 // properly in WebViewImpl::SetFocus(). Note that we are talking here about
2209 // focused on the SelectionController, not FocusController.
2210 // webview()->GetFocusedFrame() will still return the last focused frame (as
2211 // it queries the FocusController).
2212 // TODO(jcampan): http://b/issue?id=1157486 Remove next line once we have the
2213 // fix for 792423.
2214 webview()->SetFocusedFrame(NULL);
2215
[email protected]7ea066a2009-04-06 20:21:592216 if (options.findNext) {
[email protected]4f3dc372009-02-24 00:10:292217 // Force the main_frame to report the actual count.
[email protected]7ea066a2009-04-06 20:21:592218 main_frame->IncreaseMatchCount(0, request_id);
[email protected]4f3dc372009-02-24 00:10:292219 } else {
2220 // If nothing is found, set result to "0 of 0", otherwise, set it to
2221 // "-1 of 1" to indicate that we found at least one item, but we don't know
2222 // yet what is active.
2223 int ordinal = result ? -1 : 0; // -1 here means, we might know more later.
2224 int match_count = result ? 1 : 0; // 1 here means possibly more coming.
initial.commit09911bf2008-07-26 23:55:292225
[email protected]4f3dc372009-02-24 00:10:292226 // If we find no matches then this will be our last status update.
2227 // Otherwise the scoping effort will send more results.
2228 bool final_status_update = !result;
initial.commit09911bf2008-07-26 23:55:292229
[email protected]4f3dc372009-02-24 00:10:292230 // Send the search result over to the browser process.
[email protected]4f999132009-03-31 18:08:402231 Send(new ViewHostMsg_Find_Reply(routing_id_,
[email protected]7ea066a2009-04-06 20:21:592232 request_id,
[email protected]4f3dc372009-02-24 00:10:292233 match_count,
2234 selection_rect,
2235 ordinal,
2236 final_status_update));
initial.commit09911bf2008-07-26 23:55:292237
initial.commit09911bf2008-07-26 23:55:292238 // Scoping effort begins, starting with the mainframe.
2239 search_frame = main_frame;
2240
2241 main_frame->ResetMatchCount();
2242
2243 do {
2244 // Cancel all old scoping requests before starting a new one.
2245 search_frame->CancelPendingScopingEffort();
2246
2247 // We don't start another scoping effort unless at least one match has
2248 // been found.
2249 if (result) {
2250 // Start new scoping request. If the scoping function determines that it
2251 // needs to scope, it will defer until later.
[email protected]7ea066a2009-04-06 20:21:592252 search_frame->ScopeStringMatches(request_id,
2253 search_text,
2254 options,
initial.commit09911bf2008-07-26 23:55:292255 true); // reset the tickmarks
2256 }
2257
2258 // Iterate to the next frame. The frame will not necessarily scope, for
2259 // example if it is not visible.
2260 search_frame = webview()->GetNextFrameAfter(search_frame, true);
2261 } while (search_frame != main_frame);
2262 }
2263}
2264
2265void RenderView::ReportFindInPageMatchCount(int count, int request_id,
2266 bool final_update) {
2267 // If we have a message that has been queued up, then we should just replace
2268 // it. The ACK from the browser will make sure it gets sent when the browser
2269 // wants it.
2270 if (queued_find_reply_message_.get()) {
2271 IPC::Message* msg = new ViewHostMsg_Find_Reply(
2272 routing_id_,
2273 request_id,
2274 count,
[email protected]b3f2b912009-04-09 16:18:522275 gfx::Rect(),
initial.commit09911bf2008-07-26 23:55:292276 -1, // Don't update active match ordinal.
2277 final_update);
2278 queued_find_reply_message_.reset(msg);
2279 } else {
2280 // Send the search result over to the browser process.
2281 Send(new ViewHostMsg_Find_Reply(
2282 routing_id_,
2283 request_id,
2284 count,
[email protected]b3f2b912009-04-09 16:18:522285 gfx::Rect(),
initial.commit09911bf2008-07-26 23:55:292286 -1, // // Don't update active match ordinal.
2287 final_update));
2288 }
2289}
2290
2291void RenderView::ReportFindInPageSelection(int request_id,
2292 int active_match_ordinal,
[email protected]b3f2b912009-04-09 16:18:522293 const WebRect& selection_rect) {
initial.commit09911bf2008-07-26 23:55:292294 // Send the search result over to the browser process.
2295 Send(new ViewHostMsg_Find_Reply(routing_id_,
2296 request_id,
2297 -1,
2298 selection_rect,
2299 active_match_ordinal,
2300 false));
2301}
2302
2303bool RenderView::WasOpenedByUserGesture(WebView* webview) const {
2304 return WasOpenedByUserGestureHelper();
2305}
2306
2307bool RenderView::WasOpenedByUserGestureHelper() const {
2308 // If pop-up blocking has been disabled, then treat all new windows as if
2309 // they were opened by a user gesture. This will prevent them from being
2310 // blocked. This is a bit of a hack, there should be a more straightforward
2311 // way to disable pop-up blocking.
2312 if (disable_popup_blocking_)
2313 return true;
2314
2315 return opened_by_user_gesture_;
2316}
2317
2318void RenderView::SpellCheck(const std::wstring& word, int& misspell_location,
2319 int& misspell_length) {
2320 Send(new ViewHostMsg_SpellCheck(routing_id_, word, &misspell_location,
2321 &misspell_length));
2322}
2323
2324void RenderView::SetInputMethodState(bool enabled) {
2325 // Save the updated IME status and mark the input focus has been updated.
2326 // The IME status is to be sent to a browser process next time when
2327 // the input caret is rendered.
[email protected]9f23f592008-11-17 08:36:342328 if (!ime_control_busy_) {
2329 ime_control_updated_ = true;
2330 ime_control_new_state_ = enabled;
2331 }
initial.commit09911bf2008-07-26 23:55:292332}
2333
2334void RenderView::ScriptedPrint(WebFrame* frame) {
[email protected]6c8afae52009-01-22 02:24:572335#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292336 // Retrieve the default print settings to calculate the expected number of
2337 // pages.
2338 ViewMsg_Print_Params default_settings;
2339 IPC::SyncMessage* msg =
2340 new ViewHostMsg_GetDefaultPrintSettings(routing_id_, &default_settings);
2341 if (Send(msg)) {
2342 msg = NULL;
2343 // Continue only if the settings are valid.
2344 if (default_settings.dpi && default_settings.document_cookie) {
[email protected]88a3ecc2009-03-19 17:36:222345 int expected_pages_count = 0;
2346 gfx::Size canvas_size;
2347 canvas_size.set_width(
2348 printing::ConvertUnit(default_settings.printable_size.width(),
2349 static_cast<int>(default_settings.dpi),
2350 default_settings.desired_dpi));
2351 canvas_size.set_height(
2352 printing::ConvertUnit(default_settings.printable_size.height(),
2353 static_cast<int>(default_settings.dpi),
2354 default_settings.desired_dpi));
2355 frame->BeginPrint(canvas_size, &expected_pages_count);
initial.commit09911bf2008-07-26 23:55:292356 DCHECK(expected_pages_count);
[email protected]88a3ecc2009-03-19 17:36:222357 frame->EndPrint();
initial.commit09911bf2008-07-26 23:55:292358
2359 // Ask the browser to show UI to retrieve the final print settings.
2360 ViewMsg_PrintPages_Params print_settings;
2361 // host_window_ may be NULL at this point if the current window is a popup
2362 // and the print() command has been issued from the parent. The receiver
2363 // of this message has to deal with this.
2364 msg = new ViewHostMsg_ScriptedPrint(routing_id_,
2365 host_window_,
2366 default_settings.document_cookie,
2367 expected_pages_count,
2368 &print_settings);
2369 if (Send(msg)) {
2370 msg = NULL;
2371
2372 // If the settings are invalid, early quit.
2373 if (print_settings.params.dpi &&
2374 print_settings.params.document_cookie) {
2375 // Render the printed pages. It will implicitly revert the document to
2376 // display CSS media type.
2377 PrintPages(print_settings, frame);
2378 // All went well.
2379 return;
2380 } else {
2381 // The user cancelled.
2382 }
2383 } else {
2384 // Send() failed.
2385 NOTREACHED();
2386 }
2387 } else {
2388 // The user cancelled.
2389 }
2390 } else {
2391 // Send() failed.
2392 NOTREACHED();
2393 }
2394 // TODO(maruel): bug 1123882 Alert the user that printing failed.
[email protected]6c8afae52009-01-22 02:24:572395#else // defined(OS_WIN)
2396 // TODO(port): print not implemented
2397 NOTIMPLEMENTED();
2398#endif
initial.commit09911bf2008-07-26 23:55:292399}
2400
2401void RenderView::WebInspectorOpened(int num_resources) {
2402 Send(new ViewHostMsg_InspectElement_Reply(routing_id_, num_resources));
2403}
2404
2405void RenderView::UserMetricsRecordAction(const std::wstring& action) {
2406 Send(new ViewHostMsg_UserMetricsRecordAction(routing_id_, action));
2407}
2408
2409void RenderView::DnsPrefetch(const std::vector<std::string>& host_names) {
2410 Send(new ViewHostMsg_DnsPrefetch(host_names));
2411}
2412
[email protected]630e26b2008-10-14 22:55:172413void RenderView::OnZoom(int function) {
2414 static const bool kZoomIsTextOnly = false;
2415 switch (function) {
2416 case PageZoom::SMALLER:
2417 webview()->ZoomOut(kZoomIsTextOnly);
initial.commit09911bf2008-07-26 23:55:292418 break;
[email protected]630e26b2008-10-14 22:55:172419 case PageZoom::STANDARD:
2420 webview()->ResetZoom();
initial.commit09911bf2008-07-26 23:55:292421 break;
[email protected]630e26b2008-10-14 22:55:172422 case PageZoom::LARGER:
2423 webview()->ZoomIn(kZoomIsTextOnly);
initial.commit09911bf2008-07-26 23:55:292424 break;
2425 default:
2426 NOTREACHED();
2427 }
2428}
2429
[email protected]ea8c7452009-04-02 20:47:062430void RenderView::OnInsertText(const string16& text) {
[email protected]00d7e622009-04-21 23:06:052431 WebTextInput* text_input = webview()->GetMainFrame()->GetTextInput();
2432 if (text_input)
2433 text_input->InsertText(UTF16ToUTF8(text));
[email protected]ea8c7452009-04-02 20:47:062434}
2435
[email protected]e38f40152008-09-12 23:08:302436void RenderView::OnSetPageEncoding(const std::wstring& encoding_name) {
initial.commit09911bf2008-07-26 23:55:292437 webview()->SetPageEncoding(encoding_name);
2438}
2439
2440void RenderView::OnPasswordFormsSeen(WebView* webview,
2441 const std::vector<PasswordForm>& forms) {
2442 Send(new ViewHostMsg_PasswordFormsSeen(routing_id_, forms));
2443}
2444
[email protected]8d0f15c2008-11-11 01:01:092445void RenderView::OnAutofillFormSubmitted(WebView* webview,
2446 const AutofillForm& form) {
2447 Send(new ViewHostMsg_AutofillFormSubmitted(routing_id_, form));
2448}
2449
initial.commit09911bf2008-07-26 23:55:292450WebHistoryItem* RenderView::GetHistoryEntryAtOffset(int offset) {
[email protected]50b691c2008-10-31 19:08:352451 // Our history list is kept in the browser process on the UI thread. Since
2452 // we can't make a sync IPC call to that thread without risking deadlock,
2453 // we use a trick: construct a fake history item of the form:
2454 // history://go/OFFSET
2455 // When WebCore tells us to navigate to it, we tell the browser process to
2456 // do a back/forward navigation instead.
2457
2458 GURL url(StringPrintf("%s://go/%d", kBackForwardNavigationScheme, offset));
2459 history_navigation_item_ = WebHistoryItem::Create(url, L"", "", NULL);
2460 return history_navigation_item_.get();
initial.commit09911bf2008-07-26 23:55:292461}
2462
[email protected]0c0383772008-11-04 00:48:312463void RenderView::GoToEntryAtOffset(int offset) {
[email protected]f46aff62008-10-16 07:58:052464 history_back_list_count_ += offset;
2465 history_forward_list_count_ -= offset;
2466
initial.commit09911bf2008-07-26 23:55:292467 Send(new ViewHostMsg_GoToEntryAtOffset(routing_id_, offset));
2468}
2469
2470int RenderView::GetHistoryBackListCount() {
2471 return history_back_list_count_;
2472}
2473
2474int RenderView::GetHistoryForwardListCount() {
2475 return history_forward_list_count_;
2476}
2477
2478void RenderView::OnNavStateChanged(WebView* webview) {
[email protected]81a34412009-01-05 19:17:242479 if (!nav_state_sync_timer_.IsRunning()) {
2480 nav_state_sync_timer_.Start(
2481 TimeDelta::FromSeconds(delay_seconds_for_form_state_sync_), this,
2482 &RenderView::SyncNavigationState);
2483 }
initial.commit09911bf2008-07-26 23:55:292484}
2485
2486void RenderView::SetTooltipText(WebView* webview,
2487 const std::wstring& tooltip_text) {
2488 Send(new ViewHostMsg_SetTooltipText(routing_id_, tooltip_text));
2489}
2490
[email protected]2e417c82009-04-02 22:30:262491void RenderView::DidChangeSelection(bool is_empty_selection) {
2492#if defined(OS_LINUX)
2493 if (!is_empty_selection) {
[email protected]dbadbcc2009-04-09 00:57:102494 Send(new ViewHostMsg_SelectionChanged(routing_id_,
2495 webview()->GetMainFrame()->GetSelection(false)));
[email protected]2e417c82009-04-02 22:30:262496 }
2497#endif
2498}
2499
2500
initial.commit09911bf2008-07-26 23:55:292501void RenderView::DownloadUrl(const GURL& url, const GURL& referrer) {
2502 Send(new ViewHostMsg_DownloadUrl(routing_id_, url, referrer));
2503}
2504
[email protected]611cad42009-03-16 18:51:342505WebDevToolsAgentDelegate* RenderView::GetWebDevToolsAgentDelegate() {
[email protected]b75b7d072009-04-06 13:47:002506 return devtools_agent_.get();
[email protected]611cad42009-03-16 18:51:342507}
2508
[email protected]ea8c7452009-04-02 20:47:062509void RenderView::PasteFromSelectionClipboard() {
2510 Send(new ViewHostMsg_PasteFromSelectionClipboard(routing_id_));
2511}
2512
initial.commit09911bf2008-07-26 23:55:292513WebFrame* RenderView::GetChildFrame(const std::wstring& frame_xpath) const {
2514 WebFrame* web_frame;
2515 if (frame_xpath.empty()) {
2516 web_frame = webview()->GetMainFrame();
2517 } else {
2518 web_frame = webview()->GetMainFrame()->GetChildFrame(frame_xpath);
2519 }
2520
2521 return web_frame;
2522}
2523
[email protected]f29acf52008-11-03 20:08:332524void RenderView::EvaluateScript(const std::wstring& frame_xpath,
2525 const std::wstring& script) {
initial.commit09911bf2008-07-26 23:55:292526 WebFrame* web_frame = GetChildFrame(frame_xpath);
2527 if (!web_frame)
2528 return;
2529
[email protected]4f999132009-03-31 18:08:402530 web_frame->ExecuteScript(WebScriptSource(WideToUTF16Hack(script)));
initial.commit09911bf2008-07-26 23:55:292531}
2532
[email protected]1810e132009-03-24 23:35:482533void RenderView::InsertCSS(const std::wstring& frame_xpath,
2534 const std::string& css) {
2535 WebFrame* web_frame = GetChildFrame(frame_xpath);
2536 if (!web_frame)
2537 return;
2538
2539 web_frame->InsertCSSStyles(css);
2540}
2541
initial.commit09911bf2008-07-26 23:55:292542void RenderView::OnScriptEvalRequest(const std::wstring& frame_xpath,
2543 const std::wstring& jscript) {
[email protected]f29acf52008-11-03 20:08:332544 EvaluateScript(frame_xpath, jscript);
initial.commit09911bf2008-07-26 23:55:292545}
2546
[email protected]1810e132009-03-24 23:35:482547void RenderView::OnCSSInsertRequest(const std::wstring& frame_xpath,
2548 const std::string& css) {
2549 InsertCSS(frame_xpath, css);
2550}
2551
[email protected]7ea066a2009-04-06 20:21:592552void RenderView::OnAddMessageToConsole(
2553 const string16& frame_xpath,
2554 const string16& message,
2555 const WebConsoleMessage::Level& level) {
2556 WebFrame* web_frame = GetChildFrame(UTF16ToWideHack(frame_xpath));
[email protected]0dea3ea2009-03-31 23:30:592557 if (web_frame)
[email protected]7ea066a2009-04-06 20:21:592558 web_frame->AddMessageToConsole(WebConsoleMessage(level, message));
initial.commit09911bf2008-07-26 23:55:292559}
2560
[email protected]6c8afae52009-01-22 02:24:572561#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292562void RenderView::OnDebugAttach() {
initial.commit09911bf2008-07-26 23:55:292563 Send(new ViewHostMsg_DidDebugAttach(routing_id_));
2564 // Tell the plugin host to stop accepting messages in order to avoid
2565 // hangs while the renderer is paused.
2566 // TODO(1243929): It might be an improvement to add more plumbing to do this
2567 // when the renderer is actually paused vs. just the debugger being attached.
2568 PluginChannelHost::SetListening(false);
2569}
2570
2571void RenderView::OnDebugDetach() {
2572 // Tell the plugin host to start accepting plugin messages again.
2573 PluginChannelHost::SetListening(true);
2574}
[email protected]6c8afae52009-01-22 02:24:572575#else // defined(OS_WIN)
2576// TODO(port): plugins not yet supported
2577void RenderView::OnDebugAttach() { NOTIMPLEMENTED(); }
2578void RenderView::OnDebugDetach() { NOTIMPLEMENTED(); }
2579#endif
initial.commit09911bf2008-07-26 23:55:292580
[email protected]81e63782009-02-27 19:35:092581void RenderView::OnAllowBindings(int enabled_bindings_flags) {
2582 enabled_bindings_ |= enabled_bindings_flags;
initial.commit09911bf2008-07-26 23:55:292583}
2584
2585void RenderView::OnSetDOMUIProperty(const std::string& name,
2586 const std::string& value) {
[email protected]81e63782009-02-27 19:35:092587 DCHECK(BindingsPolicy::is_dom_ui_enabled(enabled_bindings_));
initial.commit09911bf2008-07-26 23:55:292588 dom_ui_bindings_.SetProperty(name, value);
2589}
2590
2591void RenderView::OnReservePageIDRange(int size_of_range) {
2592 next_page_id_ += size_of_range + 1;
2593}
2594
[email protected]e80c73b2009-04-07 23:24:582595void RenderView::OnDragSourceEndedOrMoved(const gfx::Point& client_point,
2596 const gfx::Point& screen_point,
initial.commit09911bf2008-07-26 23:55:292597 bool ended) {
2598 if (ended)
[email protected]e80c73b2009-04-07 23:24:582599 webview()->DragSourceEndedAt(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292600 else
[email protected]e80c73b2009-04-07 23:24:582601 webview()->DragSourceMovedTo(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292602}
2603
2604void RenderView::OnDragSourceSystemDragEnded() {
2605 webview()->DragSourceSystemDragEnded();
2606}
2607
2608void RenderView::OnUploadFileRequest(const ViewMsg_UploadFile_Params& p) {
2609 webkit_glue::FileUploadData* f = new webkit_glue::FileUploadData;
2610 f->file_path = p.file_path;
2611 f->form_name = p.form;
2612 f->file_name = p.file;
2613 f->submit_name = p.submit;
2614
2615 // Build the other form values map.
2616 if (!p.other_values.empty()) {
2617 std::vector<std::wstring> e;
2618 std::vector<std::wstring> kvp;
2619 std::vector<std::wstring>::iterator i;
2620
2621 SplitString(p.other_values, L'\n', &e);
2622 for (i = e.begin(); i != e.end(); ++i) {
2623 SplitString(*i, L'=', &kvp);
2624 if (kvp.size() == 2)
2625 f->other_form_values[kvp[0]] = kvp[1];
2626 kvp.clear();
2627 }
2628 }
2629
2630 pending_upload_data_.reset(f);
2631 ProcessPendingUpload();
2632}
2633
2634void RenderView::ProcessPendingUpload() {
2635 webkit_glue::FileUploadData* f = pending_upload_data_.get();
2636 if (f && webview() && webkit_glue::FillFormToUploadFile(webview(), *f))
2637 ResetPendingUpload();
2638}
2639
2640void RenderView::ResetPendingUpload() {
2641 pending_upload_data_.reset();
2642}
2643
2644void RenderView::OnFormFill(const FormData& form) {
2645 webkit_glue::FillForm(this->webview(), form);
2646}
2647
2648void RenderView::OnFillPasswordForm(
2649 const PasswordFormDomManager::FillData& form_data) {
2650 webkit_glue::FillPasswordForm(this->webview(), form_data);
2651}
2652
2653void RenderView::OnDragTargetDragEnter(const WebDropData& drop_data,
[email protected]e80c73b2009-04-07 23:24:582654 const gfx::Point& client_point,
2655 const gfx::Point& screen_point) {
2656 bool is_drop_target = webview()->DragTargetDragEnter(
2657 drop_data.ToDragData(),
2658 drop_data.identity,
2659 client_point,
2660 screen_point);
initial.commit09911bf2008-07-26 23:55:292661
2662 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target));
2663}
2664
[email protected]e80c73b2009-04-07 23:24:582665void RenderView::OnDragTargetDragOver(const gfx::Point& client_point,
2666 const gfx::Point& screen_point) {
2667 bool is_drop_target =
2668 webview()->DragTargetDragOver(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292669
2670 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, is_drop_target));
2671}
2672
2673void RenderView::OnDragTargetDragLeave() {
2674 webview()->DragTargetDragLeave();
2675}
2676
[email protected]e80c73b2009-04-07 23:24:582677void RenderView::OnDragTargetDrop(const gfx::Point& client_point,
2678 const gfx::Point& screen_point) {
2679 webview()->DragTargetDrop(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:292680}
2681
2682void RenderView::OnUpdateWebPreferences(const WebPreferences& prefs) {
2683 webview()->SetPreferences(prefs);
2684}
2685
2686void RenderView::OnSetAltErrorPageURL(const GURL& url) {
2687 alternate_error_page_url_ = url;
2688}
2689
2690void RenderView::DidPaint() {
2691 PluginDelegateList::iterator it = plugin_delegates_.begin();
2692 while (it != plugin_delegates_.end()) {
2693 (*it)->FlushGeometryUpdates();
2694 ++it;
2695 }
2696}
2697
2698void RenderView::OnInstallMissingPlugin() {
2699 // This could happen when the first default plugin is deleted.
2700 if (first_default_plugin_ == NULL)
2701 return;
2702 first_default_plugin_->InstallMissingPlugin();
2703}
2704
[email protected]b62d1a8c2009-01-13 23:54:572705void RenderView::OnFileChooserResponse(
[email protected]561abe62009-04-06 18:08:342706 const std::vector<FilePath>& file_names) {
[email protected]8029f5672009-03-20 22:33:362707 // This could happen if we navigated to a different page before the user
2708 // closed the chooser.
2709 if (!file_chooser_.get())
2710 return;
2711
[email protected]b62d1a8c2009-01-13 23:54:572712 file_chooser_->OnFileChoose(file_names);
initial.commit09911bf2008-07-26 23:55:292713 file_chooser_.reset();
2714}
2715
2716void RenderView::OnEnableViewSourceMode() {
2717 if (!webview())
2718 return;
2719 WebFrame* main_frame = webview()->GetMainFrame();
2720 if (!main_frame)
2721 return;
2722
2723 main_frame->SetInViewSourceMode(true);
2724}
2725
2726void RenderView::OnUpdateBackForwardListCount(int back_list_count,
2727 int forward_list_count) {
2728 history_back_list_count_ = back_list_count;
2729 history_forward_list_count_ = forward_list_count;
2730}
2731
[email protected]266eb6f2008-09-30 23:56:502732void RenderView::OnGetAccessibilityInfo(
[email protected]6a983b42009-03-20 20:12:252733 const webkit_glue::WebAccessibility::InParams& in_params,
2734 webkit_glue::WebAccessibility::OutParams* out_params) {
[email protected]6c8afae52009-01-22 02:24:572735#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:252736 if (!web_accessibility_manager_.get()) {
2737 web_accessibility_manager_.reset(
2738 webkit_glue::WebAccessibilityManager::Create());
2739 }
[email protected]266eb6f2008-09-30 23:56:502740
[email protected]6a983b42009-03-20 20:12:252741 if (!web_accessibility_manager_->GetAccObjInfo(webview(), in_params,
2742 out_params)) {
[email protected]266eb6f2008-09-30 23:56:502743 return;
2744 }
[email protected]6c8afae52009-01-22 02:24:572745#else // defined(OS_WIN)
2746 // TODO(port): accessibility not yet implemented
2747 NOTIMPLEMENTED();
2748#endif
[email protected]266eb6f2008-09-30 23:56:502749}
2750
[email protected]6a983b42009-03-20 20:12:252751void RenderView::OnClearAccessibilityInfo(int acc_obj_id, bool clear_all) {
[email protected]6c8afae52009-01-22 02:24:572752#if defined(OS_WIN)
[email protected]6a983b42009-03-20 20:12:252753 if (!web_accessibility_manager_.get()) {
[email protected]266eb6f2008-09-30 23:56:502754 // If accessibility is not activated, ignore clearing message.
2755 return;
2756 }
[email protected]6a983b42009-03-20 20:12:252757 if (!web_accessibility_manager_->ClearAccObjMap(acc_obj_id, clear_all))
[email protected]266eb6f2008-09-30 23:56:502758 return;
[email protected]6c8afae52009-01-22 02:24:572759#else // defined(OS_WIN)
2760 // TODO(port): accessibility not yet implemented
2761 NOTIMPLEMENTED();
2762#endif
[email protected]266eb6f2008-09-30 23:56:502763}
2764
initial.commit09911bf2008-07-26 23:55:292765void RenderView::OnGetAllSavableResourceLinksForCurrentPage(
2766 const GURL& page_url) {
2767 // Prepare list to storage all savable resource links.
2768 std::vector<GURL> resources_list;
2769 std::vector<GURL> referrers_list;
2770 std::vector<GURL> frames_list;
2771 webkit_glue::SavableResourcesResult result(&resources_list,
2772 &referrers_list,
2773 &frames_list);
2774
2775 if (!webkit_glue::GetAllSavableResourceLinksForCurrentPage(webview(),
2776 page_url,
2777 &result)) {
2778 // If something is wrong when collecting all savable resource links,
2779 // send empty list to embedder(browser) to tell it failed.
2780 referrers_list.clear();
2781 resources_list.clear();
2782 frames_list.clear();
2783 }
2784
2785 // Send result of all savable resource links to embedder.
2786 Send(new ViewHostMsg_SendCurrentPageAllSavableResourceLinks(routing_id_,
2787 resources_list,
2788 referrers_list,
2789 frames_list));
2790}
2791
2792void RenderView::OnGetSerializedHtmlDataForCurrentPageWithLocalLinks(
[email protected]f6b48532009-02-12 01:56:322793 const std::vector<GURL>& links,
[email protected]fde6714d12009-02-18 22:39:312794 const std::vector<FilePath>& local_paths,
2795 const FilePath& local_directory_name) {
initial.commit09911bf2008-07-26 23:55:292796 webkit_glue::DomSerializer dom_serializer(webview()->GetMainFrame(),
2797 true,
2798 this,
2799 links,
2800 local_paths,
2801 local_directory_name);
2802 dom_serializer.SerializeDom();
2803}
2804
2805void RenderView::DidSerializeDataForFrame(const GURL& frame_url,
2806 const std::string& data, PageSavingSerializationStatus status) {
2807 Send(new ViewHostMsg_SendSerializedHtmlData(routing_id_,
2808 frame_url, data, static_cast<int32>(status)));
2809}
2810
[email protected]04b4a6c2008-08-02 00:44:472811void RenderView::OnMsgShouldClose() {
initial.commit09911bf2008-07-26 23:55:292812 bool should_close = webview()->ShouldClose();
[email protected]04b4a6c2008-08-02 00:44:472813 Send(new ViewHostMsg_ShouldClose_ACK(routing_id_, should_close));
initial.commit09911bf2008-07-26 23:55:292814}
2815
2816void RenderView::OnClosePage(int new_render_process_host_id,
[email protected]04b4a6c2008-08-02 00:44:472817 int new_request_id) {
initial.commit09911bf2008-07-26 23:55:292818 // TODO(creis): We'd rather use webview()->Close() here, but that currently
2819 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs
2820 // in the onunload handler from appearing. For now, we're bypassing that and
2821 // calling the FrameLoader's CloseURL method directly. This should be
2822 // revisited to avoid having two ways to close a page. Having a single way
2823 // to close that can run onunload is also useful for fixing
2824 // http://b/issue?id=753080.
2825 WebFrame* main_frame = webview()->GetMainFrame();
2826 if (main_frame)
2827 main_frame->ClosePage();
2828
2829 Send(new ViewHostMsg_ClosePage_ACK(routing_id_,
2830 new_render_process_host_id,
[email protected]04b4a6c2008-08-02 00:44:472831 new_request_id));
initial.commit09911bf2008-07-26 23:55:292832}
2833
2834void RenderView::OnThemeChanged() {
[email protected]6c8afae52009-01-22 02:24:572835#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:292836 gfx::NativeTheme::instance()->CloseHandles();
2837 gfx::Rect view_rect(0, 0, size_.width(), size_.height());
2838 DidInvalidateRect(webwidget_, view_rect);
[email protected]6c8afae52009-01-22 02:24:572839#else // defined(OS_WIN)
2840 // TODO(port): we don't support theming on non-Windows platforms yet
2841 NOTIMPLEMENTED();
2842#endif
initial.commit09911bf2008-07-26 23:55:292843}
2844
[email protected]f46aff62008-10-16 07:58:052845void RenderView::DidAddHistoryItem() {
[email protected]f8901082008-10-31 23:34:032846 // We don't want to update the history length for the start page
2847 // navigation.
2848 WebFrame* main_frame = webview()->GetMainFrame();
2849 DCHECK(main_frame != NULL);
2850
2851 WebDataSource* ds = main_frame->GetDataSource();
2852 DCHECK(ds != NULL);
2853
2854 const WebRequest& request = ds->GetRequest();
2855 RenderViewExtraRequestData* extra_data =
2856 static_cast<RenderViewExtraRequestData*>(request.GetExtraData());
2857
2858 if (extra_data && extra_data->transition_type == PageTransition::START_PAGE)
2859 return;
2860
[email protected]f46aff62008-10-16 07:58:052861 history_back_list_count_++;
2862 history_forward_list_count_ = 0;
2863}
2864
[email protected]28790922009-03-09 19:48:372865void RenderView::OnMessageFromExternalHost(const std::string& message,
2866 const std::string& origin,
2867 const std::string& target) {
[email protected]3ac14a052008-08-15 21:22:152868 if (message.empty())
2869 return;
2870
[email protected]28790922009-03-09 19:48:372871 external_host_bindings_.ForwardMessageFromExternalHost(message, origin,
2872 target);
[email protected]3ac14a052008-08-15 21:22:152873}
2874
[email protected]0aa55312008-10-17 21:53:082875void RenderView::OnDisassociateFromPopupCount() {
2876 if (decrement_shared_popup_at_destruction_)
2877 shared_popup_counter_->data--;
2878 shared_popup_counter_ = new SharedRenderViewCounter(0);
2879 decrement_shared_popup_at_destruction_ = false;
2880}
2881
initial.commit09911bf2008-07-26 23:55:292882std::string RenderView::GetAltHTMLForTemplate(
2883 const DictionaryValue& error_strings, int template_resource_id) const {
2884 const StringPiece template_html(
2885 ResourceBundle::GetSharedInstance().GetRawDataResource(
2886 template_resource_id));
2887
2888 if (template_html.empty()) {
2889 NOTREACHED() << "unable to load template. ID: " << template_resource_id;
2890 return "";
2891 }
2892 // "t" is the id of the templates root node.
2893 return jstemplate_builder::GetTemplateHtml(
2894 template_html, &error_strings, "t");
2895}
[email protected]0e79b9e2009-02-13 04:20:482896
2897MessageLoop* RenderView::GetMessageLoopForIO() {
2898 // Assume that we have only one RenderThread in the process and the owner loop
2899 // of RenderThread is an IO message loop.
[email protected]8930d472009-02-21 08:05:282900 if (RenderThread::current())
2901 return RenderThread::current()->owner_loop();
[email protected]0e79b9e2009-02-13 04:20:482902 return NULL;
2903}
[email protected]6f56d482009-02-20 05:02:562904
[email protected]30f75e62009-02-25 22:01:002905void RenderView::OnMoveOrResizeStarted() {
2906 if (webview())
2907 webview()->HideAutofillPopup();
2908}
2909
[email protected]30f75e62009-02-25 22:01:002910void RenderView::OnResize(const gfx::Size& new_size,
2911 const gfx::Rect& resizer_rect) {
2912 if (webview())
2913 webview()->HideAutofillPopup();
2914 RenderWidget::OnResize(new_size, resizer_rect);
2915}
[email protected]0aa477bd2009-03-23 22:21:432916
[email protected]05d478752009-04-08 23:38:162917void RenderView::OnClearFocusedNode() {
2918 if (webview())
2919 webview()->ClearFocusedNode();
2920}
2921
[email protected]699ab0d2009-04-23 23:19:142922void RenderView::OnSetBackground(const SkBitmap& background) {
2923 if (webview())
2924 webview()->SetIsTransparent(!background.empty());
2925
2926 SetBackground(background);
2927}
2928
[email protected]309d7a282009-03-24 09:18:272929void RenderView::SendExtensionRequest(const std::string& name,
2930 const std::string& args,
2931 int callback_id,
2932 WebFrame* callback_frame) {
[email protected]309d7a282009-03-24 09:18:272933 if (callback_id != -1) {
2934 DCHECK(callback_frame) << "Callback specified without frame";
2935 pending_extension_callbacks_.AddWithID(callback_frame, callback_id);
2936 }
2937
2938 Send(new ViewHostMsg_ExtensionRequest(routing_id_, name, args, callback_id));
2939}
2940
2941void RenderView::OnExtensionResponse(int callback_id,
2942 const std::string& response) {
2943 WebFrame* web_frame = pending_extension_callbacks_.Lookup(callback_id);
2944 if (!web_frame)
2945 return; // The frame went away.
2946
[email protected]a1a0df02009-04-09 08:18:042947 ExtensionProcessBindings::ExecuteCallbackInFrame(web_frame, callback_id,
2948 response);
[email protected]309d7a282009-03-24 09:18:272949 pending_extension_callbacks_.Remove(callback_id);
2950}
[email protected]c20210e62009-04-03 21:39:262951
[email protected]e7e4f3c2009-04-21 15:24:082952// Dump all load time histograms.
[email protected]c20210e62009-04-03 21:39:262953//
[email protected]e7e4f3c2009-04-21 15:24:082954// There are 7 histograms measuring various times.
[email protected]c20210e62009-04-03 21:39:262955// The time points we keep are
2956// request: time document was requested by user
2957// start: time load of document started
2958// finishDoc: main document loaded, before onload()
2959// finish: after onload() and all resources are loaded
[email protected]e7e4f3c2009-04-21 15:24:082960// firstLayout: first layout performed
[email protected]c20210e62009-04-03 21:39:262961// The times that we histogram are
2962// requestToStart,
2963// startToFinishDoc,
2964// finishDocToFinish,
2965// startToFinish,
2966// requestToFinish,
[email protected]e7e4f3c2009-04-21 15:24:082967// requestToFirstLayout
2968// startToFirstLayout
[email protected]c20210e62009-04-03 21:39:262969//
[email protected]e7e4f3c2009-04-21 15:24:082970// It's possible for the request time not to be set, if a client
2971// redirect had been done (the user never requested the page)
2972// Also, it's possible to load a page without ever laying it out
2973// so firstLayout can be 0.
[email protected]c20210e62009-04-03 21:39:262974void RenderView::DumpLoadHistograms() const {
2975 WebFrame* main_frame = webview()->GetMainFrame();
2976 WebDataSource* ds = main_frame->GetDataSource();
[email protected]c20210e62009-04-03 21:39:262977 Time request_time = ds->GetRequestTime();
2978 Time start_load_time = ds->GetStartLoadTime();
2979 Time finish_document_load_time = ds->GetFinishDocumentLoadTime();
2980 Time finish_load_time = ds->GetFinishLoadTime();
[email protected]e7e4f3c2009-04-21 15:24:082981 Time first_layout_time = ds->GetFirstLayoutTime();
[email protected]c20210e62009-04-03 21:39:262982 TimeDelta request_to_start = start_load_time - request_time;
2983 TimeDelta start_to_finish_doc = finish_document_load_time - start_load_time;
[email protected]e7e4f3c2009-04-21 15:24:082984 TimeDelta finish_doc_to_finish =
2985 finish_load_time - finish_document_load_time;
[email protected]c20210e62009-04-03 21:39:262986 TimeDelta start_to_finish = finish_load_time - start_load_time;
2987 TimeDelta request_to_finish = finish_load_time - start_load_time;
[email protected]e7e4f3c2009-04-21 15:24:082988 TimeDelta request_to_first_layout = first_layout_time - request_time;
2989 TimeDelta start_to_first_layout = first_layout_time - start_load_time;
[email protected]c20210e62009-04-03 21:39:262990
[email protected]e7e4f3c2009-04-21 15:24:082991 // Client side redirects will have no request time
2992 if (request_time.ToInternalValue() != 0) {
2993 UMA_HISTOGRAM_TIMES("Renderer.All.RequestToStart", request_to_start);
2994 UMA_HISTOGRAM_TIMES("Renderer.All.RequestToFinish", request_to_finish);
2995 if (request_to_first_layout.ToInternalValue() >= 0) {
2996 UMA_HISTOGRAM_TIMES(
2997 "Renderer.All.RequestToFirstLayout", request_to_first_layout);
2998 }
2999 }
[email protected]c20210e62009-04-03 21:39:263000 UMA_HISTOGRAM_TIMES("Renderer.All.StartToFinishDoc", start_to_finish_doc);
3001 UMA_HISTOGRAM_TIMES("Renderer.All.FinishDocToFinish", finish_doc_to_finish);
3002 UMA_HISTOGRAM_TIMES("Renderer.All.StartToFinish", start_to_finish);
[email protected]e7e4f3c2009-04-21 15:24:083003 if (start_to_first_layout.ToInternalValue() >= 0) {
3004 UMA_HISTOGRAM_TIMES(
3005 "Renderer.All.StartToFirstLayout", start_to_first_layout);
[email protected]c20210e62009-04-03 21:39:263006 }
3007}