blob: 4dbc188aada9325eb0c6db39712e09598056cab0 [file] [log] [blame]
[email protected]1b4209f2011-01-07 00:25:401// Copyright (c) 2011 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
[email protected]6e24cf12011-03-18 19:57:025#include "content/renderer/render_view.h"
initial.commit09911bf2008-07-26 23:55:296
7#include <algorithm>
[email protected]b75b8292010-10-01 07:28:258#include <cmath>
initial.commit09911bf2008-07-26 23:55:299#include <string>
10#include <vector>
11
[email protected]2041cf342010-02-19 03:15:5912#include "base/callback.h"
initial.commit09911bf2008-07-26 23:55:2913#include "base/command_line.h"
[email protected]bb063b72009-03-27 23:18:5014#include "base/compiler_specific.h"
[email protected]b1cf3372011-04-20 21:28:1015#include "base/json/json_writer.h"
[email protected]625332e02010-12-14 07:48:4916#include "base/lazy_instance.h"
[email protected]835d7c82010-10-14 04:38:3817#include "base/metrics/histogram.h"
[email protected]7bf795d92010-05-22 00:14:2818#include "base/path_service.h"
[email protected]8380c092009-06-25 17:45:5119#include "base/process_util.h"
initial.commit09911bf2008-07-26 23:55:2920#include "base/string_piece.h"
21#include "base/string_util.h"
[email protected]55126132010-08-19 14:53:2822#include "base/sys_string_conversions.h"
[email protected]6fdd4182010-10-14 23:59:2623#include "base/time.h"
[email protected]be1ce6a72010-08-03 14:35:2224#include "base/utf_string_conversions.h"
[email protected]e93e04e2011-03-14 00:27:1025#include "content/common/appcache/appcache_dispatcher.h"
[email protected]9966325b2011-04-18 05:00:1026#include "content/common/bindings_policy.h"
[email protected]127dd582011-03-16 21:32:1027#include "content/common/clipboard_messages.h"
[email protected]db803aae2011-03-05 02:00:4228#include "content/common/content_constants.h"
[email protected]9966325b2011-04-18 05:00:1029#include "content/common/content_switches.h"
[email protected]37666cf2011-03-13 21:51:4230#include "content/common/database_messages.h"
[email protected]59f4f2fa2011-03-23 01:00:5531#include "content/common/drag_messages.h"
[email protected]7ef40ffe12011-03-08 05:05:2832#include "content/common/file_system/file_system_dispatcher.h"
33#include "content/common/file_system/webfilesystem_callback_dispatcher.h"
[email protected]c3113022011-04-16 03:26:3034#include "content/common/json_value_serializer.h"
[email protected]7f070d42011-03-09 20:25:3235#include "content/common/notification_service.h"
[email protected]127dd582011-03-16 21:32:1036#include "content/common/pepper_messages.h"
[email protected]cebc3dc2011-04-18 17:15:0037#include "content/common/pepper_plugin_registry.h"
[email protected]10e5cf12011-04-13 04:10:4038#include "content/common/quota_dispatcher.h"
[email protected]60916042011-03-19 00:43:3639#include "content/common/renderer_preferences.h"
[email protected]9966325b2011-04-18 05:00:1040#include "content/common/url_constants.h"
[email protected]778574e2011-03-21 22:03:5041#include "content/common/view_messages.h"
[email protected]230b7ef2011-03-16 22:30:1942#include "content/renderer/audio_message_filter.h"
[email protected]21d61e52011-03-18 19:08:2543#include "content/renderer/content_renderer_client.h"
[email protected]230b7ef2011-03-16 22:30:1944#include "content/renderer/device_orientation_dispatcher.h"
[email protected]55722152011-03-22 01:33:5345#include "content/renderer/external_popup_menu.h"
[email protected]230b7ef2011-03-16 22:30:1946#include "content/renderer/geolocation_dispatcher.h"
[email protected]921f1592011-03-18 00:41:0247#include "content/renderer/load_progress_tracker.h"
[email protected]ccc70d8e2011-03-16 20:40:3748#include "content/renderer/media/audio_renderer_impl.h"
49#include "content/renderer/media/ipc_video_decoder.h"
[email protected]921f1592011-03-18 00:41:0250#include "content/renderer/navigation_state.h"
[email protected]230b7ef2011-03-16 22:30:1951#include "content/renderer/notification_provider.h"
[email protected]ccc70d8e2011-03-16 20:40:3752#include "content/renderer/p2p/socket_dispatcher.h"
[email protected]6f516082011-03-17 19:15:3553#include "content/renderer/plugin_channel_host.h"
[email protected]8704f89b2011-04-15 00:30:0554#include "content/renderer/render_process.h"
[email protected]10e6ab572011-04-14 23:42:0055#include "content/renderer/render_thread.h"
[email protected]60916042011-03-19 00:43:3656#include "content/renderer/render_view_observer.h"
57#include "content/renderer/render_view_visitor.h"
[email protected]2cff0052011-03-18 16:51:4458#include "content/renderer/render_widget_fullscreen_pepper.h"
[email protected]663bd9e2011-03-21 01:07:0159#include "content/renderer/renderer_webapplicationcachehost_impl.h"
60#include "content/renderer/renderer_webstoragenamespace_impl.h"
[email protected]230b7ef2011-03-16 22:30:1961#include "content/renderer/speech_input_dispatcher.h"
[email protected]b1cf3372011-04-20 21:28:1062#include "content/renderer/v8_value_converter.h"
[email protected]663bd9e2011-03-21 01:07:0163#include "content/renderer/web_ui_bindings.h"
[email protected]6f516082011-03-17 19:15:3564#include "content/renderer/webgraphicscontext3d_command_buffer_impl.h"
65#include "content/renderer/webplugin_delegate_proxy.h"
66#include "content/renderer/websharedworker_proxy.h"
67#include "content/renderer/webworker_proxy.h"
[email protected]f8db8132010-12-03 00:27:4968#include "media/base/filter_collection.h"
[email protected]ee68378a2010-08-10 01:05:4169#include "media/base/media_switches.h"
[email protected]f78d1dfc2011-01-15 07:09:2770#include "media/base/message_loop_factory_impl.h"
initial.commit09911bf2008-07-26 23:55:2971#include "net/base/escape.h"
72#include "net/base/net_errors.h"
[email protected]52c68652010-12-07 17:47:0473#include "net/http/http_util.h"
[email protected]9d9f1bb2011-02-23 22:10:5774#include "ppapi/c/private/ppb_flash_net_connector.h"
[email protected]8bd0fe62011-01-17 06:44:3775#include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityCache.h"
76#include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObject.h"
77#include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h"
78#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
[email protected]8bd0fe62011-01-17 06:44:3779#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
80#include "third_party/WebKit/Source/WebKit/chromium/public/WebDragData.h"
81#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
82#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserParams.h"
[email protected]8bd0fe62011-01-17 06:44:3783#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystemCallbacks.h"
84#include "third_party/WebKit/Source/WebKit/chromium/public/WebFindOptions.h"
85#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement.h"
86#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h"
87#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
88#include "third_party/WebKit/Source/WebKit/chromium/public/WebGraphicsContext3D.h"
89#include "third_party/WebKit/Source/WebKit/chromium/public/WebHistoryItem.h"
90#include "third_party/WebKit/Source/WebKit/chromium/public/WebImage.h"
91#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h"
[email protected]69f110d62011-03-17 19:01:1492#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerAction.h"
[email protected]232a5812011-03-04 22:42:0893#include "third_party/WebKit/Source/WebKit/chromium/public/WebNetworkStateNotifier.h"
[email protected]8bd0fe62011-01-17 06:44:3794#include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeList.h"
[email protected]8bd0fe62011-01-17 06:44:3795#include "third_party/WebKit/Source/WebKit/chromium/public/WebPlugin.h"
96#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
97#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginDocument.h"
98#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h"
99#include "third_party/WebKit/Source/WebKit/chromium/public/WebPoint.h"
100#include "third_party/WebKit/Source/WebKit/chromium/public/WebRange.h"
101#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
102#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h"
103#include "third_party/WebKit/Source/WebKit/chromium/public/WebSearchableFormData.h"
104#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
[email protected]20dc3cad2011-04-20 17:27:17105#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h"
[email protected]8bd0fe62011-01-17 06:44:37106#include "third_party/WebKit/Source/WebKit/chromium/public/WebSettings.h"
107#include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
108#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageNamespace.h"
[email protected]10e5cf12011-04-13 04:10:40109#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageQuotaCallbacks.h"
[email protected]8bd0fe62011-01-17 06:44:37110#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
111#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
112#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h"
113#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h"
114#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"
115#include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
116#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
117#include "third_party/WebKit/Source/WebKit/chromium/public/WebWindowFeatures.h"
[email protected]6fdd4182010-10-14 23:59:26118#include "third_party/skia/include/core/SkBitmap.h"
[email protected]c4a9e932011-03-05 04:05:55119#include "ui/base/message_box_flags.h"
[email protected]08397d52011-02-05 01:53:38120#include "ui/gfx/native_widget_types.h"
121#include "ui/gfx/point.h"
122#include "ui/gfx/rect.h"
[email protected]c4a9e932011-03-05 04:05:55123#include "v8/include/v8.h"
[email protected]80f584d92010-01-21 03:59:04124#include "webkit/appcache/web_application_cache_host_impl.h"
[email protected]25e18f82010-10-27 16:38:43125#include "webkit/glue/alt_error_page_resource_fetcher.h"
[email protected]7a4de7a62010-08-17 18:38:24126#include "webkit/glue/context_menu.h"
[email protected]b1438212010-04-03 00:30:59127#include "webkit/glue/form_data.h"
[email protected]95056b582010-02-18 01:29:24128#include "webkit/glue/form_field.h"
[email protected]95056b582010-02-18 01:29:24129#include "webkit/glue/glue_serialize.h"
[email protected]85cc78c2010-05-04 18:30:09130#include "webkit/glue/media/video_renderer_impl.h"
[email protected]4d51d5bf2010-07-26 18:48:26131#include "webkit/glue/password_form_dom_manager.h"
[email protected]85cc78c2010-05-04 18:30:09132#include "webkit/glue/site_isolation_metrics.h"
[email protected]7a4de7a62010-08-17 18:38:24133#include "webkit/glue/webaccessibility.h"
initial.commit09911bf2008-07-26 23:55:29134#include "webkit/glue/webdropdata.h"
[email protected]a6939ca42011-02-18 17:58:07135#include "webkit/glue/webkit_constants.h"
initial.commit09911bf2008-07-26 23:55:29136#include "webkit/glue/webkit_glue.h"
[email protected]add51772009-06-11 18:25:17137#include "webkit/glue/webmediaplayer_impl.h"
[email protected]191eb3f72010-12-21 06:27:50138#include "webkit/plugins/npapi/default_plugin_shared.h"
139#include "webkit/plugins/npapi/plugin_list.h"
140#include "webkit/plugins/npapi/webplugin_delegate.h"
141#include "webkit/plugins/npapi/webplugin_delegate_impl.h"
142#include "webkit/plugins/npapi/webplugin_impl.h"
143#include "webkit/plugins/npapi/webview_plugin.h"
[email protected]0bd753682010-12-16 18:15:52144#include "webkit/plugins/ppapi/ppapi_webplugin_impl.h"
initial.commit09911bf2008-07-26 23:55:29145
[email protected]6c8afae52009-01-22 02:24:57146#if defined(OS_WIN)
147// TODO(port): these files are currently Windows only because they concern:
[email protected]6c8afae52009-01-22 02:24:57148// * theming
[email protected]08397d52011-02-05 01:53:38149#include "ui/gfx/native_theme_win.h"
[email protected]6981f7f2010-03-09 00:53:03150#elif defined(USE_X11)
[email protected]8bd0fe62011-01-17 06:44:37151#include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebRenderTheme.h"
[email protected]42e5c862011-04-07 22:13:51152#include "ui/gfx/native_theme.h"
[email protected]78043bdd2010-04-05 18:45:33153#elif defined(OS_MACOSX)
154#include "skia/ext/skia_utils_mac.h"
[email protected]6c8afae52009-01-22 02:24:57155#endif
156
[email protected]c7287a92009-11-04 20:06:15157using WebKit::WebAccessibilityCache;
[email protected]9892b472010-09-16 00:23:42158using WebKit::WebAccessibilityNotification;
[email protected]cc0445f2009-10-13 16:09:08159using WebKit::WebAccessibilityObject;
[email protected]035545f2010-04-09 13:10:21160using WebKit::WebApplicationCacheHost;
161using WebKit::WebApplicationCacheHostClient;
[email protected]6fdd4182010-10-14 23:59:26162using WebKit::WebCString;
[email protected]1c83eb42009-09-11 21:08:41163using WebKit::WebColor;
164using WebKit::WebColorName;
[email protected]0dea3ea2009-03-31 23:30:59165using WebKit::WebConsoleMessage;
[email protected]79e37442009-10-09 18:17:44166using WebKit::WebContextMenuData;
[email protected]b921cfd22010-02-25 16:57:51167using WebKit::WebCookieJar;
[email protected]e6f546c32009-07-01 17:12:55168using WebKit::WebData;
[email protected]726985e22009-06-18 21:09:28169using WebKit::WebDataSource;
[email protected]5bc8fe92010-03-11 18:19:00170using WebKit::WebDocument;
[email protected]e80c73b2009-04-07 23:24:58171using WebKit::WebDragData;
[email protected]1d9f4132009-09-08 17:29:25172using WebKit::WebDragOperation;
173using WebKit::WebDragOperationsMask;
[email protected]79dbc662009-09-04 05:42:51174using WebKit::WebEditingAction;
[email protected]9b66f34bf2010-10-27 20:45:51175using WebKit::WebElement;
[email protected]caf706f2010-10-26 17:54:08176using WebKit::WebExternalPopupMenu;
177using WebKit::WebExternalPopupMenuClient;
[email protected]cdaf8d02010-03-30 19:52:47178using WebKit::WebFileChooserCompletion;
[email protected]2b06a992010-08-21 05:48:22179using WebKit::WebFileSystem;
180using WebKit::WebFileSystemCallbacks;
[email protected]6069da8c2009-10-20 20:33:49181using WebKit::WebFindOptions;
[email protected]b1438212010-04-03 00:30:59182using WebKit::WebFormControlElement;
[email protected]979c28b2009-11-07 01:30:48183using WebKit::WebFormElement;
[email protected]dd7daa82009-08-10 05:46:45184using WebKit::WebFrame;
[email protected]ca948a22009-06-25 19:36:17185using WebKit::WebHistoryItem;
[email protected]c27ae592010-03-18 15:24:41186using WebKit::WebImage;
[email protected]e6efd022010-03-31 09:34:50187using WebKit::WebInputElement;
[email protected]3d9689372009-09-10 04:29:17188using WebKit::WebMediaPlayer;
[email protected]952cb702009-10-07 05:50:28189using WebKit::WebMediaPlayerAction;
[email protected]3d9689372009-09-10 04:29:17190using WebKit::WebMediaPlayerClient;
[email protected]4873c7d2009-07-16 06:36:28191using WebKit::WebNavigationPolicy;
[email protected]726985e22009-06-18 21:09:28192using WebKit::WebNavigationType;
[email protected]232a5812011-03-04 22:42:08193using WebKit::WebNetworkStateNotifier;
[email protected]79dbc662009-09-04 05:42:51194using WebKit::WebNode;
[email protected]3d9689372009-09-10 04:29:17195using WebKit::WebPlugin;
[email protected]00152e92010-07-19 11:47:40196using WebKit::WebPluginContainer;
[email protected]24a7f3c2010-03-25 08:26:49197using WebKit::WebPluginDocument;
[email protected]aad51d1c2010-08-05 08:38:09198using WebKit::WebPluginParams;
[email protected]48c9cf2d2009-09-16 16:47:52199using WebKit::WebPoint;
[email protected]88efb7ec2009-07-14 16:32:59200using WebKit::WebPopupMenuInfo;
[email protected]79dbc662009-09-04 05:42:51201using WebKit::WebRange;
[email protected]b3f2b912009-04-09 16:18:52202using WebKit::WebRect;
[email protected]4f999132009-03-31 18:08:40203using WebKit::WebScriptSource;
[email protected]ce0e250d2009-10-23 21:00:35204using WebKit::WebSearchableFormData;
[email protected]e3d60e5d2009-09-25 21:08:29205using WebKit::WebSecurityOrigin;
[email protected]20dc3cad2011-04-20 17:27:17206using WebKit::WebSecurityPolicy;
[email protected]2fab253a2009-08-17 23:00:59207using WebKit::WebSettings;
[email protected]9c00f002009-11-05 22:37:42208using WebKit::WebSharedWorker;
[email protected]8649fb32009-06-26 17:51:02209using WebKit::WebSize;
[email protected]bd92c3a2010-01-13 05:02:34210using WebKit::WebStorageNamespace;
[email protected]10e5cf12011-04-13 04:10:40211using WebKit::WebStorageQuotaCallbacks;
212using WebKit::WebStorageQuotaError;
213using WebKit::WebStorageQuotaType;
[email protected]726985e22009-06-18 21:09:28214using WebKit::WebString;
[email protected]79dbc662009-09-04 05:42:51215using WebKit::WebTextAffinity;
[email protected]de570ef2009-07-29 18:27:52216using WebKit::WebTextDirection;
[email protected]726985e22009-06-18 21:09:28217using WebKit::WebURL;
218using WebKit::WebURLError;
219using WebKit::WebURLRequest;
220using WebKit::WebURLResponse;
[email protected]4873c7d2009-07-16 06:36:28221using WebKit::WebVector;
[email protected]50ae00ef2009-10-19 05:11:03222using WebKit::WebView;
[email protected]4873c7d2009-07-16 06:36:28223using WebKit::WebWidget;
[email protected]6fdd4182010-10-14 23:59:26224using WebKit::WebWindowFeatures;
[email protected]27ba8532009-04-24 20:22:43225using WebKit::WebWorker;
226using WebKit::WebWorkerClient;
[email protected]6fdd4182010-10-14 23:59:26227using appcache::WebApplicationCacheHostImpl;
228using base::Time;
229using base::TimeDelta;
230using webkit_glue::AltErrorPageResourceFetcher;
[email protected]6fdd4182010-10-14 23:59:26231using webkit_glue::FormField;
[email protected]6fdd4182010-10-14 23:59:26232using webkit_glue::PasswordForm;
233using webkit_glue::PasswordFormDomManager;
[email protected]bb461532010-11-26 21:50:23234using webkit_glue::ResourceFetcher;
[email protected]6fdd4182010-10-14 23:59:26235using webkit_glue::SiteIsolationMetrics;
236using webkit_glue::WebAccessibility;
[email protected]e1acf6f2008-10-27 20:43:33237
initial.commit09911bf2008-07-26 23:55:29238//-----------------------------------------------------------------------------
239
[email protected]3354d3e2010-06-10 19:53:02240typedef std::map<WebKit::WebView*, RenderView*> ViewMap;
[email protected]625332e02010-12-14 07:48:49241static base::LazyInstance<ViewMap> g_view_map(base::LINKER_INITIALIZED);
[email protected]3354d3e2010-06-10 19:53:02242
[email protected]882daa92009-11-05 16:31:31243// Time, in seconds, we delay before sending content state changes (such as form
244// state and scroll position) to the browser. We delay sending changes to avoid
245// spamming the browser.
246// To avoid having tab/session restore require sending a message to get the
247// current content state during tab closing we use a shorter timeout for the
248// foreground renderer. This means there is a small window of time from which
249// content state is modified and not sent to session restore, but this is
250// better than having to wake up all renderers during shutdown.
251static const int kDelaySecondsForContentStateSyncHidden = 5;
252static const int kDelaySecondsForContentStateSync = 1;
initial.commit09911bf2008-07-26 23:55:29253
[email protected]0aa55312008-10-17 21:53:08254// The maximum number of popups that can be spawned from one page.
255static const int kMaximumNumberOfUnacknowledgedPopups = 25;
256
[email protected]6fdd4182010-10-14 23:59:26257static const char kBackForwardNavigationScheme[] = "history";
[email protected]50b691c2008-10-31 19:08:35258
[email protected]726985e22009-06-18 21:09:28259static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
260 WebVector<WebURL> urls;
261 ds->redirectChain(urls);
262 result->reserve(urls.size());
263 for (size_t i = 0; i < urls.size(); ++i)
264 result->push_back(urls[i]);
265}
266
[email protected]54ec7f82010-10-21 22:32:51267static bool WebAccessibilityNotificationToViewHostMsg(
268 WebAccessibilityNotification notification,
[email protected]fffaf972011-03-24 01:34:35269 ViewHostMsg_AccessibilityNotification_Type::Value* type) {
[email protected]54ec7f82010-10-21 22:32:51270 switch (notification) {
271 case WebKit::WebAccessibilityNotificationCheckedStateChanged:
[email protected]fffaf972011-03-24 01:34:35272 *type = ViewHostMsg_AccessibilityNotification_Type::
[email protected]54ec7f82010-10-21 22:32:51273 NOTIFICATION_TYPE_CHECK_STATE_CHANGED;
274 break;
275 case WebKit::WebAccessibilityNotificationChildrenChanged:
[email protected]fffaf972011-03-24 01:34:35276 *type = ViewHostMsg_AccessibilityNotification_Type::
[email protected]54ec7f82010-10-21 22:32:51277 NOTIFICATION_TYPE_CHILDREN_CHANGED;
278 break;
279 case WebKit::WebAccessibilityNotificationFocusedUIElementChanged:
[email protected]fffaf972011-03-24 01:34:35280 *type = ViewHostMsg_AccessibilityNotification_Type::
[email protected]54ec7f82010-10-21 22:32:51281 NOTIFICATION_TYPE_FOCUS_CHANGED;
282 break;
283 case WebKit::WebAccessibilityNotificationLoadComplete:
[email protected]fffaf972011-03-24 01:34:35284 *type = ViewHostMsg_AccessibilityNotification_Type::
[email protected]54ec7f82010-10-21 22:32:51285 NOTIFICATION_TYPE_LOAD_COMPLETE;
286 break;
287 case WebKit::WebAccessibilityNotificationValueChanged:
[email protected]fffaf972011-03-24 01:34:35288 *type = ViewHostMsg_AccessibilityNotification_Type::
[email protected]54ec7f82010-10-21 22:32:51289 NOTIFICATION_TYPE_VALUE_CHANGED;
290 break;
291 case WebKit::WebAccessibilityNotificationSelectedTextChanged:
[email protected]fffaf972011-03-24 01:34:35292 *type = ViewHostMsg_AccessibilityNotification_Type::
[email protected]54ec7f82010-10-21 22:32:51293 NOTIFICATION_TYPE_SELECTED_TEXT_CHANGED;
294 break;
295 default:
296 // TODO(ctguil): Support additional webkit notifications.
297 return false;
298 }
299 return true;
300}
301
initial.commit09911bf2008-07-26 23:55:29302///////////////////////////////////////////////////////////////////////////////
303
[email protected]60c42a8c72009-10-09 04:08:59304int32 RenderView::next_page_id_ = 1;
305
[email protected]cdaf8d02010-03-30 19:52:47306struct RenderView::PendingFileChooser {
307 PendingFileChooser(const ViewHostMsg_RunFileChooser_Params& p,
308 WebFileChooserCompletion* c)
309 : params(p),
310 completion(c) {
311 }
312 ViewHostMsg_RunFileChooser_Params params;
313 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback.
314};
315
[email protected]2fab253a2009-08-17 23:00:59316RenderView::RenderView(RenderThreadBase* render_thread,
[email protected]676126f72011-01-15 00:03:51317 gfx::NativeViewId parent_hwnd,
[email protected]c03a6e72011-04-19 21:42:06318 gfx::PluginWindowHandle compositing_surface,
[email protected]676126f72011-01-15 00:03:51319 int32 opener_id,
320 const RendererPreferences& renderer_prefs,
321 const WebPreferences& webkit_prefs,
322 SharedRenderViewCounter* counter,
323 int32 routing_id,
324 int64 session_storage_namespace_id,
325 const string16& frame_name)
[email protected]3e2b375b2010-04-07 17:03:12326 : RenderWidget(render_thread, WebKit::WebPopupTypeNone),
[email protected]676126f72011-01-15 00:03:51327 webkit_preferences_(webkit_prefs),
[email protected]3354d3e2010-06-10 19:53:02328 send_content_state_immediately_(false),
[email protected]81e63782009-02-27 19:35:09329 enabled_bindings_(0),
[email protected]3354d3e2010-06-10 19:53:02330 send_preferred_size_changes_(false),
[email protected]81a34412009-01-05 19:17:24331 is_loading_(false),
[email protected]e75cb49e2009-01-05 23:13:21332 navigation_gesture_(NavigationGestureUnknown),
[email protected]3354d3e2010-06-10 19:53:02333 opened_by_user_gesture_(true),
334 opener_suppressed_(false),
[email protected]81a34412009-01-05 19:17:24335 page_id_(-1),
336 last_page_id_sent_to_browser_(-1),
[email protected]3cc72b12010-03-18 23:03:00337 history_list_offset_(-1),
338 history_list_length_(0),
[email protected]81a34412009-01-05 19:17:24339 has_unload_listener_(false),
[email protected]3354d3e2010-06-10 19:53:02340 target_url_status_(TARGET_NONE),
[email protected]18ca9a6b2010-06-02 19:05:18341 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)),
[email protected]54ec7f82010-10-21 22:32:51342 ALLOW_THIS_IN_INITIALIZER_LIST(accessibility_method_factory_(this)),
[email protected]3354d3e2010-06-10 19:53:02343 ALLOW_THIS_IN_INITIALIZER_LIST(cookie_jar_(this)),
[email protected]676126f72011-01-15 00:03:51344 geolocation_dispatcher_(NULL),
345 speech_input_dispatcher_(NULL),
346 device_orientation_dispatcher_(NULL),
[email protected]54ec7f82010-10-21 22:32:51347 accessibility_ack_pending_(false),
[email protected]cae8c8492011-03-03 11:12:18348 p2p_socket_dispatcher_(NULL),
[email protected]5ee0cfd02011-01-18 05:42:22349 session_storage_namespace_id_(session_storage_namespace_id) {
[email protected]676126f72011-01-15 00:03:51350 routing_id_ = routing_id;
351 if (opener_id != MSG_ROUTING_NONE)
352 opener_id_ = opener_id;
353
[email protected]11fee2332011-03-29 20:36:35354 webwidget_ = WebView::create(this);
355
[email protected]676126f72011-01-15 00:03:51356 if (counter) {
357 shared_popup_counter_ = counter;
358 shared_popup_counter_->data++;
359 decrement_shared_popup_at_destruction_ = true;
360 } else {
361 shared_popup_counter_ = new SharedRenderViewCounter(0);
362 decrement_shared_popup_at_destruction_ = false;
363 }
364
365 notification_provider_ = new NotificationProvider(this);
366
[email protected]676126f72011-01-15 00:03:51367 g_view_map.Get().insert(std::make_pair(webview(), this));
368 webkit_preferences_.Apply(webview());
369 webview()->initializeMainFrame(this);
370 if (!frame_name.empty())
371 webview()->mainFrame()->setName(frame_name);
[email protected]1ee59cb2011-02-23 02:45:51372 webview()->settings()->setMinimumTimerInterval(
373 is_hidden() ? webkit_glue::kBackgroundTabTimerInterval :
374 webkit_glue::kForegroundTabTimerInterval);
[email protected]676126f72011-01-15 00:03:51375
376 OnSetRendererPrefs(renderer_prefs);
377
378 render_thread_->AddRoute(routing_id_, this);
379 // Take a reference on behalf of the RenderThread. This will be balanced
380 // when we receive ViewMsg_Close.
381 AddRef();
382
383 // If this is a popup, we must wait for the CreatingNew_ACK message before
384 // completing initialization. Otherwise, we can finish it now.
385 if (opener_id == MSG_ROUTING_NONE) {
386 did_show_ = true;
[email protected]c03a6e72011-04-19 21:42:06387 CompleteInit(parent_hwnd, compositing_surface);
[email protected]676126f72011-01-15 00:03:51388 }
389
390 host_window_ = parent_hwnd;
391
392 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]676126f72011-01-15 00:03:51393 if (command_line.HasSwitch(switches::kEnableAccessibility))
394 WebAccessibilityCache::enableAccessibility();
395
396 audio_message_filter_ = new AudioMessageFilter(routing_id_);
397 render_thread_->AddFilter(audio_message_filter_);
398
[email protected]a026daa2011-04-20 15:49:51399#if defined(ENABLE_P2P_APIS)
[email protected]9966325b2011-04-18 05:00:10400 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableP2PApi))
[email protected]cae8c8492011-03-03 11:12:18401 p2p_socket_dispatcher_ = new P2PSocketDispatcher(this);
[email protected]a026daa2011-04-20 15:49:51402#endif
[email protected]cae8c8492011-03-03 11:12:18403
[email protected]e48869a2011-04-01 19:56:03404 content::GetContentClient()->renderer()->RenderViewCreated(this);
initial.commit09911bf2008-07-26 23:55:29405}
406
407RenderView::~RenderView() {
[email protected]0aa55312008-10-17 21:53:08408 if (decrement_shared_popup_at_destruction_)
409 shared_popup_counter_->data--;
410
[email protected]a1128322009-10-06 18:38:46411 // If file chooser is still waiting for answer, dispatch empty answer.
[email protected]cdaf8d02010-03-30 19:52:47412 while (!file_chooser_completions_.empty()) {
413 if (file_chooser_completions_.front()->completion) {
414 file_chooser_completions_.front()->completion->didChooseFile(
415 WebVector<WebString>());
416 }
417 file_chooser_completions_.pop_front();
418 }
[email protected]a1128322009-10-06 18:38:46419
[email protected]83dde542009-09-11 20:59:55420#if defined(OS_MACOSX)
[email protected]c36a9b62010-10-14 00:41:11421 // Destroy all fake plugin window handles on the browser side.
422 while (!fake_plugin_window_handles_.empty()) {
423 // Make sure no NULL plugin window handles were inserted into this list.
424 DCHECK(*fake_plugin_window_handles_.begin());
425 // DestroyFakePluginWindowHandle modifies fake_plugin_window_handles_.
426 DestroyFakePluginWindowHandle(*fake_plugin_window_handles_.begin());
427 }
[email protected]83dde542009-09-11 20:59:55428#endif
[email protected]98324892009-09-09 21:16:05429
[email protected]5fb88962009-04-16 19:03:25430 render_thread_->RemoveFilter(audio_message_filter_);
[email protected]60c42a8c72009-10-09 04:08:59431
432#ifndef NDEBUG
433 // Make sure we are no longer referenced by the ViewMap.
[email protected]625332e02010-12-14 07:48:49434 ViewMap* views = g_view_map.Pointer();
[email protected]60c42a8c72009-10-09 04:08:59435 for (ViewMap::iterator it = views->begin(); it != views->end(); ++it)
436 DCHECK_NE(this, it->second) << "Failed to call Close?";
437#endif
[email protected]676126f72011-01-15 00:03:51438
439 FOR_EACH_OBSERVER(RenderViewObserver, observers_, set_render_view(NULL));
440 FOR_EACH_OBSERVER(RenderViewObserver, observers_, OnDestruct());
[email protected]60c42a8c72009-10-09 04:08:59441}
442
443/*static*/
444void RenderView::ForEach(RenderViewVisitor* visitor) {
[email protected]625332e02010-12-14 07:48:49445 ViewMap* views = g_view_map.Pointer();
[email protected]60c42a8c72009-10-09 04:08:59446 for (ViewMap::iterator it = views->begin(); it != views->end(); ++it) {
447 if (!visitor->Visit(it->second))
448 return;
449 }
450}
451
452/*static*/
453RenderView* RenderView::FromWebView(WebView* webview) {
[email protected]625332e02010-12-14 07:48:49454 ViewMap* views = g_view_map.Pointer();
[email protected]60c42a8c72009-10-09 04:08:59455 ViewMap::iterator it = views->find(webview);
456 return it == views->end() ? NULL : it->second;
initial.commit09911bf2008-07-26 23:55:29457}
458
459/*static*/
[email protected]0aa55312008-10-17 21:53:08460RenderView* RenderView::Create(
[email protected]81a34412009-01-05 19:17:24461 RenderThreadBase* render_thread,
[email protected]18bcc3c2009-01-27 21:39:15462 gfx::NativeViewId parent_hwnd,
[email protected]c03a6e72011-04-19 21:42:06463 gfx::PluginWindowHandle compositing_surface,
[email protected]0aa55312008-10-17 21:53:08464 int32 opener_id,
[email protected]80d96fa2009-06-10 22:34:51465 const RendererPreferences& renderer_prefs,
[email protected]0aa55312008-10-17 21:53:08466 const WebPreferences& webkit_prefs,
467 SharedRenderViewCounter* counter,
[email protected]4e6419c2010-01-15 04:50:34468 int32 routing_id,
[email protected]8ab04652010-06-12 02:47:26469 int64 session_storage_namespace_id,
470 const string16& frame_name) {
initial.commit09911bf2008-07-26 23:55:29471 DCHECK(routing_id != MSG_ROUTING_NONE);
[email protected]676126f72011-01-15 00:03:51472 return new RenderView(
473 render_thread,
474 parent_hwnd,
[email protected]c03a6e72011-04-19 21:42:06475 compositing_surface,
[email protected]676126f72011-01-15 00:03:51476 opener_id,
477 renderer_prefs,
478 webkit_prefs,
479 counter,
480 routing_id,
481 session_storage_namespace_id,
482 frame_name); // adds reference
initial.commit09911bf2008-07-26 23:55:29483}
484
[email protected]bb461532010-11-26 21:50:23485// static
initial.commit09911bf2008-07-26 23:55:29486void RenderView::SetNextPageID(int32 next_page_id) {
487 // This method should only be called during process startup, and the given
488 // page id had better not exceed our current next page id!
[email protected]4646f292009-05-20 03:49:05489 DCHECK_EQ(next_page_id_, 1);
initial.commit09911bf2008-07-26 23:55:29490 DCHECK(next_page_id >= next_page_id_);
491 next_page_id_ = next_page_id;
492}
493
[email protected]676126f72011-01-15 00:03:51494void RenderView::AddObserver(RenderViewObserver* observer) {
495 observers_.AddObserver(observer);
496}
497
498void RenderView::RemoveObserver(RenderViewObserver* observer) {
499 observer->set_render_view(NULL);
500 observers_.RemoveObserver(observer);
501}
502
[email protected]70eee342010-11-05 01:59:37503bool RenderView::RendererAccessibilityNotification::ShouldIncludeChildren() {
504 typedef ViewHostMsg_AccessibilityNotification_Params params;
[email protected]a527a022011-02-10 02:32:36505 if (type == WebKit::WebAccessibilityNotificationChildrenChanged ||
506 type == WebKit::WebAccessibilityNotificationLoadComplete) {
[email protected]70eee342010-11-05 01:59:37507 return true;
508 }
509 return false;
510}
511
[email protected]8a3125a712010-08-09 18:58:51512WebKit::WebView* RenderView::webview() const {
[email protected]4d51d5bf2010-07-26 18:48:26513 return static_cast<WebKit::WebView*>(webwidget());
514}
515
[email protected]1a3c3cb2010-12-16 21:03:40516void RenderView::SetReportLoadProgressEnabled(bool enabled) {
517 if (!enabled) {
518 load_progress_tracker_.reset(NULL);
519 return;
520 }
521 if (load_progress_tracker_ == NULL)
522 load_progress_tracker_.reset(new LoadProgressTracker(this));
523}
524
[email protected]a3a8fb6d2009-10-22 20:12:51525void RenderView::PluginCrashed(const FilePath& plugin_path) {
526 Send(new ViewHostMsg_CrashedPlugin(routing_id_, plugin_path));
initial.commit09911bf2008-07-26 23:55:29527}
528
[email protected]aad51d1c2010-08-05 08:38:09529WebPlugin* RenderView::CreatePluginNoCheck(WebFrame* frame,
530 const WebPluginParams& params) {
[email protected]191eb3f72010-12-21 06:27:50531 webkit::npapi::WebPluginInfo info;
[email protected]6fdd4182010-10-14 23:59:26532 bool found;
[email protected]0aed2f52011-03-23 18:06:36533 int content_setting;
[email protected]6fdd4182010-10-14 23:59:26534 std::string mime_type;
535 Send(new ViewHostMsg_GetPluginInfo(
[email protected]c8f73ab2011-01-22 00:05:17536 routing_id_, params.url, frame->top()->url(), params.mimeType.utf8(),
[email protected]0aed2f52011-03-23 18:06:36537 &found, &info, &content_setting, &mime_type));
[email protected]b83ff222011-01-24 17:37:12538 if (!found || !webkit::npapi::IsPluginEnabled(info))
[email protected]aad51d1c2010-08-05 08:38:09539 return NULL;
[email protected]1a78d9f32010-12-08 06:38:45540
[email protected]96dcc1762011-04-04 16:01:09541 bool pepper_plugin_was_registered = false;
[email protected]0bd753682010-12-16 18:15:52542 scoped_refptr<webkit::ppapi::PluginModule> pepper_module(
[email protected]96dcc1762011-04-04 16:01:09543 pepper_delegate_.CreatePepperPlugin(info.path,
544 &pepper_plugin_was_registered));
545 if (pepper_plugin_was_registered) {
546 if (pepper_module)
547 return CreatePepperPlugin(frame, params, info.path, pepper_module.get());
548 return NULL;
549 }
[email protected]1a78d9f32010-12-08 06:38:45550 return CreateNPAPIPlugin(frame, params, info.path, mime_type);
[email protected]aad51d1c2010-08-05 08:38:09551}
552
[email protected]d8fd6fa2010-02-01 15:54:26553void RenderView::RegisterPluginDelegate(WebPluginDelegateProxy* delegate) {
554 plugin_delegates_.insert(delegate);
[email protected]49232292010-09-03 19:07:30555 // If the renderer is visible, set initial visibility and focus state.
556 if (!is_hidden()) {
[email protected]784ea1ab2010-09-18 00:02:34557#if defined(OS_MACOSX)
[email protected]49232292010-09-03 19:07:30558 delegate->SetContainerVisibility(true);
559 if (webview() && webview()->isActive())
560 delegate->SetWindowFocus(true);
[email protected]784ea1ab2010-09-18 00:02:34561#endif
[email protected]49232292010-09-03 19:07:30562 }
[email protected]784ea1ab2010-09-18 00:02:34563 // Plugins start assuming the content has focus (so that they work in
564 // environments where RenderView isn't hosting them), so we always have to
565 // set the initial state. See webplugin_delegate_impl.h for details.
566 delegate->SetContentAreaFocus(has_focus());
[email protected]d8fd6fa2010-02-01 15:54:26567}
568
569void RenderView::UnregisterPluginDelegate(WebPluginDelegateProxy* delegate) {
570 plugin_delegates_.erase(delegate);
571}
[email protected]d8fd6fa2010-02-01 15:54:26572
[email protected]a95986a82010-12-24 06:19:28573bool RenderView::OnMessageReceived(const IPC::Message& message) {
[email protected]26aa0482009-09-30 16:55:27574 WebFrame* main_frame = webview() ? webview()->mainFrame() : NULL;
[email protected]a9f607e2009-10-23 19:59:27575 if (main_frame)
[email protected]38b592902011-04-16 02:08:42576 content::GetContentClient()->SetActiveURL(main_frame->url());
[email protected]f8b6b6f2009-03-10 16:48:26577
[email protected]676126f72011-01-15 00:03:51578 ObserverListBase<RenderViewObserver>::Iterator it(observers_);
579 RenderViewObserver* observer;
580 while ((observer = it.GetNext()) != NULL)
581 if (observer->OnMessageReceived(message))
582 return true;
[email protected]b2abac72009-02-26 12:39:28583
[email protected]a95986a82010-12-24 06:19:28584 bool handled = true;
initial.commit09911bf2008-07-26 23:55:29585 IPC_BEGIN_MESSAGE_MAP(RenderView, message)
initial.commit09911bf2008-07-26 23:55:29586 IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
587 IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
[email protected]1dda4022010-01-28 18:24:56588 IPC_MESSAGE_HANDLER(ViewMsg_ReloadFrame, OnReloadFrame)
initial.commit09911bf2008-07-26 23:55:29589 IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)
590 IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)
591 IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)
592 IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)
[email protected]c0cc3092009-09-12 08:27:27593#if defined(OS_MACOSX)
[email protected]a954bf72009-09-12 07:30:35594 IPC_MESSAGE_HANDLER(ViewMsg_CopyToFindPboard, OnCopyToFindPboard)
[email protected]c0cc3092009-09-12 08:27:27595#endif
initial.commit09911bf2008-07-26 23:55:29596 IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)
597 IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)
598 IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)
599 IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)
600 IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
[email protected]4b59ae602009-06-23 20:58:15601 IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand)
initial.commit09911bf2008-07-26 23:55:29602 IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
[email protected]24a7f3c2010-03-25 08:26:49603 IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
604 IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)
[email protected]630e26b2008-10-14 22:55:17605 IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
[email protected]d0b8d092010-10-25 04:05:17606 IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevel, OnSetZoomLevel)
[email protected]9d797f32010-04-23 07:17:54607 IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForLoadingURL,
608 OnSetZoomLevelForLoadingURL)
initial.commit09911bf2008-07-26 23:55:29609 IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
[email protected]a697f4c2009-09-14 22:30:18610 IPC_MESSAGE_HANDLER(ViewMsg_ResetPageEncodingToDefault,
611 OnResetPageEncodingToDefault)
initial.commit09911bf2008-07-26 23:55:29612 IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
[email protected]1810e132009-03-24 23:35:48613 IPC_MESSAGE_HANDLER(ViewMsg_CSSInsertRequest, OnCSSInsertRequest)
initial.commit09911bf2008-07-26 23:55:29614 IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)
[email protected]59f4f2fa2011-03-23 01:00:55615 IPC_MESSAGE_HANDLER(DragMsg_TargetDragEnter, OnDragTargetDragEnter)
616 IPC_MESSAGE_HANDLER(DragMsg_TargetDragOver, OnDragTargetDragOver)
617 IPC_MESSAGE_HANDLER(DragMsg_TargetDragLeave, OnDragTargetDragLeave)
618 IPC_MESSAGE_HANDLER(DragMsg_TargetDrop, OnDragTargetDrop)
619 IPC_MESSAGE_HANDLER(DragMsg_SourceEndedOrMoved, OnDragSourceEndedOrMoved)
620 IPC_MESSAGE_HANDLER(DragMsg_SourceSystemDragEnded,
621 OnDragSourceSystemDragEnded)
[email protected]18cb2572008-08-21 20:34:45622 IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)
[email protected]d0980792011-02-13 19:41:40623 IPC_MESSAGE_HANDLER(ViewMsg_SetWebUIProperty, OnSetWebUIProperty)
initial.commit09911bf2008-07-26 23:55:29624 IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)
[email protected]9b66f34bf2010-10-27 20:45:51625 IPC_MESSAGE_HANDLER(ViewMsg_ScrollFocusedEditableNodeIntoView,
626 OnScrollFocusedEditableNodeIntoView)
initial.commit09911bf2008-07-26 23:55:29627 IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)
628 IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
629 IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)
630 IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)
[email protected]600ea402011-04-12 00:01:51631 IPC_MESSAGE_HANDLER(ViewMsg_EnumerateDirectoryResponse,
632 OnEnumerateDirectoryResponse)
initial.commit09911bf2008-07-26 23:55:29633 IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
[email protected]9b18a84f2010-06-10 15:54:04634 IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnShouldClose)
initial.commit09911bf2008-07-26 23:55:29635 IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
636 IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)
[email protected]0aa55312008-10-17 21:53:08637 IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
638 OnDisassociateFromPopupCount)
[email protected]30f75e62009-02-25 22:01:00639 IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
[email protected]05d478752009-04-08 23:38:16640 IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
[email protected]699ab0d2009-04-23 23:19:14641 IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
[email protected]ab32b16c2009-10-16 14:57:25642 IPC_MESSAGE_HANDLER(ViewMsg_EnablePreferredSizeChangedMode,
643 OnEnablePreferredSizeChangedMode)
[email protected]cda45c02010-02-25 19:28:10644 IPC_MESSAGE_HANDLER(ViewMsg_DisableScrollbarsForSmallWindows,
645 OnDisableScrollbarsForSmallWindows)
[email protected]80d96fa2009-06-10 22:34:51646 IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
[email protected]581b87eb2009-07-23 23:06:56647 IPC_MESSAGE_HANDLER(ViewMsg_MediaPlayerActionAt, OnMediaPlayerActionAt)
[email protected]8c66c5a2009-07-22 17:26:34648 IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
[email protected]6ce7abc52010-02-02 18:40:14649#if defined(OS_MACOSX)
650 IPC_MESSAGE_HANDLER(ViewMsg_SetWindowVisibility, OnSetWindowVisibility)
[email protected]1e6e3c992010-02-08 15:52:13651 IPC_MESSAGE_HANDLER(ViewMsg_WindowFrameChanged, OnWindowFrameChanged)
[email protected]b7f75862011-01-21 21:15:13652 IPC_MESSAGE_HANDLER(ViewMsg_PluginImeCompositionCompleted,
653 OnPluginImeCompositionCompleted)
[email protected]6ce7abc52010-02-02 18:40:14654#endif
[email protected]446705872009-09-10 07:22:48655 IPC_MESSAGE_HANDLER(ViewMsg_SetEditCommandsForNextKeyEvent,
[email protected]a0c7153e2009-12-09 14:36:33656 OnSetEditCommandsForNextKeyEvent)
[email protected]a0c7153e2009-12-09 14:36:33657 IPC_MESSAGE_HANDLER(ViewMsg_CustomContextMenuAction,
658 OnCustomContextMenuAction)
[email protected]dea2d372010-09-25 06:41:14659 IPC_MESSAGE_HANDLER(ViewMsg_EnableAccessibility, OnEnableAccessibility)
[email protected]aef92842010-05-21 16:54:36660 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityFocus, OnSetAccessibilityFocus)
661 IPC_MESSAGE_HANDLER(ViewMsg_AccessibilityDoDefaultAction,
662 OnAccessibilityDoDefaultAction)
[email protected]9892b472010-09-16 00:23:42663 IPC_MESSAGE_HANDLER(ViewMsg_AccessibilityNotifications_ACK,
664 OnAccessibilityNotificationsAck)
[email protected]27a9ef32010-09-10 04:06:24665 IPC_MESSAGE_HANDLER(ViewMsg_AsyncOpenFile_ACK, OnAsyncFileOpened)
[email protected]eb415bf0e2011-04-14 02:45:42666 IPC_MESSAGE_HANDLER(ViewMsg_PpapiBrokerChannelCreated,
667 OnPpapiBrokerChannelCreated)
[email protected]caf706f2010-10-26 17:54:08668#if defined(OS_MACOSX)
669 IPC_MESSAGE_HANDLER(ViewMsg_SelectPopupMenuItem, OnSelectPopupMenuItem)
670#endif
[email protected]521b2482011-01-15 00:10:10671 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed)
[email protected]232a5812011-03-04 22:42:08672 IPC_MESSAGE_HANDLER(ViewMsg_NetworkStateChanged, OnNetworkStateChanged)
[email protected]f0557932011-01-25 20:20:51673 // TODO(viettrungluu): Move to a separate message filter.
674#if defined(ENABLE_FLAPPER_HACKS)
675 IPC_MESSAGE_HANDLER(PepperMsg_ConnectTcpACK, OnConnectTcpACK)
676#endif
677
initial.commit09911bf2008-07-26 23:55:29678 // Have the super handle all other messages.
[email protected]a95986a82010-12-24 06:19:28679 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message))
initial.commit09911bf2008-07-26 23:55:29680 IPC_END_MESSAGE_MAP()
[email protected]a95986a82010-12-24 06:19:28681 return handled;
initial.commit09911bf2008-07-26 23:55:29682}
683
initial.commit09911bf2008-07-26 23:55:29684void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {
685 if (!webview())
686 return;
687
[email protected]3cc72b12010-03-18 23:03:00688 history_list_offset_ = params.current_history_list_offset;
689 history_list_length_ = params.current_history_list_length;
690
[email protected]38b592902011-04-16 02:08:42691 content::GetContentClient()->SetActiveURL(params.url);
initial.commit09911bf2008-07-26 23:55:29692
[email protected]ecbf10d2010-02-18 13:03:29693 bool is_reload =
[email protected]2c5569662011-03-22 20:45:02694 params.navigation_type == ViewMsg_Navigate_Type::RELOAD ||
695 params.navigation_type == ViewMsg_Navigate_Type::RELOAD_IGNORING_CACHE;
initial.commit09911bf2008-07-26 23:55:29696
[email protected]26aa0482009-09-30 16:55:27697 WebFrame* main_frame = webview()->mainFrame();
[email protected]dd7daa82009-08-10 05:46:45698 if (is_reload && main_frame->currentHistoryItem().isNull()) {
initial.commit09911bf2008-07-26 23:55:29699 // We cannot reload if we do not have any history state. This happens, for
700 // example, when recovering from a crash. Our workaround here is a bit of
701 // a hack since it means that reload after a crashed tab does not cause an
702 // end-to-end cache validation.
703 is_reload = false;
704 }
705
[email protected]77f17a82009-05-21 04:42:54706 // A navigation resulting from loading a javascript URL should not be treated
707 // as a browser initiated event. Instead, we want it to look as if the page
708 // initiated any load resulting from JS execution.
709 if (!params.url.SchemeIs(chrome::kJavaScriptScheme)) {
[email protected]5e369672009-11-03 23:48:30710 NavigationState* state = NavigationState::CreateBrowserInitiated(
[email protected]3cc72b12010-03-18 23:03:00711 params.page_id,
712 params.pending_history_list_offset,
713 params.transition,
714 params.request_time);
[email protected]2c5569662011-03-22 20:45:02715 if (params.navigation_type == ViewMsg_Navigate_Type::RESTORE) {
[email protected]5e369672009-11-03 23:48:30716 // We're doing a load of a page that was restored from the last session.
717 // By default this prefers the cache over loading (LOAD_PREFERRING_CACHE)
718 // which can result in stale data for pages that are set to expire. We
719 // explicitly override that by setting the policy here so that as
720 // necessary we load from the network.
721 state->set_cache_policy_override(WebURLRequest::UseProtocolCachePolicy);
722 }
723 pending_navigation_state_.reset(state);
[email protected]77f17a82009-05-21 04:42:54724 }
initial.commit09911bf2008-07-26 23:55:29725
[email protected]a7ccc4d2010-01-27 08:14:48726 NavigationState* navigation_state = pending_navigation_state_.get();
727
[email protected]48a5c772011-04-18 23:50:50728 if (navigation_state) {
729 // New loads need to reset the error page fetcher. Otherwise if there is an
730 // outstanding error page fetcher it may complete and clobber the current
731 // page load.
732 navigation_state->set_alt_error_page_fetcher(NULL);
733 }
734
[email protected]04d3c6e2009-05-22 17:00:13735 // If we are reloading, then WebKit will use the history state of the current
736 // page, so we should just ignore any given history state. Otherwise, if we
737 // have history state, then we need to navigate to it, which corresponds to a
738 // back/forward navigation event.
[email protected]e6f546c32009-07-01 17:12:55739 if (is_reload) {
[email protected]a7ccc4d2010-01-27 08:14:48740 if (navigation_state)
741 navigation_state->set_load_type(NavigationState::RELOAD);
[email protected]ecbf10d2010-02-18 13:03:29742 bool ignore_cache = (params.navigation_type ==
[email protected]2c5569662011-03-22 20:45:02743 ViewMsg_Navigate_Type::RELOAD_IGNORING_CACHE);
[email protected]ecbf10d2010-02-18 13:03:29744 main_frame->reload(ignore_cache);
[email protected]e6f546c32009-07-01 17:12:55745 } else if (!params.state.empty()) {
[email protected]04d3c6e2009-05-22 17:00:13746 // We must know the page ID of the page we are navigating back to.
[email protected]f929f2f22009-06-12 16:56:58747 DCHECK_NE(params.page_id, -1);
[email protected]a7ccc4d2010-01-27 08:14:48748 if (navigation_state)
749 navigation_state->set_load_type(NavigationState::HISTORY_LOAD);
[email protected]dd7daa82009-08-10 05:46:45750 main_frame->loadHistoryItem(
[email protected]ca948a22009-06-25 19:36:17751 webkit_glue::HistoryItemFromString(params.state));
[email protected]04d3c6e2009-05-22 17:00:13752 } else {
753 // Navigate to the given URL.
[email protected]726985e22009-06-18 21:09:28754 WebURLRequest request(params.url);
initial.commit09911bf2008-07-26 23:55:29755
[email protected]e6f546c32009-07-01 17:12:55756 // A session history navigation should have been accompanied by state.
757 DCHECK_EQ(params.page_id, -1);
[email protected]04d3c6e2009-05-22 17:00:13758
[email protected]dd7daa82009-08-10 05:46:45759 if (main_frame->isViewSourceModeEnabled())
[email protected]e6f546c32009-07-01 17:12:55760 request.setCachePolicy(WebURLRequest::ReturnCacheDataElseLoad);
[email protected]04d3c6e2009-05-22 17:00:13761
[email protected]726985e22009-06-18 21:09:28762 if (params.referrer.is_valid()) {
[email protected]20dc3cad2011-04-20 17:27:17763 if (!WebSecurityPolicy::shouldHideReferrer(
764 params.url,
765 WebString::fromUTF8(params.referrer.spec()))) {
766 request.setHTTPHeaderField(WebString::fromUTF8("Referer"),
767 WebString::fromUTF8(params.referrer.spec()));
768 }
[email protected]726985e22009-06-18 21:09:28769 }
[email protected]04d3c6e2009-05-22 17:00:13770
[email protected]52c68652010-12-07 17:47:04771 if (!params.extra_headers.empty()) {
772 for (net::HttpUtil::HeadersIterator i(params.extra_headers.begin(),
773 params.extra_headers.end(), "\n");
774 i.GetNext(); ) {
775 request.addHTTPHeaderField(WebString::fromUTF8(i.name()),
776 WebString::fromUTF8(i.values()));
777 }
778 }
779
[email protected]16e923d2011-04-30 00:41:44780 if (navigation_state)
781 navigation_state->set_load_type(NavigationState::NORMAL_LOAD);
[email protected]dd7daa82009-08-10 05:46:45782 main_frame->loadRequest(request);
[email protected]c0588052008-10-27 23:01:50783 }
784
[email protected]77f17a82009-05-21 04:42:54785 // In case LoadRequest failed before DidCreateDataSource was called.
786 pending_navigation_state_.reset();
initial.commit09911bf2008-07-26 23:55:29787}
788
789// Stop loading the current page
790void RenderView::OnStop() {
791 if (webview())
[email protected]b4bb2502009-10-01 22:35:27792 webview()->mainFrame()->stopLoading();
initial.commit09911bf2008-07-26 23:55:29793}
794
[email protected]ecbf10d2010-02-18 13:03:29795// Reload current focused frame.
796// E.g. called by right-clicking on the frame and picking "reload this frame".
[email protected]1dda4022010-01-28 18:24:56797void RenderView::OnReloadFrame() {
[email protected]ecbf10d2010-02-18 13:03:29798 if (webview() && webview()->focusedFrame()) {
799 // We always obey the cache (ignore_cache=false) here.
800 // TODO(evanm): perhaps we could allow shift-clicking the menu item to do
801 // a cache-ignoring reload of the frame.
802 webview()->focusedFrame()->reload(false);
803 }
[email protected]1dda4022010-01-28 18:24:56804}
805
initial.commit09911bf2008-07-26 23:55:29806void RenderView::OnCopyImageAt(int x, int y) {
[email protected]26aa0482009-09-30 16:55:27807 webview()->copyImageAt(WebPoint(x, y));
initial.commit09911bf2008-07-26 23:55:29808}
809
[email protected]68b1e922009-06-23 16:00:25810void RenderView::OnExecuteEditCommand(const std::string& name,
811 const std::string& value) {
[email protected]26aa0482009-09-30 16:55:27812 if (!webview() || !webview()->focusedFrame())
[email protected]68b1e922009-06-23 16:00:25813 return;
814
[email protected]26aa0482009-09-30 16:55:27815 webview()->focusedFrame()->executeCommand(
[email protected]dd7daa82009-08-10 05:46:45816 WebString::fromUTF8(name), WebString::fromUTF8(value));
[email protected]68b1e922009-06-23 16:00:25817}
818
initial.commit09911bf2008-07-26 23:55:29819void RenderView::OnUpdateTargetURLAck() {
820 // Check if there is a targeturl waiting to be sent.
821 if (target_url_status_ == TARGET_PENDING) {
822 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_,
823 pending_target_url_));
824 }
825
826 target_url_status_ = TARGET_NONE;
827}
828
829void RenderView::OnUndo() {
830 if (!webview())
831 return;
832
[email protected]26aa0482009-09-30 16:55:27833 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Undo"));
initial.commit09911bf2008-07-26 23:55:29834}
835
836void RenderView::OnRedo() {
837 if (!webview())
838 return;
839
[email protected]26aa0482009-09-30 16:55:27840 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Redo"));
initial.commit09911bf2008-07-26 23:55:29841}
842
843void RenderView::OnCut() {
844 if (!webview())
845 return;
846
[email protected]26aa0482009-09-30 16:55:27847 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Cut"));
initial.commit09911bf2008-07-26 23:55:29848}
849
850void RenderView::OnCopy() {
851 if (!webview())
852 return;
853
[email protected]26aa0482009-09-30 16:55:27854 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Copy"));
initial.commit09911bf2008-07-26 23:55:29855}
856
[email protected]c0cc3092009-09-12 08:27:27857#if defined(OS_MACOSX)
[email protected]a954bf72009-09-12 07:30:35858void RenderView::OnCopyToFindPboard() {
859 if (!webview())
860 return;
861
862 // Since the find pasteboard supports only plain text, this can be simpler
863 // than the |OnCopy()| case.
[email protected]26aa0482009-09-30 16:55:27864 WebFrame* frame = webview()->focusedFrame();
[email protected]a954bf72009-09-12 07:30:35865 if (frame->hasSelection()) {
866 string16 selection = frame->selectionAsText();
867 RenderThread::current()->Send(
[email protected]7e3589742011-03-10 18:49:17868 new ClipboardHostMsg_FindPboardWriteStringAsync(selection));
[email protected]a954bf72009-09-12 07:30:35869 }
[email protected]a954bf72009-09-12 07:30:35870}
[email protected]c0cc3092009-09-12 08:27:27871#endif
[email protected]a954bf72009-09-12 07:30:35872
initial.commit09911bf2008-07-26 23:55:29873void RenderView::OnPaste() {
874 if (!webview())
875 return;
876
[email protected]26aa0482009-09-30 16:55:27877 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Paste"));
initial.commit09911bf2008-07-26 23:55:29878}
879
[email protected]2a3a7762009-10-19 19:17:32880void RenderView::OnReplace(const string16& text) {
initial.commit09911bf2008-07-26 23:55:29881 if (!webview())
882 return;
883
[email protected]1ff7a032010-02-03 02:46:03884 WebFrame* frame = webview()->focusedFrame();
885 if (!frame->hasSelection())
886 frame->selectWordAroundCaret();
887 frame->replaceSelection(text);
initial.commit09911bf2008-07-26 23:55:29888}
889
890void RenderView::OnDelete() {
891 if (!webview())
892 return;
893
[email protected]26aa0482009-09-30 16:55:27894 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Delete"));
initial.commit09911bf2008-07-26 23:55:29895}
896
897void RenderView::OnSelectAll() {
898 if (!webview())
899 return;
900
[email protected]26aa0482009-09-30 16:55:27901 webview()->focusedFrame()->executeCommand(
[email protected]a100d76bb2009-08-14 17:50:22902 WebString::fromUTF8("SelectAll"));
initial.commit09911bf2008-07-26 23:55:29903}
904
905void RenderView::OnSetInitialFocus(bool reverse) {
906 if (!webview())
907 return;
[email protected]26aa0482009-09-30 16:55:27908 webview()->setInitialFocus(reverse);
initial.commit09911bf2008-07-26 23:55:29909}
910
[email protected]9b66f34bf2010-10-27 20:45:51911void RenderView::OnScrollFocusedEditableNodeIntoView() {
[email protected]13a1e4c3c2011-02-03 21:07:09912 WebKit::WebNode node = GetFocusedNode();
913 if (!node.isNull()) {
914 if (IsEditableNode(node))
915 // TODO(varunjain): Change webkit API to scroll a particular node into
916 // view and use that API here instead.
917 webview()->scrollFocusedNodeIntoView();
[email protected]9b66f34bf2010-10-27 20:45:51918 }
919}
920
initial.commit09911bf2008-07-26 23:55:29921///////////////////////////////////////////////////////////////////////////////
922
923// Tell the embedding application that the URL of the active page has changed
924void RenderView::UpdateURL(WebFrame* frame) {
[email protected]dd7daa82009-08-10 05:46:45925 WebDataSource* ds = frame->dataSource();
initial.commit09911bf2008-07-26 23:55:29926 DCHECK(ds);
927
[email protected]726985e22009-06-18 21:09:28928 const WebURLRequest& request = ds->request();
929 const WebURLRequest& original_request = ds->originalRequest();
930 const WebURLResponse& response = ds->response();
initial.commit09911bf2008-07-26 23:55:29931
[email protected]daa8c58e2009-06-15 17:21:10932 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
933 DCHECK(navigation_state);
initial.commit09911bf2008-07-26 23:55:29934
935 ViewHostMsg_FrameNavigate_Params params;
[email protected]726985e22009-06-18 21:09:28936 params.http_status_code = response.httpStatusCode();
initial.commit09911bf2008-07-26 23:55:29937 params.is_post = false;
938 params.page_id = page_id_;
[email protected]dabb0d12010-10-05 12:50:07939 params.frame_id = frame->identifier();
[email protected]6d81b482011-02-22 19:47:19940 params.socket_address.set_host(response.remoteIPAddress().utf8());
941 params.socket_address.set_port(response.remotePort());
[email protected]b9a7c6d42011-02-25 02:13:03942 params.was_fetched_via_proxy = response.wasFetchedViaProxy();
[email protected]af15bed2010-08-25 21:12:09943 params.was_within_same_page = navigation_state->was_within_same_page();
[email protected]e6f546c32009-07-01 17:12:55944 if (!navigation_state->security_info().empty()) {
initial.commit09911bf2008-07-26 23:55:29945 // SSL state specified in the request takes precedence over the one in the
946 // response.
947 // So far this is only intended for error pages that are not expected to be
948 // over ssl, so we should not get any clash.
[email protected]726985e22009-06-18 21:09:28949 DCHECK(response.securityInfo().isEmpty());
[email protected]e6f546c32009-07-01 17:12:55950 params.security_info = navigation_state->security_info();
initial.commit09911bf2008-07-26 23:55:29951 } else {
[email protected]726985e22009-06-18 21:09:28952 params.security_info = response.securityInfo();
initial.commit09911bf2008-07-26 23:55:29953 }
954
955 // Set the URL to be displayed in the browser UI to the user.
[email protected]726985e22009-06-18 21:09:28956 if (ds->hasUnreachableURL()) {
957 params.url = ds->unreachableURL();
initial.commit09911bf2008-07-26 23:55:29958 } else {
[email protected]726985e22009-06-18 21:09:28959 params.url = request.url();
initial.commit09911bf2008-07-26 23:55:29960 }
961
[email protected]726985e22009-06-18 21:09:28962 GetRedirectChain(ds, &params.redirects);
[email protected]d94dc1e2010-03-04 09:29:24963 params.should_update_history = !ds->hasUnreachableURL() &&
[email protected]b7df1b72011-02-10 00:08:04964 !response.isMultipartPayload() && (response.httpStatusCode() != 404);
initial.commit09911bf2008-07-26 23:55:29965
[email protected]ce0e250d2009-10-23 21:00:35966 params.searchable_form_url = navigation_state->searchable_form_url();
967 params.searchable_form_encoding =
968 navigation_state->searchable_form_encoding();
initial.commit09911bf2008-07-26 23:55:29969
970 const PasswordForm* password_form_data =
[email protected]daa8c58e2009-06-15 17:21:10971 navigation_state->password_form_data();
initial.commit09911bf2008-07-26 23:55:29972 if (password_form_data)
973 params.password_form = *password_form_data;
974
975 params.gesture = navigation_gesture_;
976 navigation_gesture_ = NavigationGestureUnknown;
977
[email protected]0f38dc4552011-02-25 11:24:00978 // Make navigation state a part of the FrameNavigate message so that commited
979 // entry had it at all times.
980 const WebHistoryItem& item = frame->currentHistoryItem();
981 if (!item.isNull()) {
982 params.content_state = webkit_glue::HistoryItemToString(item);
983 } else {
984 params.content_state =
985 webkit_glue::CreateHistoryStateForURL(GURL(request.url()));
986 }
987
[email protected]dd7daa82009-08-10 05:46:45988 if (!frame->parent()) {
initial.commit09911bf2008-07-26 23:55:29989 // Top-level navigation.
990
[email protected]b75b8292010-10-01 07:28:25991 // Set zoom level, but don't do it for full-page plugin since they don't use
992 // the same zoom settings.
[email protected]f85f0702010-01-30 09:31:01993 HostZoomLevels::iterator host_zoom =
[email protected]9d797f32010-04-23 07:17:54994 host_zoom_levels_.find(GURL(request.url()));
[email protected]b75b8292010-10-01 07:28:25995 if (webview()->mainFrame()->document().isPluginDocument()) {
996 // Reset the zoom levels for plugins.
[email protected]b75b8292010-10-01 07:28:25997 webview()->setZoomLevel(false, 0);
[email protected]b75b8292010-10-01 07:28:25998 } else {
999 if (host_zoom != host_zoom_levels_.end())
[email protected]b75b8292010-10-01 07:28:251000 webview()->setZoomLevel(false, host_zoom->second);
[email protected]b75b8292010-10-01 07:28:251001 }
1002
[email protected]f85f0702010-01-30 09:31:011003 if (host_zoom != host_zoom_levels_.end()) {
[email protected]40bd6582009-12-04 23:49:511004 // This zoom level was merely recorded transiently for this load. We can
1005 // erase it now. If at some point we reload this page, the browser will
1006 // send us a new, up-to-date zoom level.
[email protected]f85f0702010-01-30 09:31:011007 host_zoom_levels_.erase(host_zoom);
[email protected]40bd6582009-12-04 23:49:511008 }
1009
[email protected]b75b8292010-10-01 07:28:251010 // Reset the zoom limits in case a plugin had changed them previously. This
1011 // will also call us back which will cause us to send a message to
1012 // update TabContents.
[email protected]b75b8292010-10-01 07:28:251013 webview()->zoomLimitsChanged(
1014 WebView::zoomFactorToZoomLevel(WebView::minTextSizeMultiplier),
1015 WebView::zoomFactorToZoomLevel(WebView::maxTextSizeMultiplier));
[email protected]b75b8292010-10-01 07:28:251016
initial.commit09911bf2008-07-26 23:55:291017 // Update contents MIME type for main frame.
[email protected]9c5645b2009-08-11 03:37:551018 params.contents_mime_type = ds->response().mimeType().utf8();
initial.commit09911bf2008-07-26 23:55:291019
[email protected]daa8c58e2009-06-15 17:21:101020 params.transition = navigation_state->transition_type();
initial.commit09911bf2008-07-26 23:55:291021 if (!PageTransition::IsMainFrame(params.transition)) {
1022 // If the main frame does a load, it should not be reported as a subframe
1023 // navigation. This can occur in the following case:
1024 // 1. You're on a site with frames.
1025 // 2. You do a subframe navigation. This is stored with transition type
1026 // MANUAL_SUBFRAME.
1027 // 3. You navigate to some non-frame site, say, google.com.
1028 // 4. You navigate back to the page from step 2. Since it was initially
1029 // MANUAL_SUBFRAME, it will be that same transition type here.
1030 // We don't want that, because any navigation that changes the toplevel
1031 // frame should be tracked as a toplevel navigation (this allows us to
1032 // update the URL bar, etc).
1033 params.transition = PageTransition::LINK;
1034 }
1035
initial.commit09911bf2008-07-26 23:55:291036 // If we have a valid consumed client redirect source,
1037 // the page contained a client redirect (meta refresh, document.loc...),
1038 // so we set the referrer and transition to match.
1039 if (completed_client_redirect_src_.is_valid()) {
[email protected]77e09a92008-08-01 18:11:041040 DCHECK(completed_client_redirect_src_ == params.redirects[0]);
initial.commit09911bf2008-07-26 23:55:291041 params.referrer = completed_client_redirect_src_;
1042 params.transition = static_cast<PageTransition::Type>(
1043 params.transition | PageTransition::CLIENT_REDIRECT);
1044 } else {
1045 // Bug 654101: the referrer will be empty on https->http transitions. It
1046 // would be nice if we could get the real referrer from somewhere.
[email protected]726985e22009-06-18 21:09:281047 params.referrer = GURL(
1048 original_request.httpHeaderField(WebString::fromUTF8("Referer")));
initial.commit09911bf2008-07-26 23:55:291049 }
1050
[email protected]726985e22009-06-18 21:09:281051 string16 method = request.httpMethod();
1052 if (EqualsASCII(method, "POST"))
initial.commit09911bf2008-07-26 23:55:291053 params.is_post = true;
1054
[email protected]c2a797d2009-09-21 16:46:321055 // Save some histogram data so we can compute the average memory used per
1056 // page load of the glyphs.
1057 UMA_HISTOGRAM_COUNTS_10000("Memory.GlyphPagesPerLoad",
1058 webkit_glue::GetGlyphPageCount());
1059
[email protected]15cf526b2010-02-12 06:33:491060 // This message needs to be sent before any of allowScripts(),
1061 // allowImages(), allowPlugins() is called for the new page, so that when
1062 // these functions send a ViewHostMsg_ContentBlocked message, it arrives
1063 // after the ViewHostMsg_FrameNavigate message.
initial.commit09911bf2008-07-26 23:55:291064 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
1065 } else {
1066 // Subframe navigation: the type depends on whether this navigation
1067 // generated a new session history entry. When they do generate a session
1068 // history entry, it means the user initiated the navigation and we should
1069 // mark it as such. This test checks if this is the first time UpdateURL
1070 // has been called since WillNavigateToURL was called to initiate the load.
1071 if (page_id_ > last_page_id_sent_to_browser_)
1072 params.transition = PageTransition::MANUAL_SUBFRAME;
1073 else
1074 params.transition = PageTransition::AUTO_SUBFRAME;
1075
initial.commit09911bf2008-07-26 23:55:291076 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
1077 }
1078
1079 last_page_id_sent_to_browser_ =
1080 std::max(last_page_id_sent_to_browser_, page_id_);
1081
1082 // If we end up reusing this WebRequest (for example, due to a #ref click),
[email protected]daa8c58e2009-06-15 17:21:101083 // we don't want the transition type to persist. Just clear it.
1084 navigation_state->set_transition_type(PageTransition::LINK);
[email protected]266eb6f2008-09-30 23:56:501085
[email protected]af15bed2010-08-25 21:12:091086 // Check if the navigation was within the same page, in which case we don't
1087 // want to clear the accessibility cache.
1088 if (accessibility_.get() && !navigation_state->was_within_same_page()) {
[email protected]17455962010-02-24 01:39:351089 accessibility_.reset();
[email protected]dea2d372010-09-25 06:41:141090 pending_accessibility_notifications_.clear();
[email protected]266eb6f2008-09-30 23:56:501091 }
initial.commit09911bf2008-07-26 23:55:291092}
1093
1094// Tell the embedding application that the title of the active page has changed
[email protected]6b2f7a82011-04-25 19:30:511095void RenderView::UpdateTitle(WebFrame* frame, const string16& title) {
initial.commit09911bf2008-07-26 23:55:291096 // Ignore all but top level navigations...
[email protected]3d9689372009-09-10 04:29:171097 if (!frame->parent()) {
[email protected]f0af6a72009-05-30 05:25:171098 Send(new ViewHostMsg_UpdateTitle(
[email protected]3d9689372009-09-10 04:29:171099 routing_id_,
1100 page_id_,
[email protected]6b2f7a82011-04-25 19:30:511101 UTF16ToWideHack(title.length() > content::kMaxTitleChars ?
1102 title.substr(0, content::kMaxTitleChars) : title)));
[email protected]f0af6a72009-05-30 05:25:171103 }
initial.commit09911bf2008-07-26 23:55:291104}
1105
1106void RenderView::UpdateEncoding(WebFrame* frame,
[email protected]41fc0322009-09-04 22:23:401107 const std::string& encoding_name) {
initial.commit09911bf2008-07-26 23:55:291108 // Only update main frame's encoding_name.
[email protected]26aa0482009-09-30 16:55:271109 if (webview()->mainFrame() == frame &&
initial.commit09911bf2008-07-26 23:55:291110 last_encoding_name_ != encoding_name) {
[email protected]e38f40152008-09-12 23:08:301111 // Save the encoding name for later comparing.
initial.commit09911bf2008-07-26 23:55:291112 last_encoding_name_ = encoding_name;
1113
[email protected]e38f40152008-09-12 23:08:301114 Send(new ViewHostMsg_UpdateEncoding(routing_id_, last_encoding_name_));
initial.commit09911bf2008-07-26 23:55:291115 }
1116}
1117
[email protected]e15f680732010-11-23 22:30:201118// Sends the last committed session history state to the browser so it will be
1119// saved before we navigate to a new page. This must be called *before* the
1120// page ID has been updated so we know what it was.
initial.commit09911bf2008-07-26 23:55:291121void RenderView::UpdateSessionHistory(WebFrame* frame) {
1122 // If we have a valid page ID at this point, then it corresponds to the page
1123 // we are navigating away from. Otherwise, this is the first navigation, so
1124 // there is no past session history to record.
1125 if (page_id_ == -1)
1126 return;
1127
[email protected]ca948a22009-06-25 19:36:171128 const WebHistoryItem& item =
[email protected]26aa0482009-09-30 16:55:271129 webview()->mainFrame()->previousHistoryItem();
[email protected]ca948a22009-06-25 19:36:171130 if (item.isNull())
initial.commit09911bf2008-07-26 23:55:291131 return;
[email protected]ca948a22009-06-25 19:36:171132
1133 Send(new ViewHostMsg_UpdateState(
1134 routing_id_, page_id_, webkit_glue::HistoryItemToString(item)));
initial.commit09911bf2008-07-26 23:55:291135}
1136
[email protected]3d9689372009-09-10 04:29:171137void RenderView::OpenURL(
1138 const GURL& url, const GURL& referrer, WebNavigationPolicy policy) {
1139 Send(new ViewHostMsg_OpenURL(
1140 routing_id_, url, referrer, NavigationPolicyToDisposition(policy)));
1141}
1142
[email protected]79dbc662009-09-04 05:42:511143// WebViewDelegate ------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291144
initial.commit09911bf2008-07-26 23:55:291145void RenderView::LoadNavigationErrorPage(WebFrame* frame,
[email protected]726985e22009-06-18 21:09:281146 const WebURLRequest& failed_request,
1147 const WebURLError& error,
initial.commit09911bf2008-07-26 23:55:291148 const std::string& html,
1149 bool replace) {
[email protected]21d61e52011-03-18 19:08:251150 std::string alt_html = !html.empty() ? html :
1151 content::GetContentClient()->renderer()->GetNavigationErrorHtml(
1152 failed_request, error);
[email protected]dd7daa82009-08-10 05:46:451153 frame->loadHTMLString(alt_html,
[email protected]144143c2010-10-28 08:17:361154 GURL(chrome::kUnreachableWebDataURL),
[email protected]21d61e52011-03-18 19:08:251155 error.unreachableURL,
[email protected]e6f546c32009-07-01 17:12:551156 replace);
initial.commit09911bf2008-07-26 23:55:291157}
1158
initial.commit09911bf2008-07-26 23:55:291159bool RenderView::RunJavaScriptMessage(int type,
1160 const std::wstring& message,
1161 const std::wstring& default_value,
[email protected]a455d3812009-03-05 20:18:071162 const GURL& frame_url,
initial.commit09911bf2008-07-26 23:55:291163 std::wstring* result) {
1164 bool success = false;
1165 std::wstring result_temp;
1166 if (!result)
1167 result = &result_temp;
initial.commit09911bf2008-07-26 23:55:291168
[email protected]12636df2009-09-28 22:32:211169 SendAndRunNestedMessageLoop(new ViewHostMsg_RunJavaScriptMessage(
1170 routing_id_, message, default_value, frame_url, type, &success, result));
initial.commit09911bf2008-07-26 23:55:291171 return success;
1172}
1173
[email protected]c1f50aa2010-02-18 03:46:571174bool RenderView::SendAndRunNestedMessageLoop(IPC::SyncMessage* message) {
1175 // Before WebKit asks us to show an alert (etc.), it takes care of doing the
1176 // equivalent of WebView::willEnterModalLoop. In the case of showModalDialog
1177 // it is particularly important that we do not call willEnterModalLoop as
1178 // that would defer resource loads for the dialog itself.
1179 if (RenderThread::current()) // Will be NULL during unit tests.
1180 RenderThread::current()->DoNotNotifyWebKitOfModalLoop();
1181
1182 message->EnableMessagePumping(); // Runs a nested message loop.
1183 return Send(message);
1184}
1185
[email protected]f103ab72009-09-02 17:10:591186void RenderView::OnMissingPluginStatus(
1187 WebPluginDelegateProxy* delegate,
1188 int status) {
[email protected]6c8afae52009-01-22 02:24:571189#if defined(OS_WIN)
[email protected]f103ab72009-09-02 17:10:591190 if (!first_default_plugin_) {
initial.commit09911bf2008-07-26 23:55:291191 // Show the InfoBar for the first available plugin.
[email protected]191eb3f72010-12-21 06:27:501192 if (status == webkit::npapi::default_plugin::MISSING_PLUGIN_AVAILABLE) {
[email protected]f103ab72009-09-02 17:10:591193 first_default_plugin_ = delegate->AsWeakPtr();
initial.commit09911bf2008-07-26 23:55:291194 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1195 }
1196 } else {
1197 // Closes the InfoBar if user clicks on the plugin (instead of the InfoBar)
1198 // to start the download/install.
[email protected]191eb3f72010-12-21 06:27:501199 if (status ==
1200 webkit::npapi::default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD) {
initial.commit09911bf2008-07-26 23:55:291201 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
1202 }
1203 }
[email protected]6c8afae52009-01-22 02:24:571204#else
[email protected]76c3b312010-05-20 21:38:291205 // TODO(port): Implement the infobar that accompanies the default plugin.
1206 // Linux: http://crbug.com/10952
1207 // Mac: http://crbug.com/17392
[email protected]6c8afae52009-01-22 02:24:571208 NOTIMPLEMENTED();
1209#endif
initial.commit09911bf2008-07-26 23:55:291210}
1211
[email protected]48c9cf2d2009-09-16 16:47:521212// WebKit::WebViewClient ------------------------------------------------------
1213
[email protected]844acf372011-01-14 10:49:271214WebView* RenderView::createView(
1215 WebFrame* creator,
1216 const WebURLRequest& request,
1217 const WebWindowFeatures& features,
1218 const WebString& frame_name) {
[email protected]48c9cf2d2009-09-16 16:47:521219 // Check to make sure we aren't overloading on popups.
1220 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups)
1221 return NULL;
1222
[email protected]8ab04652010-06-12 02:47:261223 ViewHostMsg_CreateWindow_Params params;
1224 params.opener_id = routing_id_;
1225 params.user_gesture = creator->isProcessingUserGesture();
1226 params.window_container_type = WindowFeaturesToContainerType(features);
1227 params.session_storage_namespace_id = session_storage_namespace_id_;
1228 params.frame_name = frame_name;
[email protected]41e65502011-01-21 09:29:111229 params.opener_frame_id = creator->identifier();
1230 params.opener_url = creator->url();
1231 params.opener_security_origin = creator->securityOrigin().toString().utf8();
1232 if (!request.isNull())
1233 params.target_url = request.url();
[email protected]8ab04652010-06-12 02:47:261234
[email protected]48c9cf2d2009-09-16 16:47:521235 int32 routing_id = MSG_ROUTING_NONE;
[email protected]4e6419c2010-01-15 04:50:341236 int64 cloned_session_storage_namespace_id;
[email protected]8ab04652010-06-12 02:47:261237 bool opener_suppressed = creator->willSuppressOpenerInNewFrame();
[email protected]48c9cf2d2009-09-16 16:47:521238
[email protected]48c9cf2d2009-09-16 16:47:521239 render_thread_->Send(
[email protected]8ab04652010-06-12 02:47:261240 new ViewHostMsg_CreateWindow(params,
1241 &routing_id,
1242 &cloned_session_storage_namespace_id));
[email protected]12636df2009-09-28 22:32:211243 if (routing_id == MSG_ROUTING_NONE)
[email protected]48c9cf2d2009-09-16 16:47:521244 return NULL;
[email protected]48c9cf2d2009-09-16 16:47:521245
[email protected]48c9cf2d2009-09-16 16:47:521246 RenderView* view = RenderView::Create(render_thread_,
[email protected]659f73fa2009-10-13 13:43:421247 0,
[email protected]c03a6e72011-04-19 21:42:061248 gfx::kNullPluginWindow,
[email protected]12636df2009-09-28 22:32:211249 routing_id_,
[email protected]48c9cf2d2009-09-16 16:47:521250 renderer_preferences_,
1251 webkit_preferences_,
[email protected]12636df2009-09-28 22:32:211252 shared_popup_counter_,
[email protected]4e6419c2010-01-15 04:50:341253 routing_id,
[email protected]8ab04652010-06-12 02:47:261254 cloned_session_storage_namespace_id,
1255 frame_name);
1256 view->opened_by_user_gesture_ = params.user_gesture;
[email protected]48c9cf2d2009-09-16 16:47:521257
[email protected]007a848b2009-10-26 15:55:461258 // Record whether the creator frame is trying to suppress the opener field.
1259 view->opener_suppressed_ = opener_suppressed;
1260
[email protected]48c9cf2d2009-09-16 16:47:521261 // Record the security origin of the creator.
[email protected]91733b62009-09-18 06:21:091262 GURL creator_url(creator->securityOrigin().toString().utf8());
[email protected]48c9cf2d2009-09-16 16:47:521263 if (!creator_url.is_valid() || !creator_url.IsStandard())
1264 creator_url = GURL();
1265 view->creator_url_ = creator_url;
1266
1267 // Copy over the alternate error page URL so we can have alt error pages in
1268 // the new render view (we don't need the browser to send the URL back down).
1269 view->alternate_error_page_url_ = alternate_error_page_url_;
1270
1271 return view->webview();
1272}
1273
[email protected]3e2b375b2010-04-07 17:03:121274WebWidget* RenderView::createPopupMenu(WebKit::WebPopupType popup_type) {
[email protected]48c9cf2d2009-09-16 16:47:521275 RenderWidget* widget = RenderWidget::Create(routing_id_,
1276 render_thread_,
[email protected]3e2b375b2010-04-07 17:03:121277 popup_type);
[email protected]48c9cf2d2009-09-16 16:47:521278 return widget->webwidget();
1279}
1280
1281WebWidget* RenderView::createPopupMenu(const WebPopupMenuInfo& info) {
[email protected]8de12d942010-11-17 20:42:441282 // TODO(jcivelli): Remove this deprecated method when its been removed from
1283 // the WebViewClient interface. It's been replaced by
1284 // createExternalPopupMenu.
1285 NOTREACHED();
1286 return NULL;
[email protected]48c9cf2d2009-09-16 16:47:521287}
1288
[email protected]caf706f2010-10-26 17:54:081289WebExternalPopupMenu* RenderView::createExternalPopupMenu(
1290 const WebPopupMenuInfo& popup_menu_info,
1291 WebExternalPopupMenuClient* popup_menu_client) {
1292 DCHECK(!external_popup_menu_.get());
1293 external_popup_menu_.reset(
1294 new ExternalPopupMenu(this, popup_menu_info, popup_menu_client));
1295 return external_popup_menu_.get();
1296}
1297
[email protected]ea192e82011-04-11 19:16:021298RenderWidgetFullscreenPepper* RenderView::CreatePepperFullscreenContainer(
[email protected]0bd753682010-12-16 18:15:521299 webkit::ppapi::PluginInstance* plugin) {
[email protected]d91233b7e2011-03-29 20:33:531300 GURL active_url;
[email protected]d91ddfc2011-04-07 18:33:421301 if (webview() && webview()->mainFrame())
[email protected]d91233b7e2011-03-29 20:33:531302 active_url = GURL(webview()->mainFrame()->url());
1303 RenderWidgetFullscreenPepper* widget = RenderWidgetFullscreenPepper::Create(
1304 routing_id_, render_thread_, plugin, active_url);
[email protected]79c7bed2010-09-14 22:28:391305 widget->show(WebKit::WebNavigationPolicyIgnore);
[email protected]92abcb832011-01-06 20:39:561306 return widget;
[email protected]79c7bed2010-09-14 22:28:391307}
1308
[email protected]68c50e52010-05-12 11:14:391309WebStorageNamespace* RenderView::createSessionStorageNamespace(unsigned quota) {
[email protected]bd92c3a2010-01-13 05:02:341310 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess))
[email protected]68c50e52010-05-12 11:14:391311 return WebStorageNamespace::createSessionStorageNamespace(quota);
[email protected]59afea12010-01-20 04:48:291312 CHECK(session_storage_namespace_id_ != kInvalidSessionStorageNamespaceId);
1313 return new RendererWebStorageNamespaceImpl(DOM_STORAGE_SESSION,
1314 session_storage_namespace_id_);
[email protected]bd92c3a2010-01-13 05:02:341315}
1316
[email protected]48c9cf2d2009-09-16 16:47:521317void RenderView::didAddMessageToConsole(
1318 const WebConsoleMessage& message, const WebString& source_name,
1319 unsigned source_line) {
[email protected]d09df4b2011-04-11 19:01:081320 logging::LogSeverity log_severity = logging::LOG_VERBOSE;
1321 switch(message.level) {
1322 case WebConsoleMessage::LevelTip:
1323 log_severity = logging::LOG_VERBOSE;
1324 break;
1325 case WebConsoleMessage::LevelLog:
1326 log_severity = logging::LOG_INFO;
1327 break;
1328 case WebConsoleMessage::LevelWarning:
1329 log_severity = logging::LOG_WARNING;
1330 break;
1331 case WebConsoleMessage::LevelError:
1332 log_severity = logging::LOG_ERROR;
1333 break;
1334 default:
1335 NOTREACHED();
1336 }
1337
[email protected]48c9cf2d2009-09-16 16:47:521338 Send(new ViewHostMsg_AddMessageToConsole(routing_id_,
[email protected]d09df4b2011-04-11 19:01:081339 static_cast<int32>(log_severity),
[email protected]48c9cf2d2009-09-16 16:47:521340 UTF16ToWideHack(message.text),
1341 static_cast<int32>(source_line),
1342 UTF16ToWideHack(source_name)));
1343}
1344
1345void RenderView::printPage(WebFrame* frame) {
[email protected]d91ddfc2011-04-07 18:33:421346 FOR_EACH_OBSERVER(RenderViewObserver, observers_, PrintPage(frame));
[email protected]48c9cf2d2009-09-16 16:47:521347}
1348
[email protected]3354d3e2010-06-10 19:53:021349WebKit::WebNotificationPresenter* RenderView::notificationPresenter() {
[email protected]676126f72011-01-15 00:03:511350 return notification_provider_;
[email protected]3354d3e2010-06-10 19:53:021351}
1352
[email protected]8a58c1c2011-04-19 18:40:121353bool RenderView::enumerateChosenDirectory(
1354 const WebString& path,
1355 WebFileChooserCompletion* chooser_completion) {
1356 int id = enumeration_completion_id_++;
1357 enumeration_completions_[id] = chooser_completion;
1358 return Send(new ViewHostMsg_EnumerateDirectory(
1359 routing_id_,
1360 id,
1361 webkit_glue::WebStringToFilePath(path)));
1362}
1363
[email protected]48c9cf2d2009-09-16 16:47:521364void RenderView::didStartLoading() {
1365 if (is_loading_) {
1366 DLOG(WARNING) << "didStartLoading called while loading";
1367 return;
1368 }
1369
1370 is_loading_ = true;
1371 // Clear the pointer so that we can assign it only when there is an unknown
1372 // plugin on a page.
1373 first_default_plugin_.reset();
1374
1375 Send(new ViewHostMsg_DidStartLoading(routing_id_));
[email protected]93b9d692011-04-13 00:44:311376
1377 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStartLoading());
[email protected]48c9cf2d2009-09-16 16:47:521378}
1379
1380void RenderView::didStopLoading() {
1381 if (!is_loading_) {
1382 DLOG(WARNING) << "DidStopLoading called while not loading";
1383 return;
1384 }
1385
1386 is_loading_ = false;
1387
1388 // NOTE: For now we're doing the safest thing, and sending out notification
1389 // when done loading. This currently isn't an issue as the favicon is only
1390 // displayed when done loading. Ideally we would send notification when
1391 // finished parsing the head, but webkit doesn't support that yet.
1392 // The feed discovery code would also benefit from access to the head.
[email protected]48c9cf2d2009-09-16 16:47:521393 Send(new ViewHostMsg_DidStopLoading(routing_id_));
1394
[email protected]90109412010-12-15 17:14:241395 if (load_progress_tracker_ != NULL)
1396 load_progress_tracker_->DidStopLoading();
1397
[email protected]93b9d692011-04-13 00:44:311398 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStopLoading());
[email protected]48c9cf2d2009-09-16 16:47:521399}
1400
[email protected]90109412010-12-15 17:14:241401void RenderView::didChangeLoadProgress(WebFrame* frame, double load_progress) {
1402 if (load_progress_tracker_ != NULL)
1403 load_progress_tracker_->DidChangeLoadProgress(frame, load_progress);
1404}
1405
[email protected]f55039a2010-02-17 14:12:061406bool RenderView::isSmartInsertDeleteEnabled() {
1407#if defined(OS_MACOSX)
1408 return true;
1409#else
1410 return false;
1411#endif
1412}
1413
[email protected]04fc9482009-09-18 22:13:031414bool RenderView::isSelectTrailingWhitespaceEnabled() {
1415#if defined(OS_WIN)
1416 return true;
1417#else
1418 return false;
1419#endif
1420}
1421
[email protected]04fc9482009-09-18 22:13:031422void RenderView::didChangeSelection(bool is_empty_selection) {
[email protected]0ff0ff32010-12-21 19:34:421423#if defined(OS_POSIX)
[email protected]04fc9482009-09-18 22:13:031424 if (!handling_input_event_)
1425 return;
1426 // TODO(estade): investigate incremental updates to the selection so that we
1427 // don't send the entire selection over IPC every time.
1428 if (!is_empty_selection) {
1429 // Sometimes we get repeated didChangeSelection calls from webkit when
1430 // the selection hasn't actually changed. We don't want to report these
1431 // because it will cause us to continually claim the X clipboard.
1432 const std::string& this_selection =
[email protected]26aa0482009-09-30 16:55:271433 webview()->focusedFrame()->selectionAsText().utf8();
[email protected]04fc9482009-09-18 22:13:031434 if (this_selection == last_selection_)
1435 return;
1436
1437 Send(new ViewHostMsg_SelectionChanged(routing_id_,
1438 this_selection));
1439 last_selection_ = this_selection;
1440 } else {
1441 last_selection_.clear();
[email protected]eef99c22010-08-17 05:55:161442 Send(new ViewHostMsg_SelectionChanged(routing_id_,
1443 last_selection_));
[email protected]04fc9482009-09-18 22:13:031444 }
[email protected]0ff0ff32010-12-21 19:34:421445#endif // defined(OS_POSIX)
[email protected]04fc9482009-09-18 22:13:031446}
1447
1448void RenderView::didExecuteCommand(const WebString& command_name) {
[email protected]afe3a1672009-11-17 19:04:121449 const std::string& name = UTF16ToUTF8(command_name);
1450 if (StartsWithASCII(name, "Move", true) ||
1451 StartsWithASCII(name, "Insert", true) ||
1452 StartsWithASCII(name, "Delete", true))
[email protected]04fc9482009-09-18 22:13:031453 return;
[email protected]9966325b2011-04-18 05:00:101454 webkit_glue::UserMetricsRecordAction(name);
[email protected]04fc9482009-09-18 22:13:031455}
1456
[email protected]54ec7f82010-10-21 22:32:511457void RenderView::SendPendingAccessibilityNotifications() {
1458 if (!accessibility_.get())
1459 return;
1460
1461 if (pending_accessibility_notifications_.empty())
1462 return;
1463
1464 // Send all pending accessibility notifications.
1465 std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications;
1466 for (size_t i = 0; i < pending_accessibility_notifications_.size(); i++) {
1467 RendererAccessibilityNotification& notification =
1468 pending_accessibility_notifications_[i];
1469 WebAccessibilityObject obj = accessibility_->getObjectById(notification.id);
1470 if (!obj.isValid())
1471 continue;
1472
1473 ViewHostMsg_AccessibilityNotification_Params param;
[email protected]a527a022011-02-10 02:32:361474 WebAccessibilityNotificationToViewHostMsg(
1475 pending_accessibility_notifications_[i].type, &param.notification_type);
[email protected]70eee342010-11-05 01:59:371476 param.acc_obj = WebAccessibility(
1477 obj, accessibility_.get(), notification.ShouldIncludeChildren());
[email protected]54ec7f82010-10-21 22:32:511478 notifications.push_back(param);
1479 }
1480 pending_accessibility_notifications_.clear();
1481 Send(new ViewHostMsg_AccessibilityNotifications(routing_id_, notifications));
1482 accessibility_ack_pending_ = true;
1483}
1484
[email protected]b2528b72009-09-24 06:57:101485bool RenderView::handleCurrentKeyboardEvent() {
1486 if (edit_commands_.empty())
1487 return false;
1488
[email protected]26aa0482009-09-30 16:55:271489 WebFrame* frame = webview()->focusedFrame();
[email protected]b2528b72009-09-24 06:57:101490 if (!frame)
1491 return false;
1492
1493 EditCommands::iterator it = edit_commands_.begin();
1494 EditCommands::iterator end = edit_commands_.end();
1495
[email protected]507b33ea2009-09-29 03:56:511496 bool did_execute_command = false;
[email protected]b2528b72009-09-24 06:57:101497 for (; it != end; ++it) {
[email protected]e6e15012009-09-30 14:59:331498 // In gtk and cocoa, it's possible to bind multiple edit commands to one
1499 // key (but it's the exception). Once one edit command is not executed, it
1500 // seems safest to not execute the rest.
[email protected]b2528b72009-09-24 06:57:101501 if (!frame->executeCommand(WebString::fromUTF8(it->name),
1502 WebString::fromUTF8(it->value)))
1503 break;
[email protected]507b33ea2009-09-29 03:56:511504 did_execute_command = true;
[email protected]b2528b72009-09-24 06:57:101505 }
1506
[email protected]507b33ea2009-09-29 03:56:511507 return did_execute_command;
[email protected]b2528b72009-09-24 06:57:101508}
1509
[email protected]a1128322009-10-06 18:38:461510bool RenderView::runFileChooser(
[email protected]01178b52010-01-15 06:59:351511 const WebKit::WebFileChooserParams& params,
[email protected]cdaf8d02010-03-30 19:52:471512 WebFileChooserCompletion* chooser_completion) {
[email protected]7ef03e02010-10-23 11:58:351513 // Do not open the file dialog in a hidden RenderView.
1514 if (is_hidden())
1515 return false;
[email protected]cdaf8d02010-03-30 19:52:471516 ViewHostMsg_RunFileChooser_Params ipc_params;
[email protected]b5977a0c2010-08-24 19:46:261517 if (params.directory)
[email protected]0aed2f52011-03-23 18:06:361518 ipc_params.mode = ViewHostMsg_RunFileChooser_Mode::OpenFolder;
[email protected]b5977a0c2010-08-24 19:46:261519 else if (params.multiSelect)
[email protected]0aed2f52011-03-23 18:06:361520 ipc_params.mode = ViewHostMsg_RunFileChooser_Mode::OpenMultiple;
[email protected]b5977a0c2010-08-24 19:46:261521 else
[email protected]0aed2f52011-03-23 18:06:361522 ipc_params.mode = ViewHostMsg_RunFileChooser_Mode::Open;
[email protected]cdaf8d02010-03-30 19:52:471523 ipc_params.title = params.title;
1524 ipc_params.default_file_name =
1525 webkit_glue::WebStringToFilePath(params.initialValue);
[email protected]099949132010-09-08 20:24:591526 ipc_params.accept_types = params.acceptTypes;
[email protected]cdaf8d02010-03-30 19:52:471527
1528 return ScheduleFileChooser(ipc_params, chooser_completion);
[email protected]a1128322009-10-06 18:38:461529}
1530
[email protected]48c9cf2d2009-09-16 16:47:521531void RenderView::runModalAlertDialog(
1532 WebFrame* frame, const WebString& message) {
[email protected]9dd7e3d72011-01-20 18:27:061533 RunJavaScriptMessage(ui::MessageBoxFlags::kIsJavascriptAlert,
[email protected]48c9cf2d2009-09-16 16:47:521534 UTF16ToWideHack(message),
1535 std::wstring(),
1536 frame->url(),
1537 NULL);
1538}
1539
1540bool RenderView::runModalConfirmDialog(
1541 WebFrame* frame, const WebString& message) {
[email protected]9dd7e3d72011-01-20 18:27:061542 return RunJavaScriptMessage(ui::MessageBoxFlags::kIsJavascriptConfirm,
[email protected]48c9cf2d2009-09-16 16:47:521543 UTF16ToWideHack(message),
1544 std::wstring(),
1545 frame->url(),
1546 NULL);
1547}
1548
1549bool RenderView::runModalPromptDialog(
1550 WebFrame* frame, const WebString& message, const WebString& default_value,
1551 WebString* actual_value) {
1552 std::wstring result;
[email protected]9dd7e3d72011-01-20 18:27:061553 bool ok = RunJavaScriptMessage(ui::MessageBoxFlags::kIsJavascriptPrompt,
[email protected]48c9cf2d2009-09-16 16:47:521554 UTF16ToWideHack(message),
1555 UTF16ToWideHack(default_value),
1556 frame->url(),
1557 &result);
1558 if (ok)
1559 actual_value->assign(WideToUTF16Hack(result));
1560 return ok;
1561}
1562
1563bool RenderView::runModalBeforeUnloadDialog(
1564 WebFrame* frame, const WebString& message) {
1565 bool success = false;
1566 // This is an ignored return value, but is included so we can accept the same
1567 // response as RunJavaScriptMessage.
1568 std::wstring ignored_result;
[email protected]12636df2009-09-28 22:32:211569 SendAndRunNestedMessageLoop(new ViewHostMsg_RunBeforeUnloadConfirm(
[email protected]48c9cf2d2009-09-16 16:47:521570 routing_id_, frame->url(), UTF16ToWideHack(message), &success,
[email protected]12636df2009-09-28 22:32:211571 &ignored_result));
[email protected]48c9cf2d2009-09-16 16:47:521572 return success;
1573}
1574
[email protected]79e37442009-10-09 18:17:441575void RenderView::showContextMenu(
1576 WebFrame* frame, const WebContextMenuData& data) {
[email protected]c27324b2009-11-19 22:44:291577 ContextMenuParams params = ContextMenuParams(data);
[email protected]db803aae2011-03-05 02:00:421578 // Serializing a GURL longer than content::kMaxURLChars will fail, so don't do
[email protected]216932c2010-08-26 21:44:271579 // it. We replace it with an empty GURL so the appropriate items are disabled
1580 // in the context menu.
1581 // TODO(jcivelli): http://crbug.com/45160 This prevents us from saving large
1582 // data encoded images. We should have a way to save them.
[email protected]db803aae2011-03-05 02:00:421583 if (params.src_url.spec().size() > content::kMaxURLChars)
[email protected]216932c2010-08-26 21:44:271584 params.src_url = GURL();
[email protected]521b2482011-01-15 00:10:101585 context_menu_node_ = data.node;
[email protected]c27324b2009-11-19 22:44:291586 Send(new ViewHostMsg_ContextMenu(routing_id_, params));
[email protected]79e37442009-10-09 18:17:441587}
1588
[email protected]52f139e2c2010-06-11 16:56:091589bool RenderView::supportsFullscreen() {
1590 return CommandLine::ForCurrentProcess()->HasSwitch(
1591 switches::kEnableVideoFullscreen);
1592}
1593
1594void RenderView::enterFullscreenForNode(const WebKit::WebNode& node) {
1595 NOTIMPLEMENTED();
1596}
1597
1598void RenderView::exitFullscreenForNode(const WebKit::WebNode& node) {
1599 NOTIMPLEMENTED();
1600}
1601
[email protected]48c9cf2d2009-09-16 16:47:521602void RenderView::setStatusText(const WebString& text) {
1603}
1604
[email protected]163f8242009-10-30 20:19:551605void RenderView::UpdateTargetURL(const GURL& url, const GURL& fallback_url) {
[email protected]aa6b90b32010-04-26 15:49:581606 GURL latest_url = url.is_empty() ? fallback_url : url;
[email protected]48c9cf2d2009-09-16 16:47:521607 if (latest_url == target_url_)
1608 return;
[email protected]163f8242009-10-30 20:19:551609
[email protected]48c9cf2d2009-09-16 16:47:521610 // Tell the browser to display a destination link.
1611 if (target_url_status_ == TARGET_INFLIGHT ||
1612 target_url_status_ == TARGET_PENDING) {
1613 // If we have a request in-flight, save the URL to be sent when we
1614 // receive an ACK to the in-flight request. We can happily overwrite
1615 // any existing pending sends.
1616 pending_target_url_ = latest_url;
1617 target_url_status_ = TARGET_PENDING;
1618 } else {
1619 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_, latest_url));
1620 target_url_ = latest_url;
1621 target_url_status_ = TARGET_INFLIGHT;
1622 }
1623}
1624
[email protected]882daa92009-11-05 16:31:311625void RenderView::StartNavStateSyncTimerIfNecessary() {
1626 int delay;
1627 if (send_content_state_immediately_)
1628 delay = 0;
1629 else if (is_hidden())
1630 delay = kDelaySecondsForContentStateSyncHidden;
1631 else
1632 delay = kDelaySecondsForContentStateSync;
1633
1634 if (nav_state_sync_timer_.IsRunning()) {
1635 // The timer is already running. If the delay of the timer maches the amount
1636 // we want to delay by, then return. Otherwise stop the timer so that it
1637 // gets started with the right delay.
1638 if (nav_state_sync_timer_.GetCurrentDelay().InSeconds() == delay)
1639 return;
1640 nav_state_sync_timer_.Stop();
1641 }
1642
1643 nav_state_sync_timer_.Start(
1644 TimeDelta::FromSeconds(delay), this, &RenderView::SyncNavigationState);
1645}
1646
[email protected]163f8242009-10-30 20:19:551647void RenderView::setMouseOverURL(const WebURL& url) {
1648 mouse_over_url_ = GURL(url);
1649 UpdateTargetURL(mouse_over_url_, focus_url_);
1650}
1651
1652void RenderView::setKeyboardFocusURL(const WebURL& url) {
1653 focus_url_ = GURL(url);
1654 UpdateTargetURL(focus_url_, mouse_over_url_);
1655}
1656
[email protected]48c9cf2d2009-09-16 16:47:521657void RenderView::setToolTipText(const WebString& text, WebTextDirection hint) {
1658 Send(new ViewHostMsg_SetTooltipText(routing_id_, UTF16ToWideHack(text),
1659 hint));
1660}
1661
[email protected]c27ae592010-03-18 15:24:411662void RenderView::startDragging(const WebDragData& data,
1663 WebDragOperationsMask mask,
1664 const WebImage& image,
1665 const WebPoint& imageOffset) {
1666#if WEBKIT_USING_SKIA
1667 SkBitmap bitmap(image.getSkBitmap());
1668#elif WEBKIT_USING_CG
[email protected]78043bdd2010-04-05 18:45:331669 SkBitmap bitmap = gfx::CGImageToSkBitmap(image.getCGImageRef());
[email protected]c27ae592010-03-18 15:24:411670#endif
1671
[email protected]59f4f2fa2011-03-23 01:00:551672 Send(new DragHostMsg_StartDragging(routing_id_,
[email protected]48c9cf2d2009-09-16 16:47:521673 WebDropData(data),
[email protected]c27ae592010-03-18 15:24:411674 mask,
1675 bitmap,
1676 imageOffset));
[email protected]48c9cf2d2009-09-16 16:47:521677}
1678
[email protected]28b92df2009-09-25 17:35:451679bool RenderView::acceptsLoadDrops() {
1680 return renderer_preferences_.can_accept_load_drops;
1681}
1682
[email protected]48c9cf2d2009-09-16 16:47:521683void RenderView::focusNext() {
1684 Send(new ViewHostMsg_TakeFocus(routing_id_, false));
1685}
1686
1687void RenderView::focusPrevious() {
1688 Send(new ViewHostMsg_TakeFocus(routing_id_, true));
1689}
1690
[email protected]08e9e132010-06-01 16:58:491691void RenderView::focusedNodeChanged(const WebNode& node) {
[email protected]9b66f34bf2010-10-27 20:45:511692 Send(new ViewHostMsg_FocusedNodeChanged(routing_id_, IsEditableNode(node)));
[email protected]a4b103b2010-10-05 18:46:071693
1694 if (WebAccessibilityCache::accessibilityEnabled() && node.isNull()) {
1695 // TODO(ctguil): Make WebKit send this notification.
1696 // When focus is cleared notify accessibility that the document is focused.
1697 postAccessibilityNotification(
1698 webview()->accessibilityObject(),
1699 WebKit::WebAccessibilityNotificationFocusedUIElementChanged);
1700 }
[email protected]13a1e4c3c2011-02-03 21:07:091701
[email protected]38b592902011-04-16 02:08:421702 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FocusedNodeChanged(node));
[email protected]08e9e132010-06-01 16:58:491703}
1704
[email protected]48c9cf2d2009-09-16 16:47:521705void RenderView::navigateBackForwardSoon(int offset) {
[email protected]48c9cf2d2009-09-16 16:47:521706 Send(new ViewHostMsg_GoToEntryAtOffset(routing_id_, offset));
1707}
1708
1709int RenderView::historyBackListCount() {
[email protected]3cc72b12010-03-18 23:03:001710 return history_list_offset_ < 0 ? 0 : history_list_offset_;
[email protected]48c9cf2d2009-09-16 16:47:521711}
1712
1713int RenderView::historyForwardListCount() {
[email protected]3cc72b12010-03-18 23:03:001714 return history_list_length_ - historyBackListCount() - 1;
[email protected]48c9cf2d2009-09-16 16:47:521715}
1716
[email protected]c4e98902010-06-01 10:20:141717void RenderView::didUpdateInspectorSetting(const WebString& key,
1718 const WebString& value) {
1719 Send(new ViewHostMsg_UpdateInspectorSetting(routing_id_,
1720 key.utf8(),
1721 value.utf8()));
[email protected]8922e1f2009-10-03 05:01:261722}
1723
[email protected]79dbc662009-09-04 05:42:511724// WebKit::WebWidgetClient ----------------------------------------------------
1725
[email protected]ea42e7782010-08-23 23:58:121726void RenderView::didFocus() {
1727 // TODO(jcivelli): when https://bugs.webkit.org/show_bug.cgi?id=33389 is fixed
1728 // we won't have to test for user gesture anymore and we can
1729 // move that code back to render_widget.cc
1730 if (webview() && webview()->mainFrame() &&
1731 webview()->mainFrame()->isProcessingUserGesture()) {
1732 Send(new ViewHostMsg_Focus(routing_id_));
1733 }
1734}
1735
1736void RenderView::didBlur() {
1737 // TODO(jcivelli): see TODO above in didFocus().
1738 if (webview() && webview()->mainFrame() &&
1739 webview()->mainFrame()->isProcessingUserGesture()) {
1740 Send(new ViewHostMsg_Blur(routing_id_));
1741 }
1742}
1743
initial.commit09911bf2008-07-26 23:55:291744// We are supposed to get a single call to Show for a newly created RenderView
1745// that was created via RenderView::CreateWebView. So, we wait until this
1746// point to dispatch the ShowView message.
1747//
1748// This method provides us with the information about how to display the newly
1749// created RenderView (i.e., as a constrained popup or as a new tab).
1750//
[email protected]4873c7d2009-07-16 06:36:281751void RenderView::show(WebNavigationPolicy policy) {
initial.commit09911bf2008-07-26 23:55:291752 DCHECK(!did_show_) << "received extraneous Show call";
1753 DCHECK(opener_id_ != MSG_ROUTING_NONE);
1754
1755 if (did_show_)
1756 return;
1757 did_show_ = true;
1758
[email protected]6779aa12011-03-29 17:32:241759 if (content::GetContentClient()->renderer()->AllowPopup(creator_url_))
[email protected]4026ce1e2010-09-14 19:35:041760 opened_by_user_gesture_ = true;
[email protected]4026ce1e2010-09-14 19:35:041761
[email protected]28295ec2009-10-16 05:34:331762 // Force new windows to a popup if they were not opened with a user gesture.
1763 if (!opened_by_user_gesture_) {
1764 // We exempt background tabs for compat with older versions of Chrome.
1765 // TODO(darin): This seems bogus. These should have a user gesture, so
1766 // we probably don't need this check.
1767 if (policy != WebKit::WebNavigationPolicyNewBackgroundTab)
1768 policy = WebKit::WebNavigationPolicyNewPopup;
1769 }
1770
initial.commit09911bf2008-07-26 23:55:291771 // NOTE: initial_pos_ may still have its default values at this point, but
1772 // that's okay. It'll be ignored if disposition is not NEW_POPUP, or the
1773 // browser process will impose a default position otherwise.
[email protected]4873c7d2009-07-16 06:36:281774 Send(new ViewHostMsg_ShowView(opener_id_, routing_id_,
1775 NavigationPolicyToDisposition(policy), initial_pos_,
[email protected]7e7414ae2010-01-26 20:19:291776 opened_by_user_gesture_));
[email protected]2533ce12009-05-09 00:02:241777 SetPendingWindowRect(initial_pos_);
initial.commit09911bf2008-07-26 23:55:291778}
1779
[email protected]4873c7d2009-07-16 06:36:281780void RenderView::runModal() {
initial.commit09911bf2008-07-26 23:55:291781 DCHECK(did_show_) << "should already have shown the view";
1782
[email protected]c1f50aa2010-02-18 03:46:571783 // We must keep WebKit's shared timer running in this case in order to allow
1784 // showModalDialog to function properly.
1785 //
1786 // TODO(darin): WebKit should really be smarter about suppressing events and
1787 // timers so that we do not need to manage the shared timer in such a heavy
1788 // handed manner.
1789 //
1790 if (RenderThread::current()) // Will be NULL during unit tests.
1791 RenderThread::current()->DoNotSuspendWebKitSharedTimer();
1792
[email protected]12636df2009-09-28 22:32:211793 SendAndRunNestedMessageLoop(new ViewHostMsg_RunModal(routing_id_));
initial.commit09911bf2008-07-26 23:55:291794}
1795
[email protected]3d9689372009-09-10 04:29:171796// WebKit::WebFrameClient -----------------------------------------------------
1797
[email protected]00152e92010-07-19 11:47:401798WebPlugin* RenderView::createPlugin(WebFrame* frame,
1799 const WebPluginParams& params) {
[email protected]e7c21b812011-03-19 18:03:301800 return content::GetContentClient()->renderer()->CreatePlugin(
[email protected]21d61e52011-03-18 19:08:251801 this, frame, params);
[email protected]3d9689372009-09-10 04:29:171802}
1803
1804WebWorker* RenderView::createWorker(WebFrame* frame, WebWorkerClient* client) {
[email protected]14396e92010-05-06 20:40:561805 WebApplicationCacheHostImpl* appcache_host =
1806 WebApplicationCacheHostImpl::FromFrame(frame);
1807 int appcache_host_id = appcache_host ? appcache_host->host_id() : 0;
1808 return new WebWorkerProxy(client, RenderThread::current(), routing_id_,
1809 appcache_host_id);
[email protected]3d9689372009-09-10 04:29:171810}
1811
[email protected]9c00f002009-11-05 22:37:421812WebSharedWorker* RenderView::createSharedWorker(
1813 WebFrame* frame, const WebURL& url, const WebString& name,
[email protected]30447b62009-11-13 01:13:371814 unsigned long long document_id) {
[email protected]9c00f002009-11-05 22:37:421815
[email protected]30447b62009-11-13 01:13:371816 int route_id = MSG_ROUTING_NONE;
[email protected]6de0bcf2010-02-17 22:00:511817 bool exists = false;
[email protected]30447b62009-11-13 01:13:371818 bool url_mismatch = false;
[email protected]6de0bcf2010-02-17 22:00:511819 ViewHostMsg_CreateWorker_Params params;
1820 params.url = url;
1821 params.is_shared = true;
1822 params.name = name;
1823 params.document_id = document_id;
1824 params.render_view_route_id = routing_id_;
1825 params.route_id = MSG_ROUTING_NONE;
[email protected]f9bc9c02010-05-24 19:19:231826 params.parent_appcache_host_id = 0;
1827 params.script_resource_appcache_id = 0;
[email protected]30447b62009-11-13 01:13:371828 Send(new ViewHostMsg_LookupSharedWorker(
[email protected]6de0bcf2010-02-17 22:00:511829 params, &exists, &route_id, &url_mismatch));
[email protected]30447b62009-11-13 01:13:371830 if (url_mismatch) {
1831 return NULL;
1832 } else {
1833 return new WebSharedWorkerProxy(RenderThread::current(),
[email protected]0791d3a2010-01-28 01:28:491834 document_id,
[email protected]6de0bcf2010-02-17 22:00:511835 exists,
[email protected]30447b62009-11-13 01:13:371836 route_id,
1837 routing_id_);
1838 }
[email protected]9c00f002009-11-05 22:37:421839}
1840
[email protected]3d9689372009-09-10 04:29:171841WebMediaPlayer* RenderView::createMediaPlayer(
1842 WebFrame* frame, WebMediaPlayerClient* client) {
[email protected]16e923d2011-04-30 00:41:441843 FOR_EACH_OBSERVER(
1844 RenderViewObserver, observers_, WillCreateMediaPlayer(frame, client));
[email protected]7198402c2011-04-11 12:15:171845
[email protected]f78d1dfc2011-01-15 07:09:271846 scoped_ptr<media::MessageLoopFactory> message_loop_factory(
1847 new media::MessageLoopFactoryImpl());
[email protected]f8db8132010-12-03 00:27:491848 scoped_ptr<media::FilterCollection> collection(
1849 new media::FilterCollection());
[email protected]457d8342010-10-23 01:20:371850
[email protected]3d9689372009-09-10 04:29:171851 // Add in any custom filter factories first.
1852 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
1853 if (!cmd_line->HasSwitch(switches::kDisableAudio)) {
1854 // Add the chrome specific audio renderer.
[email protected]b7ba5b52010-11-15 22:04:491855 collection->AddAudioRenderer(new AudioRendererImpl(audio_message_filter()));
[email protected]3d9689372009-09-10 04:29:171856 }
1857
[email protected]3bb08602010-10-07 21:47:171858 if (cmd_line->HasSwitch(switches::kEnableAcceleratedDecoding) &&
[email protected]11c4c812010-10-22 19:50:121859 !cmd_line->HasSwitch(switches::kDisableAcceleratedCompositing)) {
[email protected]5aa6a312010-11-06 00:00:071860 WebGraphicsContext3DCommandBufferImpl* context =
1861 static_cast<WebGraphicsContext3DCommandBufferImpl*>(
1862 frame->view()->graphicsContext3D());
1863 if (!context)
1864 return NULL;
[email protected]a9a43012010-11-05 01:54:061865
[email protected]5aa6a312010-11-06 00:00:071866 // Add the hardware video decoder factory.
1867 // TODO(hclam): This will cause the renderer process to crash on context
1868 // lost.
1869 bool ret = context->makeContextCurrent();
1870 CHECK(ret) << "Failed to switch context";
[email protected]b7ba5b52010-11-15 22:04:491871 collection->AddVideoDecoder(new IpcVideoDecoder(
[email protected]5aa6a312010-11-06 00:00:071872 MessageLoop::current(), context->context()));
[email protected]3bb08602010-10-07 21:47:171873 }
1874
[email protected]457d8342010-10-23 01:20:371875 scoped_refptr<webkit_glue::WebVideoRenderer> video_renderer;
[email protected]77128dec2010-11-08 17:05:311876 bool pts_logging = cmd_line->HasSwitch(switches::kEnableVideoLogging);
1877 scoped_refptr<webkit_glue::VideoRendererImpl> renderer(
1878 new webkit_glue::VideoRendererImpl(pts_logging));
[email protected]b7ba5b52010-11-15 22:04:491879 collection->AddVideoRenderer(renderer);
[email protected]77128dec2010-11-08 17:05:311880 video_renderer = renderer;
[email protected]8400e032010-02-26 18:50:111881
[email protected]a8e24d522010-12-01 07:13:581882 scoped_ptr<webkit_glue::WebMediaPlayerImpl> result(
[email protected]f78d1dfc2011-01-15 07:09:271883 new webkit_glue::WebMediaPlayerImpl(client,
1884 collection.release(),
1885 message_loop_factory.release()));
[email protected]79684282010-12-06 21:15:461886 if (!result->Initialize(frame,
[email protected]a8e24d522010-12-01 07:13:581887 cmd_line->HasSwitch(switches::kSimpleDataSource),
1888 video_renderer)) {
1889 return NULL;
1890 }
1891 return result.release();
[email protected]3d9689372009-09-10 04:29:171892}
1893
[email protected]035545f2010-04-09 13:10:211894WebApplicationCacheHost* RenderView::createApplicationCacheHost(
1895 WebFrame* frame, WebApplicationCacheHostClient* client) {
1896 return new RendererWebApplicationCacheHostImpl(
1897 FromWebView(frame->view()), client,
1898 RenderThread::current()->appcache_dispatcher()->backend_proxy());
1899}
1900
[email protected]8ff181072010-11-29 17:09:381901WebCookieJar* RenderView::cookieJar(WebFrame* frame) {
1902 return &cookie_jar_;
1903}
1904
[email protected]5041f982010-08-11 21:40:451905void RenderView::frameDetached(WebFrame* frame) {
[email protected]676126f72011-01-15 00:03:511906 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame));
[email protected]5041f982010-08-11 21:40:451907}
1908
[email protected]3d9689372009-09-10 04:29:171909void RenderView::willClose(WebFrame* frame) {
[email protected]676126f72011-01-15 00:03:511910 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame));
[email protected]3d9689372009-09-10 04:29:171911}
1912
1913void RenderView::loadURLExternally(
1914 WebFrame* frame, const WebURLRequest& request,
1915 WebNavigationPolicy policy) {
[email protected]efce17b2009-09-11 18:04:591916 GURL referrer(request.httpHeaderField(WebString::fromUTF8("Referer")));
1917 if (policy == WebKit::WebNavigationPolicyDownload) {
1918 Send(new ViewHostMsg_DownloadUrl(routing_id_, request.url(), referrer));
1919 } else {
1920 OpenURL(request.url(), referrer, policy);
1921 }
[email protected]3d9689372009-09-10 04:29:171922}
1923
1924WebNavigationPolicy RenderView::decidePolicyForNavigation(
1925 WebFrame* frame, const WebURLRequest& request, WebNavigationType type,
[email protected]65b95cd2009-10-09 05:10:221926 const WebNode&, WebNavigationPolicy default_policy, bool is_redirect) {
[email protected]3d9689372009-09-10 04:29:171927 // Webkit is asking whether to navigate to a new URL.
1928 // This is fine normally, except if we're showing UI from one security
1929 // context and they're trying to navigate to a different context.
1930 const GURL& url = request.url();
1931
[email protected]d19ea342011-04-20 20:31:131932 // A content initiated navigation may have originated from a link-click,
1933 // script, drag-n-drop operation, etc.
1934 bool is_content_initiated =
1935 NavigationState::FromDataSource(frame->provisionalDataSource())->
1936 is_content_initiated();
1937
[email protected]3d9689372009-09-10 04:29:171938 // If the browser is interested, then give it a chance to look at top level
[email protected]3a8eecb2010-04-22 23:56:301939 // navigations.
[email protected]d19ea342011-04-20 20:31:131940 if (is_content_initiated &&
1941 renderer_preferences_.browser_handles_top_level_requests &&
[email protected]8079b362010-05-07 18:37:451942 IsNonLocalTopLevelNavigation(url, frame, type)) {
[email protected]61c9f032010-03-31 23:04:191943 GURL referrer(request.httpHeaderField(WebString::fromUTF8("Referer")));
[email protected]a58db8b2010-08-24 01:51:231944 // Reset these counters as the RenderView could be reused for the next
1945 // navigation.
1946 page_id_ = -1;
[email protected]a58db8b2010-08-24 01:51:231947 last_page_id_sent_to_browser_ = -1;
[email protected]61c9f032010-03-31 23:04:191948 OpenURL(url, referrer, default_policy);
1949 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
[email protected]3d9689372009-09-10 04:29:171950 }
1951
[email protected]a6b960ad972010-09-01 19:53:581952 GURL old_url(frame->url());
[email protected]3d9689372009-09-10 04:29:171953
[email protected]6101c342010-12-16 22:44:371954 // Detect when we're crossing a permission-based boundary (e.g. into or out of
[email protected]c39f9bf2011-02-12 00:43:551955 // an extension or app origin, leaving a WebUI page, etc). We only care about
[email protected]8f4da8c2011-02-09 19:49:571956 // top-level navigations within the current tab (as opposed to, for example,
[email protected]6101c342010-12-16 22:44:371957 // opening a new window). But we sometimes navigate to about:blank to clear a
1958 // tab, and we want to still allow that.
1959 //
[email protected]8f4da8c2011-02-09 19:49:571960 // Note: we do this only for GET requests because our mechanism for switching
1961 // processes only issues GET requests. In particular, POST requests don't
1962 // work, because this mechanism does not preserve form POST data. If it
1963 // becomes necessary to support process switching for POST requests, we will
1964 // need to send the request's httpBody data up to the browser process, and
1965 // issue a special POST navigation in WebKit (via
1966 // FrameLoader::loadFrameRequest). See ResourceDispatcher and WebURLLoaderImpl
1967 // for examples of how to send the httpBody data.
1968 // Note2: We normally don't do this for browser-initiated navigations, since
1969 // it's pointless to tell the browser about navigations it gave us. But
1970 // we do potentially ask the browser to handle a redirect that was originally
1971 // initiated by the browser. See http://crbug.com/70943
1972 //
1973 // TODO(creis): Move this redirect check to the browser process to avoid
1974 // ping-ponging. See http://crbug.com/72380.
1975 if (!frame->parent() && (is_content_initiated || is_redirect) &&
[email protected]6101c342010-12-16 22:44:371976 default_policy == WebKit::WebNavigationPolicyCurrentTab &&
1977 request.httpMethod() == "GET" && !url.SchemeIs(chrome::kAboutScheme)) {
1978 bool send_referrer = false;
1979 bool should_fork =
[email protected]c09163a2011-02-15 00:05:551980 BindingsPolicy::is_web_ui_enabled(enabled_bindings_) ||
[email protected]3d9689372009-09-10 04:29:171981 frame->isViewSourceModeEnabled() ||
[email protected]6101c342010-12-16 22:44:371982 url.SchemeIs(chrome::kViewSourceScheme);
[email protected]5351dbc2010-08-27 15:22:111983
[email protected]e48869a2011-04-01 19:56:031984 if (!should_fork) {
1985 // Give the embedder a chance.
1986 should_fork = content::GetContentClient()->renderer()->ShouldFork(
1987 frame, url, is_content_initiated, &send_referrer);
[email protected]6101c342010-12-16 22:44:371988 }
1989
1990 if (should_fork) {
[email protected]5351dbc2010-08-27 15:22:111991 GURL referrer(request.httpHeaderField(WebString::fromUTF8("Referer")));
[email protected]6101c342010-12-16 22:44:371992 OpenURL(url, send_referrer ? referrer : GURL(), default_policy);
[email protected]5351dbc2010-08-27 15:22:111993 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
1994 }
[email protected]3d9689372009-09-10 04:29:171995 }
1996
1997 // Detect when a page is "forking" a new tab that can be safely rendered in
1998 // its own process. This is done by sites like Gmail that try to open links
1999 // in new windows without script connections back to the original page. We
2000 // treat such cases as browser navigations (in which we will create a new
2001 // renderer for a cross-site navigation), rather than WebKit navigations.
2002 //
2003 // We use the following heuristic to decide whether to fork a new page in its
2004 // own process:
2005 // The parent page must open a new tab to about:blank, set the new tab's
2006 // window.opener to null, and then redirect the tab to a cross-site URL using
2007 // JavaScript.
[email protected]007a848b2009-10-26 15:55:462008 //
2009 // TODO(creis): Deprecate this logic once we can rely on rel=noreferrer
2010 // (see below).
[email protected]3d9689372009-09-10 04:29:172011 bool is_fork =
2012 // Must start from a tab showing about:blank, which is later redirected.
[email protected]a6b960ad972010-09-01 19:53:582013 old_url == GURL(chrome::kAboutBlankURL) &&
[email protected]3d9689372009-09-10 04:29:172014 // Must be the first real navigation of the tab.
[email protected]48c9cf2d2009-09-16 16:47:522015 historyBackListCount() < 1 &&
2016 historyForwardListCount() < 1 &&
[email protected]3d9689372009-09-10 04:29:172017 // The parent page must have set the child's window.opener to null before
2018 // redirecting to the desired URL.
2019 frame->opener() == NULL &&
2020 // Must be a top-level frame.
2021 frame->parent() == NULL &&
2022 // Must not have issued the request from this page.
2023 is_content_initiated &&
2024 // Must be targeted at the current tab.
2025 default_policy == WebKit::WebNavigationPolicyCurrentTab &&
2026 // Must be a JavaScript navigation, which appears as "other".
2027 type == WebKit::WebNavigationTypeOther;
[email protected]007a848b2009-10-26 15:55:462028
2029 // Recognize if this navigation is from a link with rel=noreferrer and
2030 // target=_blank attributes, in which case the opener will be suppressed. If
2031 // so, it is safe to load cross-site pages in a separate process, so we
2032 // should let the browser handle it.
2033 bool is_noreferrer_and_blank_target =
2034 // Frame should be top level and not yet navigated.
2035 frame->parent() == NULL &&
2036 frame->url().isEmpty() &&
2037 historyBackListCount() < 1 &&
2038 historyForwardListCount() < 1 &&
2039 // Links with rel=noreferrer will have no Referer field, and their
2040 // resulting frame will have its window.opener suppressed.
2041 // TODO(creis): should add a request.httpReferrer() method to help avoid
2042 // typos on the unusual spelling of Referer.
2043 request.httpHeaderField(WebString::fromUTF8("Referer")).isNull() &&
2044 opener_suppressed_ &&
2045 frame->opener() == NULL &&
2046 // Links with target=_blank will have no name.
2047 frame->name().isNull() &&
2048 // Another frame (with a non-empty creator) should have initiated the
2049 // request, targeted at this frame.
2050 !creator_url_.is_empty() &&
2051 is_content_initiated &&
2052 default_policy == WebKit::WebNavigationPolicyCurrentTab &&
2053 type == WebKit::WebNavigationTypeOther;
2054
2055 if (is_fork || is_noreferrer_and_blank_target) {
[email protected]3d9689372009-09-10 04:29:172056 // Open the URL via the browser, not via WebKit.
2057 OpenURL(url, GURL(), default_policy);
2058 return WebKit::WebNavigationPolicyIgnore;
2059 }
2060
2061 return default_policy;
2062}
2063
[email protected]6069da8c2009-10-20 20:33:492064bool RenderView::canHandleRequest(
2065 WebFrame* frame, const WebURLRequest& request) {
2066 // We allow WebKit to think that everything can be handled even though
2067 // browser-side we limit what we load.
[email protected]7b7a7dc2009-10-19 02:23:342068 return true;
2069}
2070
[email protected]6069da8c2009-10-20 20:33:492071WebURLError RenderView::cannotHandleRequestError(
2072 WebFrame* frame, const WebURLRequest& request) {
2073 NOTREACHED(); // Since we said we can handle all requests.
2074 return WebURLError();
2075}
2076
2077WebURLError RenderView::cancelledError(
2078 WebFrame* frame, const WebURLRequest& request) {
2079 WebURLError error;
2080 error.domain = WebString::fromUTF8(net::kErrorDomain);
2081 error.reason = net::ERR_ABORTED;
2082 error.unreachableURL = request.url();
2083 return error;
[email protected]7b7a7dc2009-10-19 02:23:342084}
2085
2086void RenderView::unableToImplementPolicyWithError(
[email protected]6069da8c2009-10-20 20:33:492087 WebFrame*, const WebURLError&) {
2088 NOTREACHED(); // Since we said we can handle all requests.
[email protected]7b7a7dc2009-10-19 02:23:342089}
2090
[email protected]90eeddb2010-05-06 21:06:432091void RenderView::willSendSubmitEvent(WebKit::WebFrame* frame,
2092 const WebKit::WebFormElement& form) {
2093 // Some login forms have onSubmit handlers that put a hash of the password
2094 // into a hidden field and then clear the password. (Issue 28910.)
2095 // This method gets called before any of those handlers run, so save away
2096 // a copy of the password in case it gets lost.
2097 NavigationState* navigation_state =
2098 NavigationState::FromDataSource(frame->dataSource());
2099 navigation_state->set_password_form_data(
2100 PasswordFormDomManager::CreatePasswordForm(form));
2101}
2102
[email protected]979c28b2009-11-07 01:30:482103void RenderView::willSubmitForm(WebFrame* frame, const WebFormElement& form) {
[email protected]3d9689372009-09-10 04:29:172104 NavigationState* navigation_state =
2105 NavigationState::FromDataSource(frame->provisionalDataSource());
2106
2107 if (navigation_state->transition_type() == PageTransition::LINK)
2108 navigation_state->set_transition_type(PageTransition::FORM_SUBMIT);
2109
2110 // Save these to be processed when the ensuing navigation is committed.
[email protected]ce0e250d2009-10-23 21:00:352111 WebSearchableFormData web_searchable_form_data(form);
2112 navigation_state->set_searchable_form_url(web_searchable_form_data.url());
2113 navigation_state->set_searchable_form_encoding(
[email protected]b7910b3a2010-01-13 18:33:212114 web_searchable_form_data.encoding().utf8());
[email protected]90eeddb2010-05-06 21:06:432115 PasswordForm* password_form_data =
2116 PasswordFormDomManager::CreatePasswordForm(form);
2117 navigation_state->set_password_form_data(password_form_data);
2118
[email protected]098c95cb2011-04-28 16:49:012119 // In order to save the password that the user actually typed and not one
2120 // that may have gotten transformed by the site prior to submit, recover it
2121 // from the form contents already stored by |willSendSubmitEvent| into the
2122 // dataSource's NavigationState (as opposed to the provisionalDataSource's,
2123 // which is what we're storing into now.)
2124 if (password_form_data) {
[email protected]90eeddb2010-05-06 21:06:432125 NavigationState* old_navigation_state =
2126 NavigationState::FromDataSource(frame->dataSource());
2127 if (old_navigation_state) {
2128 PasswordForm* old_form_data = old_navigation_state->password_form_data();
2129 if (old_form_data && old_form_data->action == password_form_data->action)
2130 password_form_data->password_value = old_form_data->password_value;
2131 }
2132 }
[email protected]3d9689372009-09-10 04:29:172133
[email protected]2a5b1732011-04-01 23:55:552134 FOR_EACH_OBSERVER(
2135 RenderViewObserver, observers_, WillSubmitForm(frame, form));
[email protected]3d9689372009-09-10 04:29:172136}
2137
2138void RenderView::willPerformClientRedirect(
2139 WebFrame* frame, const WebURL& from, const WebURL& to, double interval,
2140 double fire_time) {
[email protected]eb0bff942011-04-07 22:08:382141 FOR_EACH_OBSERVER(
2142 RenderViewObserver, observers_,
2143 WillPerformClientRedirect(frame, from, to, interval, fire_time));
[email protected]3d9689372009-09-10 04:29:172144}
2145
2146void RenderView::didCancelClientRedirect(WebFrame* frame) {
[email protected]eb0bff942011-04-07 22:08:382147 FOR_EACH_OBSERVER(
2148 RenderViewObserver, observers_, DidCancelClientRedirect(frame));
[email protected]3d9689372009-09-10 04:29:172149}
2150
2151void RenderView::didCompleteClientRedirect(
2152 WebFrame* frame, const WebURL& from) {
2153 if (!frame->parent())
2154 completed_client_redirect_src_ = from;
[email protected]eb0bff942011-04-07 22:08:382155 FOR_EACH_OBSERVER(
2156 RenderViewObserver, observers_, DidCompleteClientRedirect(frame, from));
[email protected]3d9689372009-09-10 04:29:172157}
2158
2159void RenderView::didCreateDataSource(WebFrame* frame, WebDataSource* ds) {
2160 // The rest of RenderView assumes that a WebDataSource will always have a
2161 // non-null NavigationState.
[email protected]a7ccc4d2010-01-27 08:14:482162 bool content_initiated = !pending_navigation_state_.get();
2163 NavigationState* state = content_initiated ?
2164 NavigationState::CreateContentInitiated() :
2165 pending_navigation_state_.release();
[email protected]8a3125a712010-08-09 18:58:512166
[email protected]8a3125a712010-08-09 18:58:512167 // NavigationState::referred_by_prefetcher_ is true if we are
2168 // navigating from a page that used prefetching using a link on that
2169 // page. We are early enough in the request process here that we
2170 // can still see the NavigationState of the previous page and set
2171 // this value appropriately.
2172 // TODO(gavinp): catch the important case of navigation in a new
2173 // renderer process.
2174 if (webview()) {
[email protected]e47aec52010-08-12 00:50:302175 if (WebFrame* old_frame = webview()->mainFrame()) {
[email protected]05c8e502010-08-15 15:13:522176 const WebURLRequest& original_request = ds->originalRequest();
[email protected]8a3125a712010-08-09 18:58:512177 const GURL referrer(
2178 original_request.httpHeaderField(WebString::fromUTF8("Referer")));
2179 if (!referrer.is_empty() &&
2180 NavigationState::FromDataSource(
2181 old_frame->dataSource())->was_prefetcher()) {
2182 for (;old_frame;old_frame = old_frame->traverseNext(false)) {
2183 WebDataSource* old_frame_ds = old_frame->dataSource();
2184 if (old_frame_ds && referrer == GURL(old_frame_ds->request().url())) {
2185 state->set_was_referred_by_prefetcher(true);
2186 break;
2187 }
2188 }
2189 }
2190 }
2191 }
2192
[email protected]4c1b6f0b2010-02-07 16:38:182193 if (content_initiated) {
[email protected]05c8e502010-08-15 15:13:522194 const WebURLRequest& request = ds->request();
[email protected]8a3125a712010-08-09 18:58:512195 switch (request.cachePolicy()) {
[email protected]4c1b6f0b2010-02-07 16:38:182196 case WebURLRequest::UseProtocolCachePolicy: // normal load.
2197 state->set_load_type(NavigationState::LINK_LOAD_NORMAL);
2198 break;
2199 case WebURLRequest::ReloadIgnoringCacheData: // reload.
2200 state->set_load_type(NavigationState::LINK_LOAD_RELOAD);
2201 break;
2202 case WebURLRequest::ReturnCacheDataElseLoad: // allow stale data.
2203 state->set_load_type(NavigationState::LINK_LOAD_CACHE_STALE_OK);
2204 break;
2205 case WebURLRequest::ReturnCacheDataDontLoad: // Don't re-post.
2206 state->set_load_type(NavigationState::LINK_LOAD_CACHE_ONLY);
2207 break;
2208 }
2209 }
[email protected]fa7b6b542009-11-03 05:02:302210
[email protected]16e923d2011-04-30 00:41:442211 ds->setExtraData(state);
[email protected]11f595b22011-04-11 14:48:502212
[email protected]946a0032011-03-31 18:42:282213 FOR_EACH_OBSERVER(
2214 RenderViewObserver, observers_, DidCreateDataSource(frame, ds));
[email protected]3d9689372009-09-10 04:29:172215}
2216
2217void RenderView::didStartProvisionalLoad(WebFrame* frame) {
2218 WebDataSource* ds = frame->provisionalDataSource();
2219 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
2220
[email protected]3d9689372009-09-10 04:29:172221 // Update the request time if WebKit has better knowledge of it.
2222 if (navigation_state->request_time().is_null()) {
2223 double event_time = ds->triggeringEventTime();
2224 if (event_time != 0.0)
2225 navigation_state->set_request_time(Time::FromDoubleT(event_time));
2226 }
2227
[email protected]05c8e502010-08-15 15:13:522228 // Start time is only set after request time.
2229 navigation_state->set_start_load_time(Time::Now());
2230
[email protected]3d9689372009-09-10 04:29:172231 bool is_top_most = !frame->parent();
2232 if (is_top_most) {
2233 navigation_gesture_ = frame->isProcessingUserGesture() ?
[email protected]cd448092010-12-06 23:49:132234 NavigationGestureUser : NavigationGestureAuto;
[email protected]3d9689372009-09-10 04:29:172235
2236 // Make sure redirect tracking state is clear for the new load.
2237 completed_client_redirect_src_ = GURL();
2238 } else if (frame->parent()->isLoading()) {
2239 // Take note of AUTO_SUBFRAME loads here, so that we can know how to
[email protected]4fb66842009-12-04 21:41:002240 // load an error page. See didFailProvisionalLoad.
[email protected]3d9689372009-09-10 04:29:172241 navigation_state->set_transition_type(PageTransition::AUTO_SUBFRAME);
2242 }
2243
[email protected]28685da92011-02-07 21:49:172244 FOR_EACH_OBSERVER(
2245 RenderViewObserver, observers_, DidStartProvisionalLoad(frame));
2246
[email protected]3d9689372009-09-10 04:29:172247 Send(new ViewHostMsg_DidStartProvisionalLoadForFrame(
[email protected]dabb0d12010-10-05 12:50:072248 routing_id_, frame->identifier(), is_top_most, ds->request().url()));
[email protected]3d9689372009-09-10 04:29:172249}
2250
2251void RenderView::didReceiveServerRedirectForProvisionalLoad(WebFrame* frame) {
2252 if (frame->parent())
2253 return;
2254 // Received a redirect on the main frame.
2255 WebDataSource* data_source = frame->provisionalDataSource();
2256 if (!data_source) {
2257 // Should only be invoked when we have a data source.
2258 NOTREACHED();
2259 return;
2260 }
2261 std::vector<GURL> redirects;
2262 GetRedirectChain(data_source, &redirects);
2263 if (redirects.size() >= 2) {
[email protected]40bd6582009-12-04 23:49:512264 Send(new ViewHostMsg_DidRedirectProvisionalLoad(routing_id_, page_id_,
2265 redirects[redirects.size() - 2], redirects.back()));
[email protected]3d9689372009-09-10 04:29:172266 }
2267}
2268
[email protected]40bd6582009-12-04 23:49:512269void RenderView::didFailProvisionalLoad(WebFrame* frame,
2270 const WebURLError& error) {
[email protected]3d9689372009-09-10 04:29:172271 // Notify the browser that we failed a provisional load with an error.
2272 //
2273 // Note: It is important this notification occur before DidStopLoading so the
2274 // SSL manager can react to the provisional load failure before being
2275 // notified the load stopped.
2276 //
2277 WebDataSource* ds = frame->provisionalDataSource();
2278 DCHECK(ds);
2279
2280 const WebURLRequest& failed_request = ds->request();
2281
[email protected]28685da92011-02-07 21:49:172282 FOR_EACH_OBSERVER(
2283 RenderViewObserver, observers_, DidFailProvisionalLoad(frame, error));
2284
[email protected]3d9689372009-09-10 04:29:172285 bool show_repost_interstitial =
2286 (error.reason == net::ERR_CACHE_MISS &&
2287 EqualsASCII(failed_request.httpMethod(), "POST"));
2288 Send(new ViewHostMsg_DidFailProvisionalLoadWithError(
[email protected]dabb0d12010-10-05 12:50:072289 routing_id_, frame->identifier(), !frame->parent(), error.reason,
2290 error.unreachableURL, show_repost_interstitial));
[email protected]3d9689372009-09-10 04:29:172291
2292 // Don't display an error page if this is simply a cancelled load. Aside
2293 // from being dumb, WebCore doesn't expect it and it will cause a crash.
2294 if (error.reason == net::ERR_ABORTED)
2295 return;
2296
2297 // Make sure we never show errors in view source mode.
2298 frame->enableViewSourceMode(false);
2299
2300 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
2301
2302 // If this is a failed back/forward/reload navigation, then we need to do a
2303 // 'replace' load. This is necessary to avoid messing up session history.
2304 // Otherwise, we do a normal load, which simulates a 'go' navigation as far
2305 // as session history is concerned.
2306 //
2307 // AUTO_SUBFRAME loads should always be treated as loads that do not advance
2308 // the page id.
2309 //
2310 bool replace =
2311 navigation_state->pending_page_id() != -1 ||
2312 navigation_state->transition_type() == PageTransition::AUTO_SUBFRAME;
2313
2314 // If we failed on a browser initiated request, then make sure that our error
2315 // page load is regarded as the same browser initiated request.
2316 if (!navigation_state->is_content_initiated()) {
2317 pending_navigation_state_.reset(NavigationState::CreateBrowserInitiated(
2318 navigation_state->pending_page_id(),
[email protected]3cc72b12010-03-18 23:03:002319 navigation_state->pending_history_list_offset(),
[email protected]3d9689372009-09-10 04:29:172320 navigation_state->transition_type(),
2321 navigation_state->request_time()));
2322 }
2323
2324 // Provide the user with a more helpful error page?
2325 if (MaybeLoadAlternateErrorPage(frame, error, replace))
2326 return;
2327
2328 // Fallback to a local error page.
[email protected]3f853a52010-09-13 19:15:082329 LoadNavigationErrorPage(frame, failed_request, error, std::string(), replace);
[email protected]3d9689372009-09-10 04:29:172330}
2331
2332void RenderView::didReceiveDocumentData(
2333 WebFrame* frame, const char* data, size_t data_len,
2334 bool& prevent_default) {
2335 NavigationState* navigation_state =
2336 NavigationState::FromDataSource(frame->dataSource());
[email protected]06333afe2011-02-24 14:55:092337 navigation_state->set_use_error_page(false);
[email protected]3d9689372009-09-10 04:29:172338}
2339
[email protected]40bd6582009-12-04 23:49:512340void RenderView::didCommitProvisionalLoad(WebFrame* frame,
2341 bool is_new_navigation) {
[email protected]3d9689372009-09-10 04:29:172342 NavigationState* navigation_state =
2343 NavigationState::FromDataSource(frame->dataSource());
2344
2345 navigation_state->set_commit_load_time(Time::Now());
2346 if (is_new_navigation) {
[email protected]e15f680732010-11-23 22:30:202347 // When we perform a new navigation, we need to update the last committed
2348 // session history entry with state for the page we are leaving.
[email protected]3d9689372009-09-10 04:29:172349 UpdateSessionHistory(frame);
2350
2351 // We bump our Page ID to correspond with the new session history entry.
2352 page_id_ = next_page_id_++;
2353
[email protected]3cc72b12010-03-18 23:03:002354 // Advance our offset in session history, applying the length limit. There
2355 // is now no forward history.
2356 history_list_offset_++;
[email protected]9966325b2011-04-18 05:00:102357 if (history_list_offset_ >= content::kMaxSessionHistoryEntries)
2358 history_list_offset_ = content::kMaxSessionHistoryEntries - 1;
[email protected]3cc72b12010-03-18 23:03:002359 history_list_length_ = history_list_offset_ + 1;
[email protected]3d9689372009-09-10 04:29:172360 } else {
2361 // Inspect the navigation_state on this frame to see if the navigation
2362 // corresponds to a session history navigation... Note: |frame| may or
2363 // may not be the toplevel frame, but for the case of capturing session
2364 // history, the first committed frame suffices. We keep track of whether
2365 // we've seen this commit before so that only capture session history once
2366 // per navigation.
2367 //
2368 // Note that we need to check if the page ID changed. In the case of a
2369 // reload, the page ID doesn't change, and UpdateSessionHistory gets the
2370 // previous URL and the current page ID, which would be wrong.
2371 if (navigation_state->pending_page_id() != -1 &&
2372 navigation_state->pending_page_id() != page_id_ &&
2373 !navigation_state->request_committed()) {
2374 // This is a successful session history navigation!
2375 UpdateSessionHistory(frame);
2376 page_id_ = navigation_state->pending_page_id();
[email protected]3cc72b12010-03-18 23:03:002377
2378 history_list_offset_ = navigation_state->pending_history_list_offset();
[email protected]3d9689372009-09-10 04:29:172379 }
2380 }
2381
[email protected]28685da92011-02-07 21:49:172382 FOR_EACH_OBSERVER(RenderViewObserver, observers_,
2383 DidCommitProvisionalLoad(frame, is_new_navigation));
2384
[email protected]3d9689372009-09-10 04:29:172385 // Remember that we've already processed this request, so we don't update
2386 // the session history again. We do this regardless of whether this is
2387 // a session history navigation, because if we attempted a session history
2388 // navigation without valid HistoryItem state, WebCore will think it is a
2389 // new navigation.
2390 navigation_state->set_request_committed(true);
2391
2392 UpdateURL(frame);
2393
2394 // If this committed load was initiated by a client redirect, we're
2395 // at the last stop now, so clear it.
2396 completed_client_redirect_src_ = GURL();
2397
2398 // Check whether we have new encoding name.
[email protected]26aa0482009-09-30 16:55:272399 UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
[email protected]3d9689372009-09-10 04:29:172400}
2401
2402void RenderView::didClearWindowObject(WebFrame* frame) {
[email protected]9966325b2011-04-18 05:00:102403 FOR_EACH_OBSERVER(RenderViewObserver, observers_,
2404 DidClearWindowObject(frame));
2405
[email protected]0d7ae862010-10-01 13:52:452406 GURL frame_url = frame->url();
[email protected]c09163a2011-02-15 00:05:552407 if (BindingsPolicy::is_web_ui_enabled(enabled_bindings_) &&
[email protected]bfa83eb82010-10-06 08:41:252408 (frame_url.SchemeIs(chrome::kChromeUIScheme) ||
2409 frame_url.SchemeIs(chrome::kDataScheme))) {
[email protected]c50008512011-02-03 01:17:272410 GetWebUIBindings()->set_message_sender(this);
2411 GetWebUIBindings()->set_routing_id(routing_id_);
2412 GetWebUIBindings()->BindToJavascript(frame, "chrome");
[email protected]3d9689372009-09-10 04:29:172413 }
[email protected]3d9689372009-09-10 04:29:172414}
2415
2416void RenderView::didCreateDocumentElement(WebFrame* frame) {
[email protected]3d9689372009-09-10 04:29:172417 // Notify the browser about non-blank documents loading in the top frame.
2418 GURL url = frame->url();
[email protected]e0d481582009-09-15 21:06:252419 if (url.is_valid() && url.spec() != chrome::kAboutBlankURL) {
[email protected]26aa0482009-09-30 16:55:272420 if (frame == webview()->mainFrame())
[email protected]3d9689372009-09-10 04:29:172421 Send(new ViewHostMsg_DocumentAvailableInMainFrame(routing_id_));
2422 }
[email protected]e48869a2011-04-01 19:56:032423
2424 FOR_EACH_OBSERVER(RenderViewObserver, observers_,
2425 DidCreateDocumentElement(frame));
[email protected]3d9689372009-09-10 04:29:172426}
2427
[email protected]a3bc4d12011-04-20 17:22:212428void RenderView::didReceiveTitle(WebFrame* frame, const WebString& title,
2429 WebTextDirection direction) {
[email protected]6b2f7a82011-04-25 19:30:512430 // TODO: pass direction through various APIs.
2431 // http://code.google.com/p/chromium/issues/detail?id=79903
2432 UpdateTitle(frame, title);
[email protected]3d9689372009-09-10 04:29:172433
2434 // Also check whether we have new encoding name.
[email protected]26aa0482009-09-30 16:55:272435 UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
[email protected]3d9689372009-09-10 04:29:172436}
2437
[email protected]5019ef12010-04-27 17:26:582438void RenderView::didChangeIcons(WebFrame* frame) {
[email protected]9966325b2011-04-18 05:00:102439 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidChangeIcons(frame));
[email protected]5019ef12010-04-27 17:26:582440}
2441
[email protected]3d9689372009-09-10 04:29:172442void RenderView::didFinishDocumentLoad(WebFrame* frame) {
2443 WebDataSource* ds = frame->dataSource();
2444 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
2445 DCHECK(navigation_state);
2446 navigation_state->set_finish_document_load_time(Time::Now());
2447
[email protected]622474d2010-11-04 09:21:082448 Send(new ViewHostMsg_DocumentLoadedInFrame(routing_id_, frame->identifier()));
[email protected]3d9689372009-09-10 04:29:172449
[email protected]28685da92011-02-07 21:49:172450 FOR_EACH_OBSERVER(RenderViewObserver, observers_,
2451 DidFinishDocumentLoad(frame));
[email protected]3d9689372009-09-10 04:29:172452
2453 // Check whether we have new encoding name.
[email protected]26aa0482009-09-30 16:55:272454 UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
[email protected]3d9689372009-09-10 04:29:172455}
2456
2457void RenderView::didHandleOnloadEvents(WebFrame* frame) {
[email protected]25497492010-09-11 15:15:082458 if (webview()->mainFrame() == frame) {
2459 Send(new ViewHostMsg_DocumentOnLoadCompletedInMainFrame(routing_id_,
2460 page_id_));
2461 }
[email protected]3d9689372009-09-10 04:29:172462}
2463
2464void RenderView::didFailLoad(WebFrame* frame, const WebURLError& error) {
[email protected]28685da92011-02-07 21:49:172465 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidFailLoad(frame, error));
[email protected]3d9689372009-09-10 04:29:172466}
2467
2468void RenderView::didFinishLoad(WebFrame* frame) {
2469 WebDataSource* ds = frame->dataSource();
2470 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
2471 DCHECK(navigation_state);
2472 navigation_state->set_finish_load_time(Time::Now());
[email protected]4d44a1c2010-04-28 19:20:412473
[email protected]676126f72011-01-15 00:03:512474 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidFinishLoad(frame));
[email protected]fdd94a02010-11-05 08:07:172475
2476 Send(new ViewHostMsg_DidFinishLoad(routing_id_, frame->identifier()));
[email protected]3d9689372009-09-10 04:29:172477}
2478
[email protected]ccbe04e2010-03-17 17:58:432479void RenderView::didNavigateWithinPage(
[email protected]3d9689372009-09-10 04:29:172480 WebFrame* frame, bool is_new_navigation) {
2481 // If this was a reference fragment navigation that we initiated, then we
2482 // could end up having a non-null pending navigation state. We just need to
2483 // update the ExtraData on the datasource so that others who read the
2484 // ExtraData will get the new NavigationState. Similarly, if we did not
2485 // initiate this navigation, then we need to take care to reset any pre-
2486 // existing navigation state to a content-initiated navigation state.
2487 // DidCreateDataSource conveniently takes care of this for us.
2488 didCreateDataSource(frame, frame->dataSource());
2489
[email protected]af15bed2010-08-25 21:12:092490 NavigationState* new_state =
2491 NavigationState::FromDataSource(frame->dataSource());
2492 new_state->set_was_within_same_page(true);
2493
[email protected]3d9689372009-09-10 04:29:172494 didCommitProvisionalLoad(frame, is_new_navigation);
2495
[email protected]6b2f7a82011-04-25 19:30:512496 UpdateTitle(frame, frame->view()->mainFrame()->dataSource()->pageTitle());
[email protected]3d9689372009-09-10 04:29:172497}
2498
[email protected]476b6f82009-09-10 21:00:592499void RenderView::didUpdateCurrentHistoryItem(WebFrame* frame) {
[email protected]882daa92009-11-05 16:31:312500 StartNavStateSyncTimerIfNecessary();
[email protected]476b6f82009-09-10 21:00:592501}
2502
[email protected]3d9689372009-09-10 04:29:172503void RenderView::assignIdentifierToRequest(
2504 WebFrame* frame, unsigned identifier, const WebURLRequest& request) {
2505 // Ignore
2506}
2507
2508void RenderView::willSendRequest(
2509 WebFrame* frame, unsigned identifier, WebURLRequest& request,
2510 const WebURLResponse& redirect_response) {
[email protected]5e369672009-11-03 23:48:302511 WebFrame* top_frame = frame->top();
2512 if (!top_frame)
2513 top_frame = frame;
[email protected]8a3125a712010-08-09 18:58:512514 WebDataSource* provisional_data_source = top_frame->provisionalDataSource();
2515 WebDataSource* top_data_source = top_frame->dataSource();
2516 WebDataSource* data_source =
2517 provisional_data_source ? provisional_data_source : top_data_source;
[email protected]78d5cfe2011-02-04 08:43:222518
[email protected]e48869a2011-04-01 19:56:032519
[email protected]78d5cfe2011-02-04 08:43:222520 GURL request_url(request.url());
[email protected]e48869a2011-04-01 19:56:032521 GURL new_url;
2522 if (content::GetContentClient()->renderer()->WillSendRequest(
2523 frame, request_url, &new_url)) {
2524 request.setURL(WebURL(new_url));
[email protected]78d5cfe2011-02-04 08:43:222525 }
2526
[email protected]5e369672009-11-03 23:48:302527 if (data_source) {
2528 NavigationState* state = NavigationState::FromDataSource(data_source);
2529 if (state && state->is_cache_policy_override_set())
2530 request.setCachePolicy(state->cache_policy_override());
2531 }
[email protected]8a3125a712010-08-09 18:58:512532
2533 if (top_data_source) {
2534 NavigationState* state = NavigationState::FromDataSource(top_data_source);
2535 if (state && request.targetType() == WebURLRequest::TargetIsPrefetch)
2536 state->set_was_prefetcher(true);
2537 }
2538
[email protected]3d9689372009-09-10 04:29:172539 request.setRequestorID(routing_id_);
[email protected]cd448092010-12-06 23:49:132540 request.setHasUserGesture(frame->isProcessingUserGesture());
2541
[email protected]0a8db0d2011-04-13 15:15:402542 if (!renderer_preferences_.enable_referrers)
[email protected]7deade42010-03-05 09:33:132543 request.clearHTTPHeaderField("Referer");
[email protected]fa0a3432010-03-30 16:53:492544
[email protected]85cc78c2010-05-04 18:30:092545 // Temporary metrics, see site_isolation_metrics.h
2546 SiteIsolationMetrics::AddRequest(identifier, request.targetType());
[email protected]3d9689372009-09-10 04:29:172547}
2548
2549void RenderView::didReceiveResponse(
2550 WebFrame* frame, unsigned identifier, const WebURLResponse& response) {
[email protected]fa0a3432010-03-30 16:53:492551
[email protected]85cc78c2010-05-04 18:30:092552 // Temporary metrics, see site_isolation_metrics.h
2553 SiteIsolationMetrics::LogMimeTypeForCrossOriginRequest(frame,
2554 identifier,
2555 response);
[email protected]fa0a3432010-03-30 16:53:492556
[email protected]3d9689372009-09-10 04:29:172557 // Only do this for responses that correspond to a provisional data source
2558 // of the top-most frame. If we have a provisional data source, then we
2559 // can't have any sub-resources yet, so we know that this response must
2560 // correspond to a frame load.
2561 if (!frame->provisionalDataSource() || frame->parent())
2562 return;
2563
2564 // If we are in view source mode, then just let the user see the source of
[email protected]3f853a52010-09-13 19:15:082565 // the server's error page.
[email protected]3d9689372009-09-10 04:29:172566 if (frame->isViewSourceModeEnabled())
2567 return;
2568
[email protected]65041fa2010-05-21 06:56:532569 NavigationState* navigation_state =
2570 NavigationState::FromDataSource(frame->provisionalDataSource());
2571 CHECK(navigation_state);
[email protected]3f853a52010-09-13 19:15:082572 int http_status_code = response.httpStatusCode();
[email protected]65041fa2010-05-21 06:56:532573
[email protected]972ebdff2010-06-10 22:59:072574 // Record page load flags.
2575 navigation_state->set_was_fetched_via_spdy(response.wasFetchedViaSPDY());
2576 navigation_state->set_was_npn_negotiated(response.wasNpnNegotiated());
[email protected]193b0b892010-06-26 03:57:572577 navigation_state->set_was_alternate_protocol_available(
2578 response.wasAlternateProtocolAvailable());
[email protected]972ebdff2010-06-10 22:59:072579 navigation_state->set_was_fetched_via_proxy(response.wasFetchedViaProxy());
[email protected]3f853a52010-09-13 19:15:082580 navigation_state->set_http_status_code(http_status_code);
[email protected]06333afe2011-02-24 14:55:092581 // Whether or not the http status code actually corresponds to an error is
2582 // only checked when the page is done loading, if |use_error_page| is
2583 // still true.
2584 navigation_state->set_use_error_page(true);
[email protected]3d9689372009-09-10 04:29:172585}
2586
2587void RenderView::didFinishResourceLoad(
2588 WebFrame* frame, unsigned identifier) {
2589 NavigationState* navigation_state =
2590 NavigationState::FromDataSource(frame->dataSource());
[email protected]06333afe2011-02-24 14:55:092591 if (!navigation_state->use_error_page())
[email protected]3d9689372009-09-10 04:29:172592 return;
2593
[email protected]06333afe2011-02-24 14:55:092594 // Display error page, if appropriate.
[email protected]3f853a52010-09-13 19:15:082595 int http_status_code = navigation_state->http_status_code();
2596 if (http_status_code == 404) {
2597 // On 404s, try a remote search page as a fallback.
2598 const GURL& frame_url = frame->url();
[email protected]3d9689372009-09-10 04:29:172599
[email protected]3f853a52010-09-13 19:15:082600 const GURL& error_page_url = GetAlternateErrorPageURL(frame_url, HTTP_404);
[email protected]06333afe2011-02-24 14:55:092601 if (error_page_url.is_valid()) {
2602 WebURLError original_error;
2603 original_error.unreachableURL = frame_url;
[email protected]3d9689372009-09-10 04:29:172604
[email protected]06333afe2011-02-24 14:55:092605 navigation_state->set_alt_error_page_fetcher(
2606 new AltErrorPageResourceFetcher(
2607 error_page_url, frame, original_error,
2608 NewCallback(this, &RenderView::AltErrorPageFinished)));
2609 return;
2610 }
2611 }
[email protected]3d9689372009-09-10 04:29:172612
[email protected]9966325b2011-04-18 05:00:102613 content::GetContentClient()->renderer()->ShowErrorPage(
2614 this, frame, http_status_code);
[email protected]3d9689372009-09-10 04:29:172615}
2616
2617void RenderView::didFailResourceLoad(
2618 WebFrame* frame, unsigned identifier, const WebURLError& error) {
2619 // Ignore
2620}
2621
2622void RenderView::didLoadResourceFromMemoryCache(
2623 WebFrame* frame, const WebURLRequest& request,
2624 const WebURLResponse& response) {
2625 // Let the browser know we loaded a resource from the memory cache. This
2626 // message is needed to display the correct SSL indicators.
2627 Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(
2628 routing_id_,
2629 request.url(),
[email protected]3d9689372009-09-10 04:29:172630 response.securityInfo()));
2631}
2632
[email protected]6069da8c2009-10-20 20:33:492633void RenderView::didDisplayInsecureContent(WebFrame* frame) {
[email protected]e3d60e5d2009-09-25 21:08:292634 Send(new ViewHostMsg_DidDisplayInsecureContent(routing_id_));
2635}
2636
[email protected]92771112011-01-20 00:13:022637void RenderView::didRunInsecureContent(
2638 WebFrame* frame, const WebSecurityOrigin& origin, const WebURL& target) {
[email protected]e3d60e5d2009-09-25 21:08:292639 Send(new ViewHostMsg_DidRunInsecureContent(
2640 routing_id_,
[email protected]92771112011-01-20 00:13:022641 origin.toString().utf8(),
2642 target));
[email protected]e3d60e5d2009-09-25 21:08:292643}
2644
[email protected]5e56df82011-04-18 17:00:152645bool RenderView::allowImages(WebFrame* frame, bool enabled_per_settings) {
2646 ObserverListBase<RenderViewObserver>::Iterator it(observers_);
2647 RenderViewObserver* observer;
2648 while ((observer = it.GetNext()) != NULL)
2649 if (!observer->AllowImages(frame, enabled_per_settings))
2650 return false;
2651
2652 return true;
2653}
2654
2655bool RenderView::allowPlugins(WebFrame* frame, bool enabled_per_settings) {
2656 ObserverListBase<RenderViewObserver>::Iterator it(observers_);
2657 RenderViewObserver* observer;
2658 while ((observer = it.GetNext()) != NULL)
2659 if (!observer->AllowPlugins(frame, enabled_per_settings))
2660 return false;
2661
2662 return true;
2663}
2664
[email protected]7ea093ba2009-11-03 05:54:592665bool RenderView::allowScript(WebFrame* frame, bool enabled_per_settings) {
[email protected]5e56df82011-04-18 17:00:152666 ObserverListBase<RenderViewObserver>::Iterator it(observers_);
2667 RenderViewObserver* observer;
2668 while ((observer = it.GetNext()) != NULL)
2669 if (!observer->AllowScript(frame, enabled_per_settings))
2670 return false;
[email protected]7ea093ba2009-11-03 05:54:592671
[email protected]5e56df82011-04-18 17:00:152672 return true;
[email protected]7ea093ba2009-11-03 05:54:592673}
2674
[email protected]0a1a45432010-03-31 08:09:452675bool RenderView::allowDatabase(
2676 WebFrame* frame, const WebString& name, const WebString& display_name,
2677 unsigned long estimated_size) {
2678 WebSecurityOrigin origin = frame->securityOrigin();
2679 if (origin.isEmpty())
2680 return false; // Uninitialized document?
2681
2682 bool result;
[email protected]26a9acf2010-12-13 19:35:052683 if (!Send(new DatabaseHostMsg_Allow(routing_id_,
[email protected]0a1a45432010-03-31 08:09:452684 origin.toString().utf8(), name, display_name, estimated_size, &result)))
2685 return false;
[email protected]9fb83e82010-07-02 18:24:552686 Send(new ViewHostMsg_WebDatabaseAccessed(routing_id_,
2687 GURL(origin.toString().utf8()),
2688 name,
2689 display_name,
2690 estimated_size,
2691 !result));
[email protected]0a1a45432010-03-31 08:09:452692 return result;
2693}
[email protected]8934a3b2010-02-25 00:34:002694void RenderView::didNotAllowScript(WebKit::WebFrame* frame) {
[email protected]5e56df82011-04-18 17:00:152695 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidNotAllowScript(frame));
[email protected]8934a3b2010-02-25 00:34:002696}
2697
[email protected]c21f1d52010-03-04 03:19:432698void RenderView::didNotAllowPlugins(WebKit::WebFrame* frame) {
[email protected]5e56df82011-04-18 17:00:152699 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidNotAllowPlugins(frame));
[email protected]c21f1d52010-03-04 03:19:432700}
2701
[email protected]3d9689372009-09-10 04:29:172702void RenderView::didExhaustMemoryAvailableForScript(WebFrame* frame) {
2703 Send(new ViewHostMsg_JSOutOfMemory(routing_id_));
2704}
2705
[email protected]0c882b282009-10-07 17:01:282706void RenderView::didCreateScriptContext(WebFrame* frame) {
[email protected]e48869a2011-04-01 19:56:032707 content::GetContentClient()->renderer()->DidCreateScriptContext(frame);
[email protected]0c882b282009-10-07 17:01:282708}
2709
2710void RenderView::didDestroyScriptContext(WebFrame* frame) {
[email protected]e48869a2011-04-01 19:56:032711 content::GetContentClient()->renderer()->DidDestroyScriptContext(frame);
[email protected]0c882b282009-10-07 17:01:282712}
2713
2714void RenderView::didCreateIsolatedScriptContext(WebFrame* frame) {
[email protected]e48869a2011-04-01 19:56:032715 content::GetContentClient()->renderer()->DidCreateIsolatedScriptContext(
2716 frame);
[email protected]0c882b282009-10-07 17:01:282717}
2718
[email protected]af7eb3fb2010-09-23 21:31:062719bool RenderView::allowScriptExtension(WebFrame* frame,
2720 const WebString& extension_name,
2721 int extension_group) {
2722 // NULL in unit tests.
2723 if (!RenderThread::current())
2724 return true;
2725
2726 // Note: we prefer the provisional URL here instead of the document URL
2727 // because we might be currently loading an URL into a blank page.
2728 // See http://code.google.com/p/chromium/issues/detail?id=10924
2729 WebDataSource* ds = frame->provisionalDataSource();
2730 if (!ds)
2731 ds = frame->dataSource();
2732 return RenderThread::current()->AllowScriptExtension(
2733 extension_name.utf8(), ds->request().url(), extension_group);
2734}
2735
[email protected]fc86daa2010-03-30 23:52:532736void RenderView::logCrossFramePropertyAccess(WebFrame* frame,
2737 WebFrame* target,
2738 bool cross_origin,
2739 const WebString& property_name,
2740 unsigned long long event_id) {
[email protected]6cf19311f2011-04-14 23:06:022741 FOR_EACH_OBSERVER(
2742 RenderViewObserver,
2743 observers_,
2744 LogCrossFramePropertyAccess(
2745 frame, target, cross_origin, property_name, event_id));
[email protected]ab9eabac2010-03-16 16:54:102746}
2747
[email protected]3d9689372009-09-10 04:29:172748void RenderView::didChangeContentsSize(WebFrame* frame, const WebSize& size) {
[email protected]d8a179c2010-01-31 00:58:142749 CheckPreferredSize();
2750}
2751
2752void RenderView::CheckPreferredSize() {
[email protected]3d9689372009-09-10 04:29:172753 // We don't always want to send the change messages over IPC, only if we've
[email protected]ab32b16c2009-10-16 14:57:252754 // be put in that mode by getting a |ViewMsg_EnablePreferredSizeChangedMode|
[email protected]3d9689372009-09-10 04:29:172755 // message.
[email protected]705243f2010-05-05 19:58:072756 if (!send_preferred_size_changes_ || !webview())
2757 return;
[email protected]dfca5acf2010-03-22 03:28:432758
[email protected]705243f2010-05-05 19:58:072759 // WebCore likes to tell us things have changed even when they haven't, so
2760 // cache the width and height and only send the IPC message when we're sure
2761 // they're different.
2762 gfx::Size size(webview()->mainFrame()->contentsPreferredWidth(),
2763 webview()->mainFrame()->documentElementScrollHeight());
[email protected]8205d742010-10-22 23:51:532764
2765 // In the presence of zoom, these sizes are still reported as if unzoomed,
2766 // so we need to adjust.
2767 double zoom_factor = WebView::zoomLevelToZoomFactor(webview()->zoomLevel());
2768 size.set_width(static_cast<int>(size.width() * zoom_factor));
2769 size.set_height(static_cast<int>(size.height() * zoom_factor));
2770
[email protected]705243f2010-05-05 19:58:072771 if (size == preferred_size_)
2772 return;
[email protected]c27324b2009-11-19 22:44:292773
[email protected]705243f2010-05-05 19:58:072774 preferred_size_ = size;
2775 Send(new ViewHostMsg_DidContentsPreferredSizeChange(routing_id_,
2776 preferred_size_));
[email protected]3d9689372009-09-10 04:29:172777}
2778
[email protected]143dcd592009-11-06 21:33:492779void RenderView::didChangeScrollOffset(WebFrame* frame) {
2780 StartNavStateSyncTimerIfNecessary();
2781}
2782
[email protected]8922e1f2009-10-03 05:01:262783void RenderView::reportFindInPageMatchCount(int request_id, int count,
2784 bool final_update) {
[email protected]e7c58a32010-08-13 19:47:112785 int active_match_ordinal = -1; // -1 = don't update active match ordinal
2786 if (!count)
2787 active_match_ordinal = 0;
2788
2789 IPC::Message* msg = new ViewHostMsg_Find_Reply(
2790 routing_id_,
2791 request_id,
2792 count,
2793 gfx::Rect(),
2794 active_match_ordinal,
2795 final_update);
2796
[email protected]8922e1f2009-10-03 05:01:262797 // If we have a message that has been queued up, then we should just replace
2798 // it. The ACK from the browser will make sure it gets sent when the browser
2799 // wants it.
2800 if (queued_find_reply_message_.get()) {
[email protected]8922e1f2009-10-03 05:01:262801 queued_find_reply_message_.reset(msg);
2802 } else {
2803 // Send the search result over to the browser process.
[email protected]e7c58a32010-08-13 19:47:112804 Send(msg);
[email protected]8922e1f2009-10-03 05:01:262805 }
2806}
2807
2808void RenderView::reportFindInPageSelection(int request_id,
2809 int active_match_ordinal,
2810 const WebRect& selection_rect) {
2811 // Send the search result over to the browser process.
2812 Send(new ViewHostMsg_Find_Reply(routing_id_,
2813 request_id,
2814 -1,
2815 selection_rect,
2816 active_match_ordinal,
2817 false));
2818}
2819
[email protected]2b06a992010-08-21 05:48:222820void RenderView::openFileSystem(
2821 WebFrame* frame,
2822 WebFileSystem::Type type,
2823 long long size,
[email protected]d275d7a2010-11-03 01:34:492824 bool create,
[email protected]2b06a992010-08-21 05:48:222825 WebFileSystemCallbacks* callbacks) {
[email protected]c5a272d2010-09-27 18:37:082826 DCHECK(callbacks);
[email protected]2b06a992010-08-21 05:48:222827
2828 WebSecurityOrigin origin = frame->securityOrigin();
[email protected]c5a272d2010-09-27 18:37:082829 if (origin.isEmpty()) {
2830 // Uninitialized document?
2831 callbacks->didFail(WebKit::WebFileErrorAbort);
2832 return;
2833 }
[email protected]2b06a992010-08-21 05:48:222834
[email protected]c5a272d2010-09-27 18:37:082835 ChildThread::current()->file_system_dispatcher()->OpenFileSystem(
2836 GURL(origin.toString()), static_cast<fileapi::FileSystemType>(type),
[email protected]d275d7a2010-11-03 01:34:492837 size, create, new WebFileSystemCallbackDispatcher(callbacks));
[email protected]2b06a992010-08-21 05:48:222838}
2839
[email protected]10e5cf12011-04-13 04:10:402840void RenderView::queryStorageUsageAndQuota(
2841 WebFrame* frame,
2842 WebStorageQuotaType type,
2843 WebStorageQuotaCallbacks* callbacks) {
2844 DCHECK(frame);
2845 WebSecurityOrigin origin = frame->securityOrigin();
2846 if (origin.isEmpty()) {
2847 // Uninitialized document?
2848 callbacks->didFail(WebKit::WebStorageQuotaErrorAbort);
2849 return;
2850 }
2851 ChildThread::current()->quota_dispatcher()->QueryStorageUsageAndQuota(
2852 GURL(origin.toString()), type, callbacks);
2853}
2854
2855void RenderView::requestStorageQuota(
2856 WebFrame* frame,
2857 WebStorageQuotaType type,
2858 unsigned long long requested_size,
2859 WebStorageQuotaCallbacks* callbacks) {
2860 DCHECK(frame);
2861 WebSecurityOrigin origin = frame->securityOrigin();
2862 if (origin.isEmpty()) {
2863 // Uninitialized document?
2864 callbacks->didFail(WebKit::WebStorageQuotaErrorAbort);
2865 return;
2866 }
2867 ChildThread::current()->quota_dispatcher()->RequestStorageQuota(
2868 GURL(origin.toString()), type, requested_size, callbacks);
2869}
2870
[email protected]79dbc662009-09-04 05:42:512871// webkit_glue::WebPluginPageDelegate -----------------------------------------
2872
[email protected]191eb3f72010-12-21 06:27:502873webkit::npapi::WebPluginDelegate* RenderView::CreatePluginDelegate(
[email protected]4e0616e2010-05-28 14:55:532874 const FilePath& file_path,
2875 const std::string& mime_type) {
[email protected]f103ab72009-09-02 17:10:592876 if (!PluginChannelHost::IsListening())
2877 return NULL;
2878
[email protected]00c39612010-03-06 02:53:282879 bool in_process_plugin = RenderProcess::current()->UseInProcessPlugins();
[email protected]d032f492009-09-29 00:33:462880 if (in_process_plugin) {
[email protected]6876dff2010-01-15 19:38:092881#if defined(OS_WIN) // In-proc plugins aren't supported on Linux or Mac.
[email protected]e8f7a182011-03-10 00:50:222882 return webkit::npapi::WebPluginDelegateImpl::Create(
2883 file_path, mime_type, gfx::NativeViewFromId(host_window_));
[email protected]6876dff2010-01-15 19:38:092884#else
[email protected]e8f7a182011-03-10 00:50:222885 NOTIMPLEMENTED();
2886 return NULL;
[email protected]7b6616f2010-01-14 18:07:552887#endif
[email protected]f103ab72009-09-02 17:10:592888 }
2889
[email protected]4e0616e2010-05-28 14:55:532890 return new WebPluginDelegateProxy(mime_type, AsWeakPtr());
[email protected]f103ab72009-09-02 17:10:592891}
2892
2893void RenderView::CreatedPluginWindow(gfx::PluginWindowHandle window) {
[email protected]6981f7f2010-03-09 00:53:032894#if defined(USE_X11)
[email protected]f103ab72009-09-02 17:10:592895 RenderThread::current()->Send(new ViewHostMsg_CreatePluginContainer(
2896 routing_id(), window));
2897#endif
2898}
2899
2900void RenderView::WillDestroyPluginWindow(gfx::PluginWindowHandle window) {
[email protected]6981f7f2010-03-09 00:53:032901#if defined(USE_X11)
[email protected]f103ab72009-09-02 17:10:592902 RenderThread::current()->Send(new ViewHostMsg_DestroyPluginContainer(
2903 routing_id(), window));
2904#endif
2905 CleanupWindowInPluginMoves(window);
2906}
2907
[email protected]191eb3f72010-12-21 06:27:502908void RenderView::DidMovePlugin(const webkit::npapi::WebPluginGeometry& move) {
[email protected]f103ab72009-09-02 17:10:592909 SchedulePluginMove(move);
2910}
2911
2912void RenderView::DidStartLoadingForPlugin() {
2913 // TODO(darin): Make is_loading_ be a counter!
[email protected]48c9cf2d2009-09-16 16:47:522914 didStartLoading();
[email protected]f103ab72009-09-02 17:10:592915}
2916
2917void RenderView::DidStopLoadingForPlugin() {
2918 // TODO(darin): Make is_loading_ be a counter!
[email protected]48c9cf2d2009-09-16 16:47:522919 didStopLoading();
[email protected]f103ab72009-09-02 17:10:592920}
2921
[email protected]b921cfd22010-02-25 16:57:512922WebCookieJar* RenderView::GetCookieJar() {
2923 return &cookie_jar_;
2924}
2925
initial.commit09911bf2008-07-26 23:55:292926void RenderView::SyncNavigationState() {
2927 if (!webview())
2928 return;
2929
[email protected]26aa0482009-09-30 16:55:272930 const WebHistoryItem& item = webview()->mainFrame()->currentHistoryItem();
[email protected]ca948a22009-06-25 19:36:172931 if (item.isNull())
initial.commit09911bf2008-07-26 23:55:292932 return;
[email protected]ca948a22009-06-25 19:36:172933
2934 Send(new ViewHostMsg_UpdateState(
2935 routing_id_, page_id_, webkit_glue::HistoryItemToString(item)));
initial.commit09911bf2008-07-26 23:55:292936}
2937
[email protected]7ccddb8c2009-08-04 17:36:552938GURL RenderView::GetAlternateErrorPageURL(const GURL& failed_url,
initial.commit09911bf2008-07-26 23:55:292939 ErrorPageType error_type) {
[email protected]7ccddb8c2009-08-04 17:36:552940 if (failed_url.SchemeIsSecure()) {
initial.commit09911bf2008-07-26 23:55:292941 // If the URL that failed was secure, then the embedding web page was not
2942 // expecting a network attacker to be able to manipulate its contents. As
2943 // we fetch alternate error pages over HTTP, we would be allowing a network
2944 // attacker to manipulate the contents of the response if we tried to use
2945 // the link doctor here.
[email protected]810a52ef2010-01-08 01:22:152946 return GURL();
initial.commit09911bf2008-07-26 23:55:292947 }
2948
2949 // Grab the base URL from the browser process.
2950 if (!alternate_error_page_url_.is_valid())
[email protected]810a52ef2010-01-08 01:22:152951 return GURL();
initial.commit09911bf2008-07-26 23:55:292952
2953 // Strip query params from the failed URL.
2954 GURL::Replacements remove_params;
2955 remove_params.ClearUsername();
2956 remove_params.ClearPassword();
2957 remove_params.ClearQuery();
2958 remove_params.ClearRef();
[email protected]7ccddb8c2009-08-04 17:36:552959 const GURL url_to_send = failed_url.ReplaceComponents(remove_params);
[email protected]6fd28f642010-03-15 17:15:502960 std::string spec_to_send = url_to_send.spec();
2961 // Notify link doctor of the url truncation by sending of "?" at the end.
2962 if (failed_url.has_query())
2963 spec_to_send.append("?");
initial.commit09911bf2008-07-26 23:55:292964
2965 // Construct the query params to send to link doctor.
2966 std::string params(alternate_error_page_url_.query());
2967 params.append("&url=");
[email protected]6fd28f642010-03-15 17:15:502968 params.append(EscapeQueryParamValue(spec_to_send, true));
initial.commit09911bf2008-07-26 23:55:292969 params.append("&sourceid=chrome");
2970 params.append("&error=");
2971 switch (error_type) {
2972 case DNS_ERROR:
2973 params.append("dnserror");
2974 break;
2975
2976 case HTTP_404:
2977 params.append("http404");
2978 break;
2979
[email protected]5df266ac2008-10-15 19:50:132980 case CONNECTION_ERROR:
[email protected]e1f934b2009-01-26 20:41:332981 params.append("connectionfailure");
[email protected]5df266ac2008-10-15 19:50:132982 break;
2983
initial.commit09911bf2008-07-26 23:55:292984 default:
2985 NOTREACHED() << "unknown ErrorPageType";
2986 }
2987
2988 // OK, build the final url to return.
2989 GURL::Replacements link_doctor_params;
2990 link_doctor_params.SetQueryStr(params);
2991 GURL url = alternate_error_page_url_.ReplaceComponents(link_doctor_params);
2992 return url;
2993}
2994
[email protected]c50008512011-02-03 01:17:272995WebUIBindings* RenderView::GetWebUIBindings() {
2996 if (!web_ui_bindings_.get()) {
2997 web_ui_bindings_.reset(new WebUIBindings());
[email protected]c091c2c2010-09-17 19:05:462998 }
[email protected]c50008512011-02-03 01:17:272999 return web_ui_bindings_.get();
[email protected]c091c2c2010-09-17 19:05:463000}
3001
[email protected]0fdbf8c2010-07-08 20:33:013002WebKit::WebPlugin* RenderView::GetWebPluginFromPluginDocument() {
3003 return webview()->mainFrame()->document().to<WebPluginDocument>().plugin();
[email protected]24a7f3c2010-03-25 08:26:493004}
3005
[email protected]6069da8c2009-10-20 20:33:493006void RenderView::OnFind(int request_id, const string16& search_text,
3007 const WebFindOptions& options) {
[email protected]26aa0482009-09-30 16:55:273008 WebFrame* main_frame = webview()->mainFrame();
[email protected]24a7f3c2010-03-25 08:26:493009
3010 if (main_frame->document().isPluginDocument()) {
[email protected]24a7f3c2010-03-25 08:26:493011 if (options.findNext) {
3012 // Just navigate back/forward.
[email protected]0fdbf8c2010-07-08 20:33:013013 GetWebPluginFromPluginDocument()->selectFindResult(options.forward);
[email protected]24a7f3c2010-03-25 08:26:493014 } else {
[email protected]afdbd142010-07-10 08:01:233015 if (GetWebPluginFromPluginDocument()->startFind(
3016 search_text, options.matchCase, request_id)) {
[email protected]24a7f3c2010-03-25 08:26:493017 } else {
[email protected]e7c58a32010-08-13 19:47:113018 // Send "no results".
3019 Send(new ViewHostMsg_Find_Reply(routing_id_,
3020 request_id,
3021 0,
3022 gfx::Rect(),
3023 0,
3024 true));
[email protected]24a7f3c2010-03-25 08:26:493025 }
3026 }
3027 return;
3028 }
3029
[email protected]b4bb2502009-10-01 22:35:273030 WebFrame* frame_after_main = main_frame->traverseNext(true);
[email protected]26aa0482009-09-30 16:55:273031 WebFrame* focused_frame = webview()->focusedFrame();
initial.commit09911bf2008-07-26 23:55:293032 WebFrame* search_frame = focused_frame; // start searching focused frame.
3033
3034 bool multi_frame = (frame_after_main != main_frame);
3035
3036 // If we have multiple frames, we don't want to wrap the search within the
3037 // frame, so we check here if we only have main_frame in the chain.
3038 bool wrap_within_frame = !multi_frame;
3039
[email protected]b3f2b912009-04-09 16:18:523040 WebRect selection_rect;
initial.commit09911bf2008-07-26 23:55:293041 bool result = false;
3042
[email protected]7830da3e2009-11-06 16:27:263043 // If something is selected when we start searching it means we cannot just
3044 // increment the current match ordinal; we need to re-generate it.
3045 WebRange current_selection = focused_frame->selectionRange();
3046
initial.commit09911bf2008-07-26 23:55:293047 do {
[email protected]dd7daa82009-08-10 05:46:453048 result = search_frame->find(
[email protected]7ea066a2009-04-06 20:21:593049 request_id, search_text, options, wrap_within_frame, &selection_rect);
initial.commit09911bf2008-07-26 23:55:293050
3051 if (!result) {
3052 // don't leave text selected as you move to the next frame.
[email protected]a100d76bb2009-08-14 17:50:223053 search_frame->executeCommand(WebString::fromUTF8("Unselect"));
initial.commit09911bf2008-07-26 23:55:293054
3055 // Find the next frame, but skip the invisible ones.
3056 do {
3057 // What is the next frame to search? (we might be going backwards). Note
3058 // that we specify wrap=true so that search_frame never becomes NULL.
[email protected]7ea066a2009-04-06 20:21:593059 search_frame = options.forward ?
[email protected]b4bb2502009-10-01 22:35:273060 search_frame->traverseNext(true) :
3061 search_frame->traversePrevious(true);
[email protected]dd7daa82009-08-10 05:46:453062 } while (!search_frame->hasVisibleContent() &&
3063 search_frame != focused_frame);
initial.commit09911bf2008-07-26 23:55:293064
[email protected]884db412008-11-24 23:46:503065 // Make sure selection doesn't affect the search operation in new frame.
[email protected]a100d76bb2009-08-14 17:50:223066 search_frame->executeCommand(WebString::fromUTF8("Unselect"));
initial.commit09911bf2008-07-26 23:55:293067
3068 // If we have multiple frames and we have wrapped back around to the
3069 // focused frame, we need to search it once more allowing wrap within
3070 // the frame, otherwise it will report 'no match' if the focused frame has
3071 // reported matches, but no frames after the focused_frame contain a
3072 // match for the search word(s).
3073 if (multi_frame && search_frame == focused_frame) {
[email protected]dd7daa82009-08-10 05:46:453074 result = search_frame->find(
[email protected]7ea066a2009-04-06 20:21:593075 request_id, search_text, options, true, // Force wrapping.
3076 &selection_rect);
initial.commit09911bf2008-07-26 23:55:293077 }
3078 }
3079
[email protected]26aa0482009-09-30 16:55:273080 webview()->setFocusedFrame(search_frame);
initial.commit09911bf2008-07-26 23:55:293081 } while (!result && search_frame != focused_frame);
3082
[email protected]7830da3e2009-11-06 16:27:263083 if (options.findNext && current_selection.isNull()) {
[email protected]4f3dc372009-02-24 00:10:293084 // Force the main_frame to report the actual count.
[email protected]dd7daa82009-08-10 05:46:453085 main_frame->increaseMatchCount(0, request_id);
[email protected]4f3dc372009-02-24 00:10:293086 } else {
3087 // If nothing is found, set result to "0 of 0", otherwise, set it to
3088 // "-1 of 1" to indicate that we found at least one item, but we don't know
3089 // yet what is active.
3090 int ordinal = result ? -1 : 0; // -1 here means, we might know more later.
3091 int match_count = result ? 1 : 0; // 1 here means possibly more coming.
initial.commit09911bf2008-07-26 23:55:293092
[email protected]4f3dc372009-02-24 00:10:293093 // If we find no matches then this will be our last status update.
3094 // Otherwise the scoping effort will send more results.
3095 bool final_status_update = !result;
initial.commit09911bf2008-07-26 23:55:293096
[email protected]4f3dc372009-02-24 00:10:293097 // Send the search result over to the browser process.
[email protected]4f999132009-03-31 18:08:403098 Send(new ViewHostMsg_Find_Reply(routing_id_,
[email protected]7ea066a2009-04-06 20:21:593099 request_id,
[email protected]4f3dc372009-02-24 00:10:293100 match_count,
3101 selection_rect,
3102 ordinal,
3103 final_status_update));
initial.commit09911bf2008-07-26 23:55:293104
initial.commit09911bf2008-07-26 23:55:293105 // Scoping effort begins, starting with the mainframe.
3106 search_frame = main_frame;
3107
[email protected]dd7daa82009-08-10 05:46:453108 main_frame->resetMatchCount();
initial.commit09911bf2008-07-26 23:55:293109
3110 do {
3111 // Cancel all old scoping requests before starting a new one.
[email protected]dd7daa82009-08-10 05:46:453112 search_frame->cancelPendingScopingEffort();
initial.commit09911bf2008-07-26 23:55:293113
3114 // We don't start another scoping effort unless at least one match has
3115 // been found.
3116 if (result) {
3117 // Start new scoping request. If the scoping function determines that it
3118 // needs to scope, it will defer until later.
[email protected]dd7daa82009-08-10 05:46:453119 search_frame->scopeStringMatches(request_id,
[email protected]7ea066a2009-04-06 20:21:593120 search_text,
3121 options,
initial.commit09911bf2008-07-26 23:55:293122 true); // reset the tickmarks
3123 }
3124
3125 // Iterate to the next frame. The frame will not necessarily scope, for
3126 // example if it is not visible.
[email protected]b4bb2502009-10-01 22:35:273127 search_frame = search_frame->traverseNext(true);
initial.commit09911bf2008-07-26 23:55:293128 } while (search_frame != main_frame);
3129 }
3130}
3131
[email protected]24a7f3c2010-03-25 08:26:493132void RenderView::OnStopFinding(const ViewMsg_StopFinding_Params& params) {
3133 WebView* view = webview();
3134 if (!view)
3135 return;
3136
3137 WebDocument doc = view->mainFrame()->document();
3138 if (doc.isPluginDocument()) {
[email protected]0fdbf8c2010-07-08 20:33:013139 GetWebPluginFromPluginDocument()->stopFind();
[email protected]24a7f3c2010-03-25 08:26:493140 return;
3141 }
3142
3143 bool clear_selection =
3144 params.action == ViewMsg_StopFinding_Params::kClearSelection;
3145 if (clear_selection)
3146 view->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect"));
3147
3148 WebFrame* frame = view->mainFrame();
3149 while (frame) {
3150 frame->stopFinding(clear_selection);
3151 frame = frame->traverseNext(false);
3152 }
3153
3154 if (params.action == ViewMsg_StopFinding_Params::kActivateSelection) {
3155 WebFrame* focused_frame = view->focusedFrame();
3156 if (focused_frame) {
3157 WebDocument doc = focused_frame->document();
3158 if (!doc.isNull()) {
3159 WebNode node = doc.focusedNode();
3160 if (!node.isNull())
3161 node.simulateClick();
3162 }
3163 }
3164 }
3165}
3166
3167void RenderView::OnFindReplyAck() {
3168 // Check if there is any queued up request waiting to be sent.
3169 if (queued_find_reply_message_.get()) {
3170 // Send the search result over to the browser process.
[email protected]d22d8732010-05-04 19:24:423171 Send(queued_find_reply_message_.release());
[email protected]24a7f3c2010-03-25 08:26:493172 }
3173}
3174
[email protected]0bd753682010-12-16 18:15:523175WebPlugin* RenderView::CreatePepperPlugin(
3176 WebFrame* frame,
3177 const WebPluginParams& params,
3178 const FilePath& path,
3179 webkit::ppapi::PluginModule* pepper_module) {
3180 return new webkit::ppapi::WebPluginImpl(
[email protected]b75b8292010-10-01 07:28:253181 pepper_module, params, pepper_delegate_.AsWeakPtr());
[email protected]aad51d1c2010-08-05 08:38:093182}
[email protected]00152e92010-07-19 11:47:403183
[email protected]191eb3f72010-12-21 06:27:503184WebPlugin* RenderView::CreateNPAPIPlugin(
3185 WebFrame* frame,
3186 const WebPluginParams& params,
3187 const FilePath& path,
3188 const std::string& mime_type) {
3189 return new webkit::npapi::WebPluginImpl(
[email protected]20a793e2010-10-12 06:50:083190 frame, params, path, mime_type, AsWeakPtr());
[email protected]00152e92010-07-19 11:47:403191}
3192
[email protected]40bd6582009-12-04 23:49:513193void RenderView::OnZoom(PageZoom::Function function) {
3194 if (!webview()) // Not sure if this can happen, but no harm in being safe.
3195 return;
3196
[email protected]258d31122010-05-09 10:59:413197 webview()->hidePopups();
[email protected]b03794d2010-03-26 19:57:523198
[email protected]b75b8292010-10-01 07:28:253199 double old_zoom_level = webview()->zoomLevel();
3200 double zoom_level;
3201 if (function == PageZoom::RESET) {
3202 zoom_level = 0;
3203 } else if (static_cast<int>(old_zoom_level) == old_zoom_level) {
3204 // Previous zoom level is a whole number, so just increment/decrement.
3205 zoom_level = old_zoom_level + function;
3206 } else {
3207 // Either the user hit the zoom factor limit and thus the zoom level is now
3208 // not a whole number, or a plugin changed it to a custom value. We want
3209 // to go to the next whole number so that the user can always get back to
3210 // 100% with the keyboard/menu.
3211 if ((old_zoom_level > 1 && function > 0) ||
3212 (old_zoom_level < 1 && function < 0)) {
[email protected]3209e7112010-10-01 23:53:453213 zoom_level = static_cast<int>(old_zoom_level + function);
[email protected]b75b8292010-10-01 07:28:253214 } else {
3215 // We're going towards 100%, so first go to the next whole number.
3216 zoom_level = static_cast<int>(old_zoom_level);
3217 }
3218 }
[email protected]40bd6582009-12-04 23:49:513219
[email protected]b75b8292010-10-01 07:28:253220 webview()->setZoomLevel(false, zoom_level);
3221 zoomLevelChanged();
[email protected]40bd6582009-12-04 23:49:513222}
3223
[email protected]d0b8d092010-10-25 04:05:173224void RenderView::OnSetZoomLevel(double zoom_level) {
3225 // Don't set zoom level for full-page plugin since they don't use the same
3226 // zoom settings.
3227 if (webview()->mainFrame()->document().isPluginDocument())
3228 return;
3229
3230 webview()->hidePopups();
3231 webview()->setZoomLevel(false, zoom_level);
3232 zoomLevelChanged();
3233}
3234
[email protected]9d797f32010-04-23 07:17:543235void RenderView::OnSetZoomLevelForLoadingURL(const GURL& url,
[email protected]b75b8292010-10-01 07:28:253236 double zoom_level) {
[email protected]9d797f32010-04-23 07:17:543237 host_zoom_levels_[url] = zoom_level;
initial.commit09911bf2008-07-26 23:55:293238}
3239
[email protected]41fc0322009-09-04 22:23:403240void RenderView::OnSetPageEncoding(const std::string& encoding_name) {
[email protected]26aa0482009-09-30 16:55:273241 webview()->setPageEncoding(WebString::fromUTF8(encoding_name));
initial.commit09911bf2008-07-26 23:55:293242}
3243
[email protected]a697f4c2009-09-14 22:30:183244void RenderView::OnResetPageEncodingToDefault() {
[email protected]26aa0482009-09-30 16:55:273245 WebString no_encoding;
3246 webview()->setPageEncoding(no_encoding);
[email protected]a697f4c2009-09-14 22:30:183247}
3248
[email protected]dd7daa82009-08-10 05:46:453249WebFrame* RenderView::GetChildFrame(const std::wstring& xpath) const {
3250 if (xpath.empty())
[email protected]26aa0482009-09-30 16:55:273251 return webview()->mainFrame();
[email protected]dd7daa82009-08-10 05:46:453252
3253 // xpath string can represent a frame deep down the tree (across multiple
3254 // frame DOMs).
3255 // Example, /html/body/table/tbody/tr/td/iframe\n/frameset/frame[0]
3256 // should break into 2 xpaths
3257 // /html/body/table/tbody/tr/td/iframe & /frameset/frame[0]
3258
[email protected]26aa0482009-09-30 16:55:273259 WebFrame* frame = webview()->mainFrame();
[email protected]dd7daa82009-08-10 05:46:453260
3261 std::wstring xpath_remaining = xpath;
3262 while (!xpath_remaining.empty()) {
3263 std::wstring::size_type delim_pos = xpath_remaining.find_first_of(L'\n');
3264 std::wstring xpath_child;
3265 if (delim_pos != std::wstring::npos) {
3266 xpath_child = xpath_remaining.substr(0, delim_pos);
3267 xpath_remaining.erase(0, delim_pos + 1);
3268 } else {
3269 xpath_remaining.swap(xpath_child);
3270 }
3271 frame = frame->findChildByExpression(WideToUTF16Hack(xpath_child));
initial.commit09911bf2008-07-26 23:55:293272 }
3273
[email protected]dd7daa82009-08-10 05:46:453274 return frame;
initial.commit09911bf2008-07-26 23:55:293275}
3276
[email protected]13a1e4c3c2011-02-03 21:07:093277WebNode RenderView::GetFocusedNode() const {
3278 if (!webview())
3279 return WebNode();
3280 WebFrame* focused_frame = webview()->focusedFrame();
3281 if (focused_frame) {
3282 WebDocument doc = focused_frame->document();
3283 if (!doc.isNull())
3284 return doc.focusedNode();
3285 }
3286
3287 return WebNode();
3288}
3289
[email protected]38b592902011-04-16 02:08:423290bool RenderView::IsEditableNode(const WebNode& node) {
3291 bool is_editable_node = false;
3292 if (!node.isNull()) {
3293 if (node.isContentEditable()) {
3294 is_editable_node = true;
3295 } else if (node.isElementNode()) {
3296 is_editable_node =
3297 node.toConst<WebElement>().isTextFormControlElement();
3298 }
3299 }
3300 return is_editable_node;
3301}
3302
[email protected]882b7b22010-10-05 03:34:533303void RenderView::EvaluateScript(const string16& frame_xpath,
3304 const string16& script,
3305 int id,
3306 bool notify_result) {
3307 v8::Handle<v8::Value> result;
3308 WebFrame* web_frame = GetChildFrame(UTF16ToWideHack(frame_xpath));
3309 if (web_frame)
3310 result = web_frame->executeScriptAndReturnValue(WebScriptSource(script));
3311 if (notify_result) {
[email protected]81f9fe0b2010-12-07 00:35:293312 ListValue list;
3313 if (web_frame) {
3314 v8::HandleScope handle_scope;
3315 v8::Local<v8::Context> context = web_frame->mainWorldScriptContext();
3316 v8::Context::Scope context_scope(context);
[email protected]b1cf3372011-04-20 21:28:103317 V8ValueConverter converter;
3318 converter.set_allow_date(true);
3319 converter.set_allow_regexp(true);
3320 list.Set(0, converter.FromV8Value(result, context));
[email protected]81f9fe0b2010-12-07 00:35:293321 } else {
3322 list.Set(0, Value::CreateNullValue());
3323 }
3324 Send(new ViewHostMsg_ScriptEvalResponse(routing_id_, id, list));
[email protected]882b7b22010-10-05 03:34:533325 }
initial.commit09911bf2008-07-26 23:55:293326}
3327
[email protected]1810e132009-03-24 23:35:483328void RenderView::InsertCSS(const std::wstring& frame_xpath,
[email protected]ffaef0c2009-09-15 17:08:083329 const std::string& css,
3330 const std::string& id) {
[email protected]1810e132009-03-24 23:35:483331 WebFrame* web_frame = GetChildFrame(frame_xpath);
3332 if (!web_frame)
3333 return;
3334
[email protected]ffaef0c2009-09-15 17:08:083335 web_frame->insertStyleText(WebString::fromUTF8(css), WebString::fromUTF8(id));
[email protected]1810e132009-03-24 23:35:483336}
3337
[email protected]882b7b22010-10-05 03:34:533338void RenderView::OnScriptEvalRequest(const string16& frame_xpath,
3339 const string16& jscript,
3340 int id,
3341 bool notify_result) {
3342 EvaluateScript(frame_xpath, jscript, id, notify_result);
initial.commit09911bf2008-07-26 23:55:293343}
3344
[email protected]1810e132009-03-24 23:35:483345void RenderView::OnCSSInsertRequest(const std::wstring& frame_xpath,
[email protected]ffaef0c2009-09-15 17:08:083346 const std::string& css,
3347 const std::string& id) {
3348 InsertCSS(frame_xpath, css, id);
[email protected]ae461542009-06-19 19:03:413349
3350 // Notify RenderViewHost that css has been inserted into the frame.
3351 Send(new ViewHostMsg_OnCSSInserted(routing_id_));
[email protected]1810e132009-03-24 23:35:483352}
3353
[email protected]81e63782009-02-27 19:35:093354void RenderView::OnAllowBindings(int enabled_bindings_flags) {
3355 enabled_bindings_ |= enabled_bindings_flags;
initial.commit09911bf2008-07-26 23:55:293356}
3357
[email protected]d0980792011-02-13 19:41:403358void RenderView::OnSetWebUIProperty(const std::string& name,
initial.commit09911bf2008-07-26 23:55:293359 const std::string& value) {
[email protected]c09163a2011-02-15 00:05:553360 DCHECK(BindingsPolicy::is_web_ui_enabled(enabled_bindings_));
[email protected]c50008512011-02-03 01:17:273361 GetWebUIBindings()->SetProperty(name, value);
initial.commit09911bf2008-07-26 23:55:293362}
3363
3364void RenderView::OnReservePageIDRange(int size_of_range) {
3365 next_page_id_ += size_of_range + 1;
3366}
3367
[email protected]59f4f2fa2011-03-23 01:00:553368void RenderView::OnDragTargetDragEnter(const WebDropData& drop_data,
3369 const gfx::Point& client_point,
3370 const gfx::Point& screen_point,
3371 WebDragOperationsMask ops) {
3372 WebDragOperation operation = webview()->dragTargetDragEnter(
3373 drop_data.ToDragData(),
[email protected]59f4f2fa2011-03-23 01:00:553374 client_point,
3375 screen_point,
3376 ops);
3377
3378 Send(new DragHostMsg_UpdateDragCursor(routing_id_, operation));
3379}
3380
3381void RenderView::OnDragTargetDragOver(const gfx::Point& client_point,
3382 const gfx::Point& screen_point,
3383 WebDragOperationsMask ops) {
3384 WebDragOperation operation = webview()->dragTargetDragOver(
3385 client_point,
3386 screen_point,
3387 ops);
3388
3389 Send(new DragHostMsg_UpdateDragCursor(routing_id_, operation));
3390}
3391
3392void RenderView::OnDragTargetDragLeave() {
3393 webview()->dragTargetDragLeave();
3394}
3395
3396void RenderView::OnDragTargetDrop(const gfx::Point& client_point,
3397 const gfx::Point& screen_point) {
3398 webview()->dragTargetDrop(client_point, screen_point);
3399}
3400
[email protected]e80c73b2009-04-07 23:24:583401void RenderView::OnDragSourceEndedOrMoved(const gfx::Point& client_point,
3402 const gfx::Point& screen_point,
[email protected]1d9f4132009-09-08 17:29:253403 bool ended,
3404 WebDragOperation op) {
[email protected]5f9ae6c2009-07-08 02:38:033405 if (ended) {
[email protected]26aa0482009-09-30 16:55:273406 webview()->dragSourceEndedAt(client_point, screen_point, op);
[email protected]daec5d62010-06-04 09:14:203407 } else {
3408 webview()->dragSourceMovedTo(client_point, screen_point, op);
[email protected]5f9ae6c2009-07-08 02:38:033409 }
initial.commit09911bf2008-07-26 23:55:293410}
3411
3412void RenderView::OnDragSourceSystemDragEnded() {
[email protected]26aa0482009-09-30 16:55:273413 webview()->dragSourceSystemDragEnded();
initial.commit09911bf2008-07-26 23:55:293414}
3415
initial.commit09911bf2008-07-26 23:55:293416void RenderView::OnUpdateWebPreferences(const WebPreferences& prefs) {
[email protected]2fab253a2009-08-17 23:00:593417 webkit_preferences_ = prefs;
3418 webkit_preferences_.Apply(webview());
initial.commit09911bf2008-07-26 23:55:293419}
3420
3421void RenderView::OnSetAltErrorPageURL(const GURL& url) {
3422 alternate_error_page_url_ = url;
3423}
3424
[email protected]b29aa74b2011-01-31 21:41:083425void RenderView::OnCustomContextMenuAction(
3426 const webkit_glue::CustomContextMenuContext& custom_context,
3427 unsigned action) {
3428 if (custom_context.is_pepper_menu)
3429 pepper_delegate_.OnCustomContextMenuAction(custom_context, action);
3430 else
3431 webview()->performCustomContextMenuAction(action);
[email protected]a0c7153e2009-12-09 14:36:333432}
3433
initial.commit09911bf2008-07-26 23:55:293434void RenderView::OnInstallMissingPlugin() {
3435 // This could happen when the first default plugin is deleted.
[email protected]f103ab72009-09-02 17:10:593436 if (first_default_plugin_)
3437 first_default_plugin_->InstallMissingPlugin();
initial.commit09911bf2008-07-26 23:55:293438}
3439
[email protected]600ea402011-04-12 00:01:513440void RenderView::OnEnumerateDirectoryResponse(
3441 int id,
3442 const std::vector<FilePath>& paths) {
3443 if (!enumeration_completions_[id])
3444 return;
3445
3446 WebVector<WebString> ws_file_names(paths.size());
3447 for (size_t i = 0; i < paths.size(); ++i)
3448 ws_file_names[i] = webkit_glue::FilePathToWebString(paths[i]);
3449
3450 enumeration_completions_[id]->didChooseFile(ws_file_names);
3451 enumeration_completions_.erase(id);
3452}
3453
[email protected]cdaf8d02010-03-30 19:52:473454void RenderView::OnFileChooserResponse(const std::vector<FilePath>& paths) {
[email protected]8029f5672009-03-20 22:33:363455 // This could happen if we navigated to a different page before the user
3456 // closed the chooser.
[email protected]cdaf8d02010-03-30 19:52:473457 if (file_chooser_completions_.empty())
[email protected]8029f5672009-03-20 22:33:363458 return;
3459
[email protected]cdaf8d02010-03-30 19:52:473460 WebVector<WebString> ws_file_names(paths.size());
3461 for (size_t i = 0; i < paths.size(); ++i)
3462 ws_file_names[i] = webkit_glue::FilePathToWebString(paths[i]);
[email protected]a1128322009-10-06 18:38:463463
[email protected]cdaf8d02010-03-30 19:52:473464 if (file_chooser_completions_.front()->completion)
3465 file_chooser_completions_.front()->completion->didChooseFile(ws_file_names);
3466 file_chooser_completions_.pop_front();
3467
3468 // If there are more pending file chooser requests, schedule one now.
3469 if (!file_chooser_completions_.empty()) {
3470 Send(new ViewHostMsg_RunFileChooser(routing_id_,
3471 file_chooser_completions_.front()->params));
3472 }
initial.commit09911bf2008-07-26 23:55:293473}
3474
[email protected]770dd8b2010-05-24 18:11:393475void RenderView::OnEnablePreferredSizeChangedMode(int flags) {
3476 DCHECK(flags != kPreferredSizeNothing);
[email protected]9fb325e2010-05-06 18:23:243477 if (send_preferred_size_changes_)
3478 return;
[email protected]9fb325e2010-05-06 18:23:243479 send_preferred_size_changes_ = true;
[email protected]770dd8b2010-05-24 18:11:393480
3481 // WebKit doesn't send a notification of the effective height of the page
3482 // changes, so poll for it.
3483 // TODO: Add a notification for this to WebKit, remove polling. After that's
3484 // done, rename kPreferredSizeHeightThisIsSlow to kPreferredSizeHeight.
3485 // http://crbug.com/44850
3486 if (flags & kPreferredSizeHeightThisIsSlow) {
3487 preferred_size_change_timer_.Start(TimeDelta::FromMilliseconds(10), this,
3488 &RenderView::CheckPreferredSize);
3489 }
[email protected]0666aef2009-05-13 19:48:083490}
3491
[email protected]cda45c02010-02-25 19:28:103492void RenderView::OnDisableScrollbarsForSmallWindows(
3493 const gfx::Size& disable_scrollbar_size_limit) {
3494 disable_scrollbars_size_limit_ = disable_scrollbar_size_limit;
3495}
3496
[email protected]80d96fa2009-06-10 22:34:513497void RenderView::OnSetRendererPrefs(const RendererPreferences& renderer_prefs) {
3498 renderer_preferences_ = renderer_prefs;
[email protected]6e282c92009-07-24 01:19:373499 UpdateFontRenderingFromRendererPrefs();
[email protected]0dd6f9b52010-10-14 16:39:133500#if defined(TOOLKIT_USES_GTK)
[email protected]1c83eb42009-09-11 21:08:413501 WebColorName name = WebKit::WebColorWebkitFocusRingColor;
3502 WebKit::setNamedColors(&name, &renderer_prefs.focus_ring_color, 1);
[email protected]39cd64ed2010-02-05 02:18:463503 WebKit::setCaretBlinkInterval(renderer_prefs.caret_blink_interval);
[email protected]42e5c862011-04-07 22:13:513504 gfx::NativeTheme::instance()->SetScrollbarColors(
[email protected]8d1b864d12010-10-10 00:04:343505 renderer_prefs.thumb_inactive_color,
3506 renderer_prefs.thumb_active_color,
3507 renderer_prefs.track_color);
[email protected]93623c5d2009-12-10 21:40:323508
[email protected]644d77e2010-01-27 01:03:103509 if (webview()) {
[email protected]93623c5d2009-12-10 21:40:323510 webview()->setScrollbarColors(
3511 renderer_prefs.thumb_inactive_color,
3512 renderer_prefs.thumb_active_color,
3513 renderer_prefs.track_color);
[email protected]644d77e2010-01-27 01:03:103514 webview()->setSelectionColors(
3515 renderer_prefs.active_selection_bg_color,
3516 renderer_prefs.active_selection_fg_color,
3517 renderer_prefs.inactive_selection_bg_color,
3518 renderer_prefs.inactive_selection_fg_color);
[email protected]f98d7e3c2010-09-13 22:30:463519 webview()->themeChanged();
[email protected]644d77e2010-01-27 01:03:103520 }
[email protected]7a74e102009-09-03 00:16:563521#endif
[email protected]80d96fa2009-06-10 22:34:513522}
3523
[email protected]952cb702009-10-07 05:50:283524void RenderView::OnMediaPlayerActionAt(const gfx::Point& location,
3525 const WebMediaPlayerAction& action) {
3526 if (webview())
3527 webview()->performMediaPlayerAction(action, location);
[email protected]581b87eb2009-07-23 23:06:563528}
3529
[email protected]dea2d372010-09-25 06:41:143530void RenderView::OnEnableAccessibility() {
3531 if (WebAccessibilityCache::accessibilityEnabled())
3532 return;
[email protected]9f4db512010-05-10 20:21:413533
[email protected]dea2d372010-09-25 06:41:143534 WebAccessibilityCache::enableAccessibility();
3535
3536 if (webview()) {
3537 // It's possible that the webview has already loaded a webpage without
3538 // accessibility being enabled. Initialize the browser's cached
3539 // accessibility tree by sending it a 'load complete' notification.
3540 postAccessibilityNotification(
3541 webview()->accessibilityObject(),
3542 WebKit::WebAccessibilityNotificationLoadComplete);
3543 }
[email protected]266eb6f2008-09-30 23:56:503544}
3545
[email protected]aef92842010-05-21 16:54:363546void RenderView::OnSetAccessibilityFocus(int acc_obj_id) {
3547 if (!accessibility_.get())
3548 return;
[email protected]02ea2f312010-09-27 17:03:363549
3550 WebAccessibilityObject obj = accessibility_->getObjectById(acc_obj_id);
3551 WebAccessibilityObject root = webview()->accessibilityObject();
3552 if (!obj.isValid() || !root.isValid())
3553 return;
3554
3555 // By convention, calling SetFocus on the root of the tree should clear the
3556 // current focus. Otherwise set the focus to the new node.
3557 if (accessibility_->addOrGetId(obj) == accessibility_->addOrGetId(root))
3558 webview()->clearFocusedNode();
3559 else
3560 obj.setFocused(true);
[email protected]aef92842010-05-21 16:54:363561}
3562
3563void RenderView::OnAccessibilityDoDefaultAction(int acc_obj_id) {
3564 if (!accessibility_.get())
3565 return;
[email protected]02ea2f312010-09-27 17:03:363566
3567 WebAccessibilityObject obj = accessibility_->getObjectById(acc_obj_id);
3568 if (!obj.isValid())
3569 return;
3570
3571 obj.performDefaultAction();
[email protected]aef92842010-05-21 16:54:363572}
3573
[email protected]9892b472010-09-16 00:23:423574void RenderView::OnAccessibilityNotificationsAck() {
[email protected]54ec7f82010-10-21 22:32:513575 DCHECK(accessibility_ack_pending_);
3576 accessibility_ack_pending_ = false;
3577 SendPendingAccessibilityNotifications();
[email protected]520cb7d72010-08-31 11:54:313578}
3579
[email protected]9b18a84f2010-06-10 15:54:043580void RenderView::OnShouldClose() {
[email protected]26aa0482009-09-30 16:55:273581 bool should_close = webview()->dispatchBeforeUnloadEvent();
[email protected]04b4a6c2008-08-02 00:44:473582 Send(new ViewHostMsg_ShouldClose_ACK(routing_id_, should_close));
initial.commit09911bf2008-07-26 23:55:293583}
3584
[email protected]eb6b87a2009-07-24 15:57:393585void RenderView::OnClosePage(const ViewMsg_ClosePage_Params& params) {
initial.commit09911bf2008-07-26 23:55:293586 // TODO(creis): We'd rather use webview()->Close() here, but that currently
3587 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs
3588 // in the onunload handler from appearing. For now, we're bypassing that and
3589 // calling the FrameLoader's CloseURL method directly. This should be
3590 // revisited to avoid having two ways to close a page. Having a single way
3591 // to close that can run onunload is also useful for fixing
3592 // http://b/issue?id=753080.
[email protected]26aa0482009-09-30 16:55:273593 webview()->dispatchUnloadEvent();
initial.commit09911bf2008-07-26 23:55:293594
[email protected]eb6b87a2009-07-24 15:57:393595 // Just echo back the params in the ACK.
3596 Send(new ViewHostMsg_ClosePage_ACK(routing_id_, params));
initial.commit09911bf2008-07-26 23:55:293597}
3598
3599void RenderView::OnThemeChanged() {
[email protected]6c8afae52009-01-22 02:24:573600#if defined(OS_WIN)
[email protected]c6d942212011-03-30 19:02:163601 gfx::NativeThemeWin::instance()->CloseHandles();
[email protected]f98d7e3c2010-09-13 22:30:463602 if (webview())
3603 webview()->themeChanged();
[email protected]6c8afae52009-01-22 02:24:573604#else // defined(OS_WIN)
3605 // TODO(port): we don't support theming on non-Windows platforms yet
3606 NOTIMPLEMENTED();
3607#endif
initial.commit09911bf2008-07-26 23:55:293608}
3609
[email protected]0aa55312008-10-17 21:53:083610void RenderView::OnDisassociateFromPopupCount() {
3611 if (decrement_shared_popup_at_destruction_)
3612 shared_popup_counter_->data--;
3613 shared_popup_counter_ = new SharedRenderViewCounter(0);
3614 decrement_shared_popup_at_destruction_ = false;
3615}
3616
[email protected]15d79e12009-08-02 19:23:453617bool RenderView::MaybeLoadAlternateErrorPage(WebFrame* frame,
3618 const WebURLError& error,
3619 bool replace) {
3620 // We only show alternate error pages in the main frame. They are
3621 // intended to assist the user when navigating, so there is not much
3622 // value in showing them for failed subframes. Ideally, we would be
3623 // able to use the TYPED transition type for this, but that flag is
3624 // not preserved across page reloads.
[email protected]dd7daa82009-08-10 05:46:453625 if (frame->parent())
[email protected]15d79e12009-08-02 19:23:453626 return false;
3627
3628 // Use the alternate error page service if this is a DNS failure or
[email protected]c53976d52009-08-07 18:58:373629 // connection failure.
[email protected]15d79e12009-08-02 19:23:453630 int ec = error.reason;
3631 if (ec != net::ERR_NAME_NOT_RESOLVED &&
3632 ec != net::ERR_CONNECTION_FAILED &&
3633 ec != net::ERR_CONNECTION_REFUSED &&
3634 ec != net::ERR_ADDRESS_UNREACHABLE &&
[email protected]c53976d52009-08-07 18:58:373635 ec != net::ERR_CONNECTION_TIMED_OUT)
[email protected]15d79e12009-08-02 19:23:453636 return false;
3637
3638 const GURL& error_page_url = GetAlternateErrorPageURL(error.unreachableURL,
[email protected]7ccddb8c2009-08-04 17:36:553639 ec == net::ERR_NAME_NOT_RESOLVED ? DNS_ERROR : CONNECTION_ERROR);
[email protected]15d79e12009-08-02 19:23:453640 if (!error_page_url.is_valid())
3641 return false;
3642
3643 // Load an empty page first so there is an immediate response to the error,
3644 // and then kick off a request for the alternate error page.
[email protected]dd7daa82009-08-10 05:46:453645 frame->loadHTMLString(std::string(),
[email protected]144143c2010-10-28 08:17:363646 GURL(chrome::kUnreachableWebDataURL),
[email protected]15d79e12009-08-02 19:23:453647 error.unreachableURL,
3648 replace);
3649
3650 // Now, create a fetcher for the error page and associate it with the data
3651 // source we just created via the LoadHTMLString call. That way if another
3652 // navigation occurs, the fetcher will get destroyed.
3653 NavigationState* navigation_state =
[email protected]dd7daa82009-08-10 05:46:453654 NavigationState::FromDataSource(frame->provisionalDataSource());
[email protected]15d79e12009-08-02 19:23:453655 navigation_state->set_alt_error_page_fetcher(
3656 new AltErrorPageResourceFetcher(
3657 error_page_url, frame, error,
3658 NewCallback(this, &RenderView::AltErrorPageFinished)));
3659 return true;
3660}
3661
[email protected]15d79e12009-08-02 19:23:453662void RenderView::AltErrorPageFinished(WebFrame* frame,
3663 const WebURLError& original_error,
3664 const std::string& html) {
3665 // Here, we replace the blank page we loaded previously.
[email protected]06333afe2011-02-24 14:55:093666 // If we failed to download the alternate error page, LoadNavigationErrorPage
[email protected]7ccddb8c2009-08-04 17:36:553667 // will simply display a default error page.
[email protected]06333afe2011-02-24 14:55:093668 LoadNavigationErrorPage(frame, WebURLRequest(), original_error, html, true);
[email protected]15d79e12009-08-02 19:23:453669}
3670
[email protected]30f75e62009-02-25 22:01:003671void RenderView::OnMoveOrResizeStarted() {
3672 if (webview())
[email protected]a72a1fa2010-05-03 22:18:473673 webview()->hidePopups();
[email protected]30f75e62009-02-25 22:01:003674}
3675
[email protected]30f75e62009-02-25 22:01:003676void RenderView::OnResize(const gfx::Size& new_size,
3677 const gfx::Rect& resizer_rect) {
[email protected]cda45c02010-02-25 19:28:103678 if (webview()) {
[email protected]a72a1fa2010-05-03 22:18:473679 webview()->hidePopups();
[email protected]cda45c02010-02-25 19:28:103680 if (send_preferred_size_changes_) {
[email protected]7339cd22010-10-27 00:11:203681 webview()->mainFrame()->setCanHaveScrollbars(
3682 should_display_scrollbars(new_size.width(), new_size.height()));
[email protected]cda45c02010-02-25 19:28:103683 }
3684 }
3685
[email protected]30f75e62009-02-25 22:01:003686 RenderWidget::OnResize(new_size, resizer_rect);
3687}
[email protected]0aa477bd2009-03-23 22:21:433688
[email protected]00c39612010-03-06 02:53:283689void RenderView::DidInitiatePaint() {
[email protected]53900d52010-06-16 04:25:013690 // Notify the pepper plugins that we started painting.
3691 pepper_delegate_.ViewInitiatedPaint();
[email protected]00c39612010-03-06 02:53:283692}
3693
3694void RenderView::DidFlushPaint() {
3695 // Notify any pepper plugins that we painted. This will call into the plugin,
3696 // and we it may ask to close itself as a result. This will, in turn, modify
3697 // our set, possibly invalidating the iterator. So we iterate on a copy that
3698 // won't change out from under us.
[email protected]53900d52010-06-16 04:25:013699 pepper_delegate_.ViewFlushedPaint();
3700
[email protected]00c39612010-03-06 02:53:283701 WebFrame* main_frame = webview()->mainFrame();
3702
3703 // If we have a provisional frame we are between the start and commit stages
3704 // of loading and we don't want to save stats.
3705 if (!main_frame->provisionalDataSource()) {
3706 WebDataSource* ds = main_frame->dataSource();
3707 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
3708 DCHECK(navigation_state);
3709
[email protected]05c8e502010-08-15 15:13:523710 // TODO(jar): The following code should all be inside a method, probably in
3711 // NavigatorState.
[email protected]00c39612010-03-06 02:53:283712 Time now = Time::Now();
3713 if (navigation_state->first_paint_time().is_null()) {
3714 navigation_state->set_first_paint_time(now);
3715 }
3716 if (navigation_state->first_paint_after_load_time().is_null() &&
3717 !navigation_state->finish_load_time().is_null()) {
3718 navigation_state->set_first_paint_after_load_time(now);
3719 }
3720 }
3721}
3722
[email protected]719b36f2010-12-22 20:36:463723webkit::ppapi::PluginInstance* RenderView::GetBitmapForOptimizedPluginPaint(
[email protected]ca4847f2010-09-24 05:39:153724 const gfx::Rect& paint_bounds,
3725 TransportDIB** dib,
3726 gfx::Rect* location,
3727 gfx::Rect* clip) {
3728 return pepper_delegate_.GetBitmapForOptimizedPluginPaint(
3729 paint_bounds, dib, location, clip);
3730}
3731
[email protected]bcaf2272011-02-15 15:29:433732gfx::Point RenderView::GetScrollOffset() {
[email protected]d54169e92011-01-21 09:19:523733 WebKit::WebSize scroll_offset = webview()->mainFrame()->scrollOffset();
[email protected]bcaf2272011-02-15 15:29:433734 return gfx::Point(scroll_offset.width, scroll_offset.height);
[email protected]d54169e92011-01-21 09:19:523735}
3736
[email protected]05d478752009-04-08 23:38:163737void RenderView::OnClearFocusedNode() {
3738 if (webview())
[email protected]26aa0482009-09-30 16:55:273739 webview()->clearFocusedNode();
[email protected]05d478752009-04-08 23:38:163740}
3741
[email protected]699ab0d2009-04-23 23:19:143742void RenderView::OnSetBackground(const SkBitmap& background) {
3743 if (webview())
[email protected]b4bb2502009-10-01 22:35:273744 webview()->setIsTransparent(!background.empty());
[email protected]699ab0d2009-04-23 23:19:143745
3746 SetBackground(background);
3747}
3748
[email protected]8c66c5a2009-07-22 17:26:343749void RenderView::OnSetActive(bool active) {
3750 if (webview())
[email protected]b4bb2502009-10-01 22:35:273751 webview()->setIsActive(active);
[email protected]d8fd6fa2010-02-01 15:54:263752
3753#if defined(OS_MACOSX)
3754 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
3755 for (plugin_it = plugin_delegates_.begin();
3756 plugin_it != plugin_delegates_.end(); ++plugin_it) {
3757 (*plugin_it)->SetWindowFocus(active);
3758 }
3759#endif
[email protected]8c66c5a2009-07-22 17:26:343760}
3761
[email protected]6ce7abc52010-02-02 18:40:143762#if defined(OS_MACOSX)
3763void RenderView::OnSetWindowVisibility(bool visible) {
3764 // Inform plugins that their container has changed visibility.
3765 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
3766 for (plugin_it = plugin_delegates_.begin();
3767 plugin_it != plugin_delegates_.end(); ++plugin_it) {
3768 (*plugin_it)->SetContainerVisibility(visible);
3769 }
3770}
[email protected]1e6e3c992010-02-08 15:52:133771
[email protected]4d51d5bf2010-07-26 18:48:263772void RenderView::OnWindowFrameChanged(const gfx::Rect& window_frame,
3773 const gfx::Rect& view_frame) {
[email protected]1e6e3c992010-02-08 15:52:133774 // Inform plugins that their window's frame has changed.
3775 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
3776 for (plugin_it = plugin_delegates_.begin();
3777 plugin_it != plugin_delegates_.end(); ++plugin_it) {
3778 (*plugin_it)->WindowFrameChanged(window_frame, view_frame);
3779 }
3780}
[email protected]935d63d2010-10-15 23:31:553781
[email protected]b7f75862011-01-21 21:15:133782void RenderView::OnPluginImeCompositionCompleted(const string16& text,
[email protected]935d63d2010-10-15 23:31:553783 int plugin_id) {
[email protected]b7f75862011-01-21 21:15:133784 // WebPluginDelegateProxy is responsible for figuring out if this event
[email protected]935d63d2010-10-15 23:31:553785 // applies to it or not, so inform all the delegates.
3786 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
3787 for (plugin_it = plugin_delegates_.begin();
3788 plugin_it != plugin_delegates_.end(); ++plugin_it) {
[email protected]b7f75862011-01-21 21:15:133789 (*plugin_it)->ImeCompositionCompleted(text, plugin_id);
[email protected]935d63d2010-10-15 23:31:553790 }
3791}
[email protected]6ce7abc52010-02-02 18:40:143792#endif // OS_MACOSX
3793
[email protected]9892b472010-09-16 00:23:423794void RenderView::postAccessibilityNotification(
3795 const WebAccessibilityObject& obj,
3796 WebAccessibilityNotification notification) {
[email protected]dea2d372010-09-25 06:41:143797 if (!accessibility_.get() && webview()) {
3798 // Load complete should be our first notification sent.
3799 // TODO(ctguil): Investigate if a different notification is a WebCore bug.
3800 if (notification != WebKit::WebAccessibilityNotificationLoadComplete)
3801 return;
3802
3803 // Create and initialize our accessibility cache
3804 accessibility_.reset(WebAccessibilityCache::create());
3805 accessibility_->initialize(webview());
3806 }
3807
[email protected]a3fa4f92010-09-30 22:19:333808 if (!accessibility_->isCached(obj)) {
3809 // The browser doesn't know about objects that are not in the cache. Send a
3810 // children change for the first accestor that actually is in the cache.
3811 WebAccessibilityObject parent = obj;
3812 while (parent.isValid() && !accessibility_->isCached(parent))
3813 parent = parent.parentObject();
3814
3815 DCHECK(parent.isValid() && accessibility_->isCached(parent));
3816 if (!parent.isValid())
3817 return;
3818 postAccessibilityNotification(
3819 parent, WebKit::WebAccessibilityNotificationChildrenChanged);
3820
3821 // The parent's children change takes care of the child's children change.
3822 if (notification == WebKit::WebAccessibilityNotificationChildrenChanged)
3823 return;
3824 }
3825
[email protected]dea2d372010-09-25 06:41:143826 // Add the accessibility object to our cache and ensure it's valid.
[email protected]54ec7f82010-10-21 22:32:513827 RendererAccessibilityNotification acc_notification;
3828 acc_notification.id = accessibility_->addOrGetId(obj);
[email protected]a527a022011-02-10 02:32:363829 acc_notification.type = notification;
[email protected]54ec7f82010-10-21 22:32:513830 if (acc_notification.id < 0)
[email protected]a3018be2010-03-09 04:28:483831 return;
3832
[email protected]fffaf972011-03-24 01:34:353833 ViewHostMsg_AccessibilityNotification_Type::Value temp;
[email protected]a527a022011-02-10 02:32:363834 if (!WebAccessibilityNotificationToViewHostMsg(notification, &temp))
[email protected]54ec7f82010-10-21 22:32:513835 return;
[email protected]54ec7f82010-10-21 22:32:513836
3837 // Discard duplicate accessibility notifications.
3838 for (uint32 i = 0; i < pending_accessibility_notifications_.size(); i++) {
3839 if (pending_accessibility_notifications_[i].id == acc_notification.id &&
3840 pending_accessibility_notifications_[i].type == acc_notification.type) {
[email protected]9892b472010-09-16 00:23:423841 return;
[email protected]54ec7f82010-10-21 22:32:513842 }
[email protected]9892b472010-09-16 00:23:423843 }
[email protected]54ec7f82010-10-21 22:32:513844 pending_accessibility_notifications_.push_back(acc_notification);
[email protected]a3018be2010-03-09 04:28:483845
[email protected]54ec7f82010-10-21 22:32:513846 if (!accessibility_ack_pending_ && accessibility_method_factory_.empty()) {
3847 // When no accessibility notifications are in-flight post a task to send
3848 // the notifications to the browser. We use PostTask so that we can queue
3849 // up additional notifications.
3850 MessageLoop::current()->PostTask(
3851 FROM_HERE,
3852 accessibility_method_factory_.NewRunnableMethod(
3853 &RenderView::SendPendingAccessibilityNotifications));
[email protected]520cb7d72010-08-31 11:54:313854 }
[email protected]520cb7d72010-08-31 11:54:313855}
3856
[email protected]446705872009-09-10 07:22:483857void RenderView::OnSetEditCommandsForNextKeyEvent(
3858 const EditCommands& edit_commands) {
3859 edit_commands_ = edit_commands;
3860}
3861
[email protected]60c42a8c72009-10-09 04:08:593862void RenderView::Close() {
3863 // We need to grab a pointer to the doomed WebView before we destroy it.
3864 WebView* doomed = webview();
3865 RenderWidget::Close();
[email protected]625332e02010-12-14 07:48:493866 g_view_map.Get().erase(doomed);
[email protected]60c42a8c72009-10-09 04:08:593867}
3868
[email protected]446705872009-09-10 07:22:483869void RenderView::DidHandleKeyEvent() {
3870 edit_commands_.clear();
3871}
3872
[email protected]6a8ddba52010-09-05 04:38:063873void RenderView::DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {
[email protected]676126f72011-01-15 00:03:513874 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidHandleMouseEvent(event));
[email protected]6a8ddba52010-09-05 04:38:063875}
3876
[email protected]941e4552010-02-01 21:23:433877void RenderView::OnWasHidden() {
3878 RenderWidget::OnWasHidden();
3879
[email protected]a6939ca42011-02-18 17:58:073880 if (webview()) {
3881 webview()->settings()->setMinimumTimerInterval(
3882 webkit_glue::kBackgroundTabTimerInterval);
3883 }
3884
3885#if defined(OS_MACOSX)
[email protected]941e4552010-02-01 21:23:433886 // Inform plugins that their container is no longer visible.
3887 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
3888 for (plugin_it = plugin_delegates_.begin();
3889 plugin_it != plugin_delegates_.end(); ++plugin_it) {
3890 (*plugin_it)->SetContainerVisibility(false);
3891 }
[email protected]a6939ca42011-02-18 17:58:073892#endif // OS_MACOSX
[email protected]941e4552010-02-01 21:23:433893}
3894
3895void RenderView::OnWasRestored(bool needs_repainting) {
3896 RenderWidget::OnWasRestored(needs_repainting);
3897
[email protected]a6939ca42011-02-18 17:58:073898 if (webview()) {
3899 webview()->settings()->setMinimumTimerInterval(
3900 webkit_glue::kForegroundTabTimerInterval);
3901 }
3902
3903#if defined(OS_MACOSX)
[email protected]941e4552010-02-01 21:23:433904 // Inform plugins that their container is now visible.
3905 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
3906 for (plugin_it = plugin_delegates_.begin();
3907 plugin_it != plugin_delegates_.end(); ++plugin_it) {
3908 (*plugin_it)->SetContainerVisibility(true);
3909 }
[email protected]784ea1ab2010-09-18 00:02:343910#endif // OS_MACOSX
[email protected]a6939ca42011-02-18 17:58:073911}
[email protected]1e6e3c992010-02-08 15:52:133912
3913void RenderView::OnSetFocus(bool enable) {
3914 RenderWidget::OnSetFocus(enable);
3915
[email protected]7d3c02c2010-05-05 23:10:313916 if (webview() && webview()->isActive()) {
[email protected]589621b2010-09-23 22:01:073917 // Notify all NPAPI plugins.
[email protected]1e6e3c992010-02-08 15:52:133918 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
3919 for (plugin_it = plugin_delegates_.begin();
3920 plugin_it != plugin_delegates_.end(); ++plugin_it) {
[email protected]784ea1ab2010-09-18 00:02:343921#if defined(OS_MACOSX)
[email protected]7d3c02c2010-05-05 23:10:313922 // RenderWidget's call to setFocus can cause the underlying webview's
3923 // activation state to change just like a call to setIsActive.
3924 if (enable)
3925 (*plugin_it)->SetWindowFocus(true);
[email protected]784ea1ab2010-09-18 00:02:343926#endif
[email protected]7d3c02c2010-05-05 23:10:313927 (*plugin_it)->SetContentAreaFocus(enable);
[email protected]1e6e3c992010-02-08 15:52:133928 }
[email protected]589621b2010-09-23 22:01:073929
3930 // Notify all Pepper plugins.
3931 pepper_delegate_.OnSetFocus(enable);
[email protected]1e6e3c992010-02-08 15:52:133932 }
3933}
[email protected]941e4552010-02-01 21:23:433934
[email protected]43f28f832010-02-03 02:28:483935#if defined(OS_MACOSX)
[email protected]b7f75862011-01-21 21:15:133936void RenderView::PluginFocusChanged(bool focused, int plugin_id) {
3937 IPC::Message* msg = new ViewHostMsg_PluginFocusChanged(routing_id(),
3938 focused, plugin_id);
3939 Send(msg);
3940}
3941
3942void RenderView::StartPluginIme() {
3943 IPC::Message* msg = new ViewHostMsg_StartPluginIme(routing_id());
[email protected]935d63d2010-10-15 23:31:553944 // This message can be sent during event-handling, and needs to be delivered
3945 // within that context.
3946 msg->set_unblock(true);
3947 Send(msg);
3948}
3949
[email protected]ea04a4e12010-04-15 00:58:033950gfx::PluginWindowHandle RenderView::AllocateFakePluginWindowHandle(
[email protected]77e74db2010-08-04 17:46:233951 bool opaque, bool root) {
[email protected]43f28f832010-02-03 02:28:483952 gfx::PluginWindowHandle window = NULL;
3953 Send(new ViewHostMsg_AllocateFakePluginWindowHandle(
[email protected]77e74db2010-08-04 17:46:233954 routing_id(), opaque, root, &window));
[email protected]c36a9b62010-10-14 00:41:113955 if (window) {
3956 fake_plugin_window_handles_.insert(window);
3957 }
[email protected]43f28f832010-02-03 02:28:483958 return window;
3959}
3960
3961void RenderView::DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window) {
[email protected]c36a9b62010-10-14 00:41:113962 if (window && fake_plugin_window_handles_.find(window) !=
3963 fake_plugin_window_handles_.end()) {
[email protected]43f28f832010-02-03 02:28:483964 Send(new ViewHostMsg_DestroyFakePluginWindowHandle(routing_id(), window));
[email protected]c36a9b62010-10-14 00:41:113965 fake_plugin_window_handles_.erase(window);
3966 }
[email protected]43f28f832010-02-03 02:28:483967}
3968
[email protected]44ce0b12010-03-12 16:45:333969void RenderView::AcceleratedSurfaceSetIOSurface(gfx::PluginWindowHandle window,
3970 int32 width,
3971 int32 height,
3972 uint64 io_surface_identifier) {
3973 Send(new ViewHostMsg_AcceleratedSurfaceSetIOSurface(
[email protected]43f28f832010-02-03 02:28:483974 routing_id(), window, width, height, io_surface_identifier));
3975}
3976
[email protected]44ce0b12010-03-12 16:45:333977void RenderView::AcceleratedSurfaceSetTransportDIB(
3978 gfx::PluginWindowHandle window,
3979 int32 width,
3980 int32 height,
3981 TransportDIB::Handle transport_dib) {
3982 Send(new ViewHostMsg_AcceleratedSurfaceSetTransportDIB(
[email protected]1aef98132010-02-23 18:00:073983 routing_id(), window, width, height, transport_dib));
3984}
3985
[email protected]44ce0b12010-03-12 16:45:333986TransportDIB::Handle RenderView::AcceleratedSurfaceAllocTransportDIB(
3987 size_t size) {
[email protected]1aef98132010-02-23 18:00:073988 TransportDIB::Handle dib_handle;
3989 // Assume this is a synchronous RPC.
[email protected]ada848b12010-04-08 22:35:383990 if (Send(new ViewHostMsg_AllocTransportDIB(size, true, &dib_handle)))
[email protected]1aef98132010-02-23 18:00:073991 return dib_handle;
3992 // Return an invalid handle if Send() fails.
3993 return TransportDIB::DefaultHandleValue();
3994}
3995
[email protected]44ce0b12010-03-12 16:45:333996void RenderView::AcceleratedSurfaceFreeTransportDIB(TransportDIB::Id dib_id) {
[email protected]1aef98132010-02-23 18:00:073997 Send(new ViewHostMsg_FreeTransportDIB(dib_id));
3998}
3999
[email protected]44ce0b12010-03-12 16:45:334000void RenderView::AcceleratedSurfaceBuffersSwapped(
[email protected]f35d6672010-10-28 21:39:144001 gfx::PluginWindowHandle window, uint64 surface_id) {
4002 Send(new ViewHostMsg_AcceleratedSurfaceBuffersSwapped(
4003 routing_id(), window, surface_id));
[email protected]43f28f832010-02-03 02:28:484004}
4005#endif
[email protected]58c321d2010-02-19 12:11:284006
[email protected]cdaf8d02010-03-30 19:52:474007bool RenderView::ScheduleFileChooser(
4008 const ViewHostMsg_RunFileChooser_Params& params,
4009 WebFileChooserCompletion* completion) {
4010 static const size_t kMaximumPendingFileChooseRequests = 4;
4011 if (file_chooser_completions_.size() > kMaximumPendingFileChooseRequests) {
4012 // This sanity check prevents too many file choose requests from getting
4013 // queued which could DoS the user. Getting these is most likely a
4014 // programming error (there are many ways to DoS the user so it's not
4015 // considered a "real" security check), either in JS requesting many file
4016 // choosers to pop up, or in a plugin.
4017 //
4018 // TODO(brettw) we might possibly want to require a user gesture to open
4019 // a file picker, which will address this issue in a better way.
4020 return false;
4021 }
4022
4023 file_chooser_completions_.push_back(linked_ptr<PendingFileChooser>(
4024 new PendingFileChooser(params, completion)));
4025 if (file_chooser_completions_.size() == 1) {
4026 // Actually show the browse dialog when this is the first request.
4027 Send(new ViewHostMsg_RunFileChooser(routing_id_, params));
4028 }
4029 return true;
4030}
4031
[email protected]0ff0ff32010-12-21 19:34:424032WebKit::WebGeolocationClient* RenderView::geolocationClient() {
[email protected]676126f72011-01-15 00:03:514033 if (!geolocation_dispatcher_)
4034 geolocation_dispatcher_ = new GeolocationDispatcher(this);
4035 return geolocation_dispatcher_;
[email protected]7e0c4702010-12-31 14:06:254036}
[email protected]61c9f032010-03-31 23:04:194037
[email protected]638694c2010-08-04 22:24:114038WebKit::WebSpeechInputController* RenderView::speechInputController(
4039 WebKit::WebSpeechInputListener* listener) {
[email protected]676126f72011-01-15 00:03:514040 if (!speech_input_dispatcher_)
4041 speech_input_dispatcher_ = new SpeechInputDispatcher(this, listener);
4042 return speech_input_dispatcher_;
[email protected]638694c2010-08-04 22:24:114043}
4044
[email protected]57ead352010-08-11 14:42:534045WebKit::WebDeviceOrientationClient* RenderView::deviceOrientationClient() {
[email protected]676126f72011-01-15 00:03:514046 if (!device_orientation_dispatcher_)
4047 device_orientation_dispatcher_ = new DeviceOrientationDispatcher(this);
4048 return device_orientation_dispatcher_;
[email protected]57ead352010-08-11 14:42:534049}
4050
[email protected]b75b8292010-10-01 07:28:254051void RenderView::zoomLimitsChanged(double minimum_level, double maximum_level) {
4052 // For now, don't remember plugin zoom values. We don't want to mix them with
4053 // normal web content (i.e. a fixed layout plugin would usually want them
4054 // different).
4055 bool remember = !webview()->mainFrame()->document().isPluginDocument();
4056
[email protected]b75b8292010-10-01 07:28:254057 int minimum_percent = static_cast<int>(
4058 WebView::zoomLevelToZoomFactor(minimum_level) * 100);
4059 int maximum_percent = static_cast<int>(
4060 WebView::zoomLevelToZoomFactor(maximum_level) * 100);
[email protected]b75b8292010-10-01 07:28:254061
4062 Send(new ViewHostMsg_UpdateZoomLimits(
4063 routing_id_, minimum_percent, maximum_percent, remember));
4064}
4065
4066void RenderView::zoomLevelChanged() {
4067 bool remember = !webview()->mainFrame()->document().isPluginDocument();
4068
[email protected]b75b8292010-10-01 07:28:254069 // Tell the browser which url got zoomed so it can update the menu and the
4070 // saved values if necessary
4071 Send(new ViewHostMsg_DidZoomURL(
[email protected]1cc58eb62010-10-01 22:38:414072 routing_id_, webview()->zoomLevel(), remember,
4073 GURL(webview()->mainFrame()->url())));
[email protected]b75b8292010-10-01 07:28:254074}
4075
[email protected]a6d36cc2011-02-23 00:39:484076void RenderView::registerProtocolHandler(const WebString& scheme,
4077 const WebString& base_url,
4078 const WebString& url,
4079 const WebString& title) {
4080 GURL base(base_url);
4081 GURL absolute_url = base.Resolve(UTF16ToUTF8(url));
4082 if (base.GetOrigin() != absolute_url.GetOrigin()) {
4083 return;
4084 }
4085 RenderThread::current()->Send(
4086 new ViewHostMsg_RegisterProtocolHandler(routing_id_,
4087 UTF16ToUTF8(scheme),
4088 absolute_url,
4089 title));
4090}
4091
[email protected]8079b362010-05-07 18:37:454092bool RenderView::IsNonLocalTopLevelNavigation(
[email protected]61c9f032010-03-31 23:04:194093 const GURL& url, WebKit::WebFrame* frame, WebKit::WebNavigationType type) {
[email protected]8079b362010-05-07 18:37:454094 // Must be a top level frame.
[email protected]61c9f032010-03-31 23:04:194095 if (frame->parent() != NULL)
4096 return false;
4097
[email protected]f0a3d0b2010-08-06 22:51:534098 // Navigations initiated within Webkit are not sent out to the external host
4099 // in the following cases.
[email protected]900eb2f12010-08-23 22:36:274100 // 1. The url scheme is not http/https
[email protected]d19ea342011-04-20 20:31:134101 // 2. The origin of the url and the opener is the same in which case the
[email protected]f0a3d0b2010-08-06 22:51:534102 // opener relationship is maintained.
[email protected]d19ea342011-04-20 20:31:134103 // 3. Reloads/form submits/back forward navigations
[email protected]f0a3d0b2010-08-06 22:51:534104 if (!url.SchemeIs("http") && !url.SchemeIs("https"))
4105 return false;
4106
[email protected]2fc22d12010-12-02 23:08:164107 // Not interested in reloads/form submits/resubmits/back forward navigations.
[email protected]d0ed50d2010-06-22 01:01:324108 if (type != WebKit::WebNavigationTypeReload &&
[email protected]070c49c2010-07-13 22:22:014109 type != WebKit::WebNavigationTypeFormSubmitted &&
[email protected]2fc22d12010-12-02 23:08:164110 type != WebKit::WebNavigationTypeFormResubmitted &&
[email protected]070c49c2010-07-13 22:22:014111 type != WebKit::WebNavigationTypeBackForward) {
[email protected]d0ed50d2010-06-22 01:01:324112 // The opener relationship between the new window and the parent allows the
4113 // new window to script the parent and vice versa. This is not allowed if
4114 // the origins of the two domains are different. This can be treated as a
4115 // top level navigation and routed back to the host.
4116 WebKit::WebFrame* opener = frame->opener();
[email protected]900eb2f12010-08-23 22:36:274117 if (!opener) {
[email protected]86965362011-04-21 18:42:514118 return true;
[email protected]d19ea342011-04-20 20:31:134119 } else {
4120 if (url.GetOrigin() != GURL(opener->url()).GetOrigin())
[email protected]d0ed50d2010-06-22 01:01:324121 return true;
4122 }
4123 }
[email protected]61c9f032010-03-31 23:04:194124 return false;
4125}
[email protected]2b06a992010-08-21 05:48:224126
[email protected]27a9ef32010-09-10 04:06:244127void RenderView::OnAsyncFileOpened(base::PlatformFileError error_code,
4128 IPC::PlatformFileForTransit file_for_transit,
4129 int message_id) {
4130 pepper_delegate_.OnAsyncFileOpened(
4131 error_code,
4132 IPC::PlatformFileForTransitToPlatformFile(file_for_transit),
4133 message_id);
4134}
[email protected]caf706f2010-10-26 17:54:084135
[email protected]2b657fd2011-04-18 16:00:474136void RenderView::OnPpapiBrokerChannelCreated(
4137 int request_id,
4138 base::ProcessHandle broker_process_handle,
4139 IPC::ChannelHandle handle) {
4140 pepper_delegate_.OnPpapiBrokerChannelCreated(request_id,
4141 broker_process_handle,
4142 handle);
[email protected]eb415bf0e2011-04-14 02:45:424143}
4144
[email protected]caf706f2010-10-26 17:54:084145#if defined(OS_MACOSX)
4146void RenderView::OnSelectPopupMenuItem(int selected_index) {
[email protected]68dc3ba2010-12-06 21:43:154147 if (external_popup_menu_ == NULL) {
4148 // Crash reports from the field indicate that we can be notified with a
4149 // NULL external popup menu (we probably get notified twice).
4150 // If you hit this please file a bug against jcivelli and include the page
4151 // and steps to repro.
4152 NOTREACHED();
4153 return;
4154 }
[email protected]caf706f2010-10-26 17:54:084155 external_popup_menu_->DidSelectItem(selected_index);
4156 external_popup_menu_.reset();
4157}
4158#endif
[email protected]bb461532010-11-26 21:50:234159
[email protected]1b4209f2011-01-07 00:25:404160#if defined(ENABLE_FLAPPER_HACKS)
4161void RenderView::OnConnectTcpACK(
4162 int request_id,
4163 IPC::PlatformFileForTransit socket_for_transit,
4164 const PP_Flash_NetAddress& local_addr,
4165 const PP_Flash_NetAddress& remote_addr) {
4166 pepper_delegate_.OnConnectTcpACK(
4167 request_id,
4168 IPC::PlatformFileForTransitToPlatformFile(socket_for_transit),
4169 local_addr,
4170 remote_addr);
4171}
4172#endif
[email protected]a6097f42011-01-10 08:50:514173
[email protected]b29aa74b2011-01-31 21:41:084174void RenderView::OnContextMenuClosed(
4175 const webkit_glue::CustomContextMenuContext& custom_context) {
4176 if (custom_context.is_pepper_menu)
4177 pepper_delegate_.OnContextMenuClosed(custom_context);
4178 else
4179 context_menu_node_.reset();
[email protected]521b2482011-01-15 00:10:104180}
[email protected]232a5812011-03-04 22:42:084181
4182void RenderView::OnNetworkStateChanged(bool online) {
4183 WebNetworkStateNotifier::setOnLine(online);
4184}