blob: 1856379fe592c9a13203e07c6699b969013c894c [file] [log] [blame]
[email protected]b553edd52012-01-10 12:15:231// Copyright (c) 2012 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]310ebd6302011-10-10 19:06:285#include "content/renderer/render_view_impl.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]6e806822011-11-19 01:51:0812#include "base/bind.h"
13#include "base/bind_helpers.h"
initial.commit09911bf2008-07-26 23:55:2914#include "base/command_line.h"
[email protected]bb063b72009-03-27 23:18:5015#include "base/compiler_specific.h"
[email protected]b1cf3372011-04-20 21:28:1016#include "base/json/json_writer.h"
[email protected]625332e02010-12-14 07:48:4917#include "base/lazy_instance.h"
[email protected]835d7c82010-10-14 04:38:3818#include "base/metrics/histogram.h"
[email protected]7bf795d92010-05-22 00:14:2819#include "base/path_service.h"
[email protected]8380c092009-06-25 17:45:5120#include "base/process_util.h"
[email protected]7ddea9802012-02-22 23:08:0521#include "base/string_number_conversions.h"
[email protected]0a35efc2012-03-13 17:28:1322#include "base/string_piece.h"
[email protected]318bf5802011-08-08 17:12:4123#include "base/string_split.h"
initial.commit09911bf2008-07-26 23:55:2924#include "base/string_util.h"
[email protected]55126132010-08-19 14:53:2825#include "base/sys_string_conversions.h"
[email protected]6fdd4182010-10-14 23:59:2626#include "base/time.h"
[email protected]be1ce6a72010-08-03 14:35:2227#include "base/utf_string_conversions.h"
[email protected]e93e04e2011-03-14 00:27:1028#include "content/common/appcache/appcache_dispatcher.h"
[email protected]127dd582011-03-16 21:32:1029#include "content/common/clipboard_messages.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]16dd6e22012-03-01 19:08:2032#include "content/common/fileapi/file_system_dispatcher.h"
33#include "content/common/fileapi/webfilesystem_callback_dispatcher.h"
[email protected]c26ad882012-02-07 06:41:2034#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
[email protected]a2ef54c2011-10-10 16:20:3135#include "content/common/intents_messages.h"
[email protected]7f3c7af2011-10-20 22:52:5136#include "content/common/java_bridge_messages.h"
[email protected]127dd582011-03-16 21:32:1037#include "content/common/pepper_messages.h"
[email protected]cebc3dc2011-04-18 17:15:0038#include "content/common/pepper_plugin_registry.h"
[email protected]10e5cf12011-04-13 04:10:4039#include "content/common/quota_dispatcher.h"
[email protected]940895b2011-08-20 00:50:0540#include "content/common/request_extra_data.h"
[email protected]5fa3a062012-03-21 15:39:3441#include "content/common/socket_stream_handle_data.h"
[email protected]778574e2011-03-21 22:03:5042#include "content/common/view_messages.h"
[email protected]e091df82011-10-11 18:13:2143#include "content/public/common/bindings_policy.h"
[email protected]744c2a22012-03-15 18:42:0444#include "content/public/common/content_client.h"
[email protected]54087fe2011-10-28 22:02:4845#include "content/public/common/content_constants.h"
[email protected]c08950d22011-10-13 22:20:2946#include "content/public/common/content_switches.h"
[email protected]35be7ec2012-02-12 20:42:5147#include "content/public/common/context_menu_params.h"
[email protected]8caadeb2011-11-22 02:45:2348#include "content/public/common/file_chooser_params.h"
[email protected]fb11b6a42012-03-14 07:25:1249#include "content/public/common/selected_file_info.h"
[email protected]a1d29162011-10-14 17:14:0350#include "content/public/common/url_constants.h"
[email protected]d344114c2011-10-01 01:24:3451#include "content/public/renderer/content_renderer_client.h"
[email protected]007733c2011-11-17 00:34:0752#include "content/public/renderer/document_state.h"
[email protected]82ddba1c2011-10-04 00:15:3253#include "content/public/renderer/navigation_state.h"
[email protected]3a034ebb2011-10-03 19:19:4454#include "content/public/renderer/render_view_observer.h"
[email protected]64ffa0442011-10-03 22:08:3655#include "content/public/renderer/render_view_visitor.h"
[email protected]230b7ef2011-03-16 22:30:1956#include "content/renderer/device_orientation_dispatcher.h"
[email protected]4a19be92011-09-22 14:25:0257#include "content/renderer/devtools_agent.h"
[email protected]766a7082012-02-03 23:39:1558#include "content/renderer/dom_automation_controller.h"
[email protected]55722152011-03-22 01:33:5359#include "content/renderer/external_popup_menu.h"
[email protected]230b7ef2011-03-16 22:30:1960#include "content/renderer/geolocation_dispatcher.h"
[email protected]84a83e192012-03-09 18:43:4061#include "content/renderer/gpu/compositor_thread.h"
[email protected]1784b2f2011-11-24 10:53:4862#include "content/renderer/idle_user_detector.h"
[email protected]c52b2892012-03-07 11:01:0263#include "content/renderer/input_tag_speech_dispatcher.h"
[email protected]07161902011-11-11 09:57:4264#include "content/renderer/java/java_bridge_dispatcher.h"
[email protected]921f1592011-03-18 00:41:0265#include "content/renderer/load_progress_tracker.h"
[email protected]25803d152011-06-14 01:18:0866#include "content/renderer/media/audio_message_filter.h"
[email protected]ccc70d8e2011-03-16 20:40:3767#include "content/renderer/media/audio_renderer_impl.h"
[email protected]273558fb2012-01-12 15:03:5168#include "content/renderer/media/media_stream_dependency_factory.h"
69#include "content/renderer/media/media_stream_dispatcher.h"
[email protected]ab2c4732011-07-20 19:57:4070#include "content/renderer/media/media_stream_impl.h"
[email protected]6048d512012-01-28 03:14:4871#include "content/renderer/media/render_audiosourceprovider.h"
[email protected]090f7312011-08-05 23:26:4072#include "content/renderer/media/render_media_log.h"
[email protected]6048d512012-01-28 03:14:4873#include "content/renderer/media/renderer_gpu_video_decoder_factories.h"
[email protected]4a19be92011-09-22 14:25:0274#include "content/renderer/mhtml_generator.h"
[email protected]217690d2012-01-27 07:33:1175#include "content/renderer/mouse_lock_dispatcher.h"
[email protected]230b7ef2011-03-16 22:30:1976#include "content/renderer/notification_provider.h"
[email protected]ccc70d8e2011-03-16 20:40:3777#include "content/renderer/p2p/socket_dispatcher.h"
[email protected]6f516082011-03-17 19:15:3578#include "content/renderer/plugin_channel_host.h"
[email protected]0361b942012-03-14 06:42:5379#include "content/renderer/browser_plugin/browser_plugin_constants.h"
80#include "content/renderer/browser_plugin/browser_plugin_placeholder.h"
[email protected]8704f89b2011-04-15 00:30:0581#include "content/renderer/render_process.h"
[email protected]f1a29a02011-10-06 23:08:4482#include "content/renderer/render_thread_impl.h"
[email protected]2cff0052011-03-18 16:51:4483#include "content/renderer/render_widget_fullscreen_pepper.h"
[email protected]063afcb2011-09-29 07:54:3284#include "content/renderer/renderer_accessibility.h"
[email protected]663bd9e2011-03-21 01:07:0185#include "content/renderer/renderer_webapplicationcachehost_impl.h"
[email protected]da8543762012-03-20 08:52:2086#include "content/renderer/renderer_webcolorchooser_impl.h"
[email protected]663bd9e2011-03-21 01:07:0187#include "content/renderer/renderer_webstoragenamespace_impl.h"
[email protected]86a7d3c2011-09-12 16:45:3288#include "content/renderer/text_input_client_observer.h"
[email protected]8d86f13d2011-10-04 17:01:1989#include "content/renderer/v8_value_converter_impl.h"
[email protected]0a35efc2012-03-13 17:28:1390#include "content/renderer/web_intents_host.h"
[email protected]663bd9e2011-03-21 01:07:0191#include "content/renderer/web_ui_bindings.h"
[email protected]6f516082011-03-17 19:15:3592#include "content/renderer/webplugin_delegate_proxy.h"
93#include "content/renderer/websharedworker_proxy.h"
[email protected]f8db8132010-12-03 00:27:4994#include "media/base/filter_collection.h"
[email protected]ee68378a2010-08-10 01:05:4195#include "media/base/media_switches.h"
[email protected]b80322902012-03-06 01:33:5096#include "media/base/message_loop_factory.h"
[email protected]e1d69d762011-12-13 05:12:1897#include "media/filters/gpu_video_decoder.h"
initial.commit09911bf2008-07-26 23:55:2998#include "net/base/escape.h"
99#include "net/base/net_errors.h"
[email protected]52c68652010-12-07 17:47:04100#include "net/http/http_util.h"
[email protected]8bd0fe62011-01-17 06:44:37101#include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObject.h"
[email protected]8bd0fe62011-01-17 06:44:37102#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
[email protected]8bd0fe62011-01-17 06:44:37103#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
[email protected]8bd0fe62011-01-17 06:44:37104#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
105#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserParams.h"
[email protected]8bd0fe62011-01-17 06:44:37106#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystemCallbacks.h"
107#include "third_party/WebKit/Source/WebKit/chromium/public/WebFindOptions.h"
108#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement.h"
109#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h"
110#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
[email protected]8bd0fe62011-01-17 06:44:37111#include "third_party/WebKit/Source/WebKit/chromium/public/WebHistoryItem.h"
[email protected]8bd0fe62011-01-17 06:44:37112#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h"
[email protected]56ea1a62011-05-30 07:05:57113#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
[email protected]8b5af492011-11-28 21:50:58114#include "third_party/WebKit/Source/WebKit/chromium/public/WebIntent.h"
[email protected]592e20b2012-01-20 05:53:44115#include "third_party/WebKit/Source/WebKit/chromium/public/WebIntentRequest.h"
[email protected]8b5af492011-11-28 21:50:58116#include "third_party/WebKit/Source/WebKit/chromium/public/WebIntentServiceInfo.h"
[email protected]69f110d62011-03-17 19:01:14117#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerAction.h"
[email protected]8bd0fe62011-01-17 06:44:37118#include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeList.h"
[email protected]18d5be92011-07-25 18:00:19119#include "third_party/WebKit/Source/WebKit/chromium/public/WebPageSerializer.h"
[email protected]8bd0fe62011-01-17 06:44:37120#include "third_party/WebKit/Source/WebKit/chromium/public/WebPlugin.h"
[email protected]81375e872012-01-11 21:40:36121#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginAction.h"
[email protected]8bd0fe62011-01-17 06:44:37122#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
123#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginDocument.h"
124#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h"
[email protected]8bd0fe62011-01-17 06:44:37125#include "third_party/WebKit/Source/WebKit/chromium/public/WebRange.h"
[email protected]8bd0fe62011-01-17 06:44:37126#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h"
127#include "third_party/WebKit/Source/WebKit/chromium/public/WebSearchableFormData.h"
128#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
[email protected]20dc3cad2011-04-20 17:27:17129#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h"
[email protected]8bd0fe62011-01-17 06:44:37130#include "third_party/WebKit/Source/WebKit/chromium/public/WebSettings.h"
[email protected]8bd0fe62011-01-17 06:44:37131#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageNamespace.h"
[email protected]10e5cf12011-04-13 04:10:40132#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageQuotaCallbacks.h"
[email protected]273558fb2012-01-12 15:03:51133#include "third_party/WebKit/Source/WebKit/chromium/public/WebUserMediaClient.h"
[email protected]9c4bf232011-12-15 02:25:08134#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
135#include "third_party/WebKit/Source/WebKit/chromium/public/WebWindowFeatures.h"
136#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h"
137#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebDragData.h"
138#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebGraphicsContext3D.h"
139#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebImage.h"
[email protected]273558fb2012-01-12 15:03:51140#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnectionHandler.h"
141#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnectionHandlerClient.h"
[email protected]9c4bf232011-12-15 02:25:08142#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPoint.h"
143#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
144#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
[email protected]5fa3a062012-03-21 15:39:34145#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSocketStreamHandle.h"
[email protected]e6e90dc2011-12-03 00:01:37146#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
147#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
148#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLError.h"
149#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLRequest.h"
150#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLResponse.h"
151#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
[email protected]6fdd4182010-10-14 23:59:26152#include "third_party/skia/include/core/SkBitmap.h"
[email protected]269f86d2011-12-07 02:43:47153#include "ui/base/javascript_message_type.h"
[email protected]08397d52011-02-05 01:53:38154#include "ui/gfx/native_widget_types.h"
155#include "ui/gfx/point.h"
156#include "ui/gfx/rect.h"
[email protected]c4a9e932011-03-05 04:05:55157#include "v8/include/v8.h"
[email protected]80f584d92010-01-21 03:59:04158#include "webkit/appcache/web_application_cache_host_impl.h"
[email protected]9c4bf232011-12-15 02:25:08159#include "webkit/forms/form_data.h"
160#include "webkit/forms/form_field.h"
161#include "webkit/forms/password_form_dom_manager.h"
[email protected]25e18f82010-10-27 16:38:43162#include "webkit/glue/alt_error_page_resource_fetcher.h"
[email protected]18d5be92011-07-25 18:00:19163#include "webkit/glue/dom_operations.h"
[email protected]95056b582010-02-18 01:29:24164#include "webkit/glue/glue_serialize.h"
initial.commit09911bf2008-07-26 23:55:29165#include "webkit/glue/webdropdata.h"
[email protected]a6939ca42011-02-18 17:58:07166#include "webkit/glue/webkit_constants.h"
initial.commit09911bf2008-07-26 23:55:29167#include "webkit/glue/webkit_glue.h"
[email protected]b00ba702011-08-17 01:41:03168#include "webkit/glue/weburlloader_impl.h"
[email protected]b9fd01ba2012-02-28 01:50:40169#include "webkit/glue/weburlresponse_extradata_impl.h"
[email protected]7e8b4d12012-01-20 23:39:51170#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"
[email protected]a9288f52011-11-17 05:18:16171#include "webkit/media/webmediaplayer_impl.h"
[email protected]191eb3f72010-12-21 06:27:50172#include "webkit/plugins/npapi/plugin_list.h"
173#include "webkit/plugins/npapi/webplugin_delegate.h"
174#include "webkit/plugins/npapi/webplugin_delegate_impl.h"
175#include "webkit/plugins/npapi/webplugin_impl.h"
[email protected]0bd753682010-12-16 18:15:52176#include "webkit/plugins/ppapi/ppapi_webplugin_impl.h"
initial.commit09911bf2008-07-26 23:55:29177
[email protected]6c8afae52009-01-22 02:24:57178#if defined(OS_WIN)
179// TODO(port): these files are currently Windows only because they concern:
[email protected]6c8afae52009-01-22 02:24:57180// * theming
[email protected]08397d52011-02-05 01:53:38181#include "ui/gfx/native_theme_win.h"
[email protected]6981f7f2010-03-09 00:53:03182#elif defined(USE_X11)
[email protected]8bd0fe62011-01-17 06:44:37183#include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebRenderTheme.h"
[email protected]42e5c862011-04-07 22:13:51184#include "ui/gfx/native_theme.h"
[email protected]78043bdd2010-04-05 18:45:33185#elif defined(OS_MACOSX)
186#include "skia/ext/skia_utils_mac.h"
[email protected]6c8afae52009-01-22 02:24:57187#endif
188
[email protected]9892b472010-09-16 00:23:42189using WebKit::WebAccessibilityNotification;
[email protected]cc0445f2009-10-13 16:09:08190using WebKit::WebAccessibilityObject;
[email protected]035545f2010-04-09 13:10:21191using WebKit::WebApplicationCacheHost;
192using WebKit::WebApplicationCacheHostClient;
[email protected]6fdd4182010-10-14 23:59:26193using WebKit::WebCString;
[email protected]1c83eb42009-09-11 21:08:41194using WebKit::WebColor;
195using WebKit::WebColorName;
[email protected]0dea3ea2009-03-31 23:30:59196using WebKit::WebConsoleMessage;
[email protected]79e37442009-10-09 18:17:44197using WebKit::WebContextMenuData;
[email protected]b921cfd22010-02-25 16:57:51198using WebKit::WebCookieJar;
[email protected]e6f546c32009-07-01 17:12:55199using WebKit::WebData;
[email protected]726985e22009-06-18 21:09:28200using WebKit::WebDataSource;
[email protected]5bc8fe92010-03-11 18:19:00201using WebKit::WebDocument;
[email protected]e80c73b2009-04-07 23:24:58202using WebKit::WebDragData;
[email protected]1d9f4132009-09-08 17:29:25203using WebKit::WebDragOperation;
204using WebKit::WebDragOperationsMask;
[email protected]79dbc662009-09-04 05:42:51205using WebKit::WebEditingAction;
[email protected]9b66f34bf2010-10-27 20:45:51206using WebKit::WebElement;
[email protected]caf706f2010-10-26 17:54:08207using WebKit::WebExternalPopupMenu;
208using WebKit::WebExternalPopupMenuClient;
[email protected]cdaf8d02010-03-30 19:52:47209using WebKit::WebFileChooserCompletion;
[email protected]2b06a992010-08-21 05:48:22210using WebKit::WebFileSystem;
211using WebKit::WebFileSystemCallbacks;
[email protected]6069da8c2009-10-20 20:33:49212using WebKit::WebFindOptions;
[email protected]b1438212010-04-03 00:30:59213using WebKit::WebFormControlElement;
[email protected]979c28b2009-11-07 01:30:48214using WebKit::WebFormElement;
[email protected]dd7daa82009-08-10 05:46:45215using WebKit::WebFrame;
[email protected]7e8b4d12012-01-20 23:39:51216using WebKit::WebGraphicsContext3D;
[email protected]ca948a22009-06-25 19:36:17217using WebKit::WebHistoryItem;
[email protected]42054a252011-05-17 18:02:13218using WebKit::WebIconURL;
[email protected]c27ae592010-03-18 15:24:41219using WebKit::WebImage;
[email protected]e6efd022010-03-31 09:34:50220using WebKit::WebInputElement;
[email protected]ffc8bed2012-01-21 01:23:15221using WebKit::WebIntentRequest;
222using WebKit::WebIntentServiceInfo;
[email protected]3d9689372009-09-10 04:29:17223using WebKit::WebMediaPlayer;
[email protected]952cb702009-10-07 05:50:28224using WebKit::WebMediaPlayerAction;
[email protected]3d9689372009-09-10 04:29:17225using WebKit::WebMediaPlayerClient;
[email protected]4873c7d2009-07-16 06:36:28226using WebKit::WebNavigationPolicy;
[email protected]726985e22009-06-18 21:09:28227using WebKit::WebNavigationType;
[email protected]79dbc662009-09-04 05:42:51228using WebKit::WebNode;
[email protected]18d5be92011-07-25 18:00:19229using WebKit::WebPageSerializer;
230using WebKit::WebPageSerializerClient;
[email protected]3d9689372009-09-10 04:29:17231using WebKit::WebPlugin;
[email protected]81375e872012-01-11 21:40:36232using WebKit::WebPluginAction;
[email protected]00152e92010-07-19 11:47:40233using WebKit::WebPluginContainer;
[email protected]24a7f3c2010-03-25 08:26:49234using WebKit::WebPluginDocument;
[email protected]aad51d1c2010-08-05 08:38:09235using WebKit::WebPluginParams;
[email protected]48c9cf2d2009-09-16 16:47:52236using WebKit::WebPoint;
[email protected]88efb7ec2009-07-14 16:32:59237using WebKit::WebPopupMenuInfo;
[email protected]79dbc662009-09-04 05:42:51238using WebKit::WebRange;
[email protected]b3f2b912009-04-09 16:18:52239using WebKit::WebRect;
[email protected]445e1042011-12-03 21:03:15240using WebKit::WebReferrerPolicy;
[email protected]4f999132009-03-31 18:08:40241using WebKit::WebScriptSource;
[email protected]ce0e250d2009-10-23 21:00:35242using WebKit::WebSearchableFormData;
[email protected]e3d60e5d2009-09-25 21:08:29243using WebKit::WebSecurityOrigin;
[email protected]20dc3cad2011-04-20 17:27:17244using WebKit::WebSecurityPolicy;
[email protected]2fab253a2009-08-17 23:00:59245using WebKit::WebSettings;
[email protected]9c00f002009-11-05 22:37:42246using WebKit::WebSharedWorker;
[email protected]8649fb32009-06-26 17:51:02247using WebKit::WebSize;
[email protected]5fa3a062012-03-21 15:39:34248using WebKit::WebSocketStreamHandle;
[email protected]bd92c3a2010-01-13 05:02:34249using WebKit::WebStorageNamespace;
[email protected]10e5cf12011-04-13 04:10:40250using WebKit::WebStorageQuotaCallbacks;
251using WebKit::WebStorageQuotaError;
252using WebKit::WebStorageQuotaType;
[email protected]726985e22009-06-18 21:09:28253using WebKit::WebString;
[email protected]79dbc662009-09-04 05:42:51254using WebKit::WebTextAffinity;
[email protected]de570ef2009-07-29 18:27:52255using WebKit::WebTextDirection;
[email protected]2d0f2e92011-10-03 09:02:24256using WebKit::WebTouchEvent;
[email protected]726985e22009-06-18 21:09:28257using WebKit::WebURL;
258using WebKit::WebURLError;
259using WebKit::WebURLRequest;
260using WebKit::WebURLResponse;
[email protected]4873c7d2009-07-16 06:36:28261using WebKit::WebVector;
[email protected]50ae00ef2009-10-19 05:11:03262using WebKit::WebView;
[email protected]4873c7d2009-07-16 06:36:28263using WebKit::WebWidget;
[email protected]6fdd4182010-10-14 23:59:26264using WebKit::WebWindowFeatures;
[email protected]6fdd4182010-10-14 23:59:26265using appcache::WebApplicationCacheHostImpl;
266using base::Time;
267using base::TimeDelta;
[email protected]007733c2011-11-17 00:34:07268using content::DocumentState;
[email protected]82ddba1c2011-10-04 00:15:32269using content::NavigationState;
[email protected]380244092011-10-07 17:26:27270using content::RenderThread;
[email protected]3a034ebb2011-10-03 19:19:44271using content::RenderViewObserver;
[email protected]64ffa0442011-10-03 22:08:36272using content::RenderViewVisitor;
[email protected]445e1042011-12-03 21:03:15273using content::Referrer;
[email protected]8d86f13d2011-10-04 17:01:19274using content::V8ValueConverter;
[email protected]9c4bf232011-12-15 02:25:08275using webkit::forms::FormField;
276using webkit::forms::PasswordForm;
277using webkit::forms::PasswordFormDomManager;
[email protected]6fdd4182010-10-14 23:59:26278using webkit_glue::AltErrorPageResourceFetcher;
[email protected]bb461532010-11-26 21:50:23279using webkit_glue::ResourceFetcher;
[email protected]b9fd01ba2012-02-28 01:50:40280using webkit_glue::WebURLResponseExtraDataImpl;
[email protected]e1acf6f2008-10-27 20:43:33281
initial.commit09911bf2008-07-26 23:55:29282//-----------------------------------------------------------------------------
283
[email protected]310ebd6302011-10-10 19:06:28284typedef std::map<WebKit::WebView*, RenderViewImpl*> ViewMap;
[email protected]6de0fd1d2011-11-15 13:31:49285static base::LazyInstance<ViewMap> g_view_map = LAZY_INSTANCE_INITIALIZER;
[email protected]3354d3e2010-06-10 19:53:02286
[email protected]882daa92009-11-05 16:31:31287// Time, in seconds, we delay before sending content state changes (such as form
288// state and scroll position) to the browser. We delay sending changes to avoid
289// spamming the browser.
290// To avoid having tab/session restore require sending a message to get the
291// current content state during tab closing we use a shorter timeout for the
292// foreground renderer. This means there is a small window of time from which
293// content state is modified and not sent to session restore, but this is
294// better than having to wake up all renderers during shutdown.
295static const int kDelaySecondsForContentStateSyncHidden = 5;
296static const int kDelaySecondsForContentStateSync = 1;
initial.commit09911bf2008-07-26 23:55:29297
[email protected]e99ef6f2011-10-16 01:13:00298static const size_t kExtraCharsBeforeAndAfterSelection = 100;
299
[email protected]0aa55312008-10-17 21:53:08300// The maximum number of popups that can be spawned from one page.
301static const int kMaximumNumberOfUnacknowledgedPopups = 25;
302
[email protected]c514d6372011-08-16 22:54:44303static const float kScalingIncrement = 0.1f;
304
[email protected]47578fa02011-11-02 19:34:41305static const float kScalingIncrementForGesture = 0.01f;
306
[email protected]726985e22009-06-18 21:09:28307static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
308 WebVector<WebURL> urls;
309 ds->redirectChain(urls);
310 result->reserve(urls.size());
311 for (size_t i = 0; i < urls.size(); ++i)
312 result->push_back(urls[i]);
313}
314
[email protected]007733c2011-11-17 00:34:07315// If |data_source| is non-null and has a DocumentState associated with it,
[email protected]6a8f5112011-05-13 16:38:44316// the AltErrorPageResourceFetcher is reset.
317static void StopAltErrorPageFetcher(WebDataSource* data_source) {
318 if (data_source) {
[email protected]007733c2011-11-17 00:34:07319 DocumentState* document_state = DocumentState::FromDataSource(data_source);
320 if (document_state)
321 document_state->set_alt_error_page_fetcher(NULL);
[email protected]6a8f5112011-05-13 16:38:44322 }
323}
324
[email protected]007733c2011-11-17 00:34:07325static bool IsReload(const ViewMsg_Navigate_Params& params) {
326 return
327 params.navigation_type == ViewMsg_Navigate_Type::RELOAD ||
328 params.navigation_type == ViewMsg_Navigate_Type::RELOAD_IGNORING_CACHE;
329}
330
[email protected]b9fd01ba2012-02-28 01:50:40331static WebReferrerPolicy GetReferrerPolicyFromRequest(
[email protected]445e1042011-12-03 21:03:15332 const WebURLRequest& request) {
333 return request.extraData() ?
334 static_cast<RequestExtraData*>(request.extraData())->referrer_policy() :
335 WebKit::WebReferrerPolicyDefault;
336}
337
[email protected]b9fd01ba2012-02-28 01:50:40338static WebURLResponseExtraDataImpl* GetExtraDataFromResponse(
339 const WebURLResponse& response) {
340 return static_cast<WebURLResponseExtraDataImpl*>(
341 response.extraData());
342}
343
[email protected]2149cc622012-02-14 01:12:12344NOINLINE static void CrashIntentionally() {
345 // NOTE(shess): Crash directly rather than using NOTREACHED() so
346 // that the signature is easier to triage in crash reports.
347 volatile int* zero = NULL;
348 *zero = 0;
349}
350
[email protected]8bf1048012012-02-08 01:22:18351static void MaybeHandleDebugURL(const GURL& url) {
352 if (!url.SchemeIs(chrome::kChromeUIScheme))
353 return;
354 if (url == GURL(chrome::kChromeUICrashURL)) {
[email protected]2149cc622012-02-14 01:12:12355 CrashIntentionally();
[email protected]8bf1048012012-02-08 01:22:18356 } else if (url == GURL(chrome::kChromeUIKillURL)) {
357 base::KillProcess(base::GetCurrentProcessHandle(), 1, false);
358 } else if (url == GURL(chrome::kChromeUIHangURL)) {
359 for (;;) {
360 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
361 }
362 } else if (url == GURL(chrome::kChromeUIShorthangURL)) {
363 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(20));
364 }
365}
366
initial.commit09911bf2008-07-26 23:55:29367///////////////////////////////////////////////////////////////////////////////
368
[email protected]310ebd6302011-10-10 19:06:28369struct RenderViewImpl::PendingFileChooser {
[email protected]8caadeb2011-11-22 02:45:23370 PendingFileChooser(const content::FileChooserParams& p,
[email protected]cdaf8d02010-03-30 19:52:47371 WebFileChooserCompletion* c)
372 : params(p),
373 completion(c) {
374 }
[email protected]8caadeb2011-11-22 02:45:23375 content::FileChooserParams params;
[email protected]cdaf8d02010-03-30 19:52:47376 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback.
377};
378
[email protected]217690d2012-01-27 07:33:11379namespace {
380
381class WebWidgetLockTarget : public MouseLockDispatcher::LockTarget {
382 public:
[email protected]82114f52012-03-20 22:53:41383 explicit WebWidgetLockTarget(WebKit::WebWidget* webwidget)
[email protected]217690d2012-01-27 07:33:11384 : webwidget_(webwidget) {}
385
386 virtual void OnLockMouseACK(bool succeeded) OVERRIDE {
387 if (succeeded)
388 webwidget_->didAcquirePointerLock();
389 else
390 webwidget_->didNotAcquirePointerLock();
391 }
392
393 virtual void OnMouseLockLost() OVERRIDE {
394 webwidget_->didLosePointerLock();
395 }
396
397 virtual bool HandleMouseLockedInputEvent(
398 const WebKit::WebMouseEvent &event) OVERRIDE {
399 // The WebWidget handles mouse lock in WebKit's handleInputEvent().
400 return false;
401 }
402
403 private:
404 WebKit::WebWidget* webwidget_;
405};
406
[email protected]86cd9472012-02-03 19:51:05407int64 ExtractPostId(const WebHistoryItem& item) {
408 if (item.isNull())
409 return -1;
410
411 if (item.httpBody().isNull())
412 return -1;
413
414 return item.httpBody().identifier();
415}
416
[email protected]217690d2012-01-27 07:33:11417} // namespace
418
[email protected]daf82f82011-10-31 22:35:31419RenderViewImpl::RenderViewImpl(
420 gfx::NativeViewId parent_hwnd,
421 int32 opener_id,
422 const content::RendererPreferences& renderer_prefs,
423 const WebPreferences& webkit_prefs,
424 SharedRenderViewCounter* counter,
425 int32 routing_id,
[email protected]9f4f3322012-01-18 22:29:56426 int32 surface_id,
[email protected]daf82f82011-10-31 22:35:31427 int64 session_storage_namespace_id,
[email protected]74ce1ad2011-12-16 21:51:46428 const string16& frame_name,
[email protected]6fd35b72012-03-01 19:46:41429 int32 next_page_id,
[email protected]8cca3da2012-03-20 08:26:34430 const WebKit::WebScreenInfo& screen_info,
431 bool guest)
[email protected]6fd35b72012-03-01 19:46:41432 : RenderWidget(WebKit::WebPopupTypeNone, screen_info),
[email protected]676126f72011-01-15 00:03:51433 webkit_preferences_(webkit_prefs),
[email protected]3354d3e2010-06-10 19:53:02434 send_content_state_immediately_(false),
[email protected]81e63782009-02-27 19:35:09435 enabled_bindings_(0),
[email protected]3354d3e2010-06-10 19:53:02436 send_preferred_size_changes_(false),
[email protected]81a34412009-01-05 19:17:24437 is_loading_(false),
[email protected]e75cb49e2009-01-05 23:13:21438 navigation_gesture_(NavigationGestureUnknown),
[email protected]3354d3e2010-06-10 19:53:02439 opened_by_user_gesture_(true),
440 opener_suppressed_(false),
[email protected]81a34412009-01-05 19:17:24441 page_id_(-1),
442 last_page_id_sent_to_browser_(-1),
[email protected]74ce1ad2011-12-16 21:51:46443 next_page_id_(next_page_id),
[email protected]3cc72b12010-03-18 23:03:00444 history_list_offset_(-1),
445 history_list_length_(0),
[email protected]3354d3e2010-06-10 19:53:02446 target_url_status_(TARGET_NONE),
[email protected]bbef1d32011-10-25 14:36:55447 selection_text_offset_(0),
[email protected]dd6afca2011-08-13 03:44:31448 cached_is_main_frame_pinned_to_left_(false),
449 cached_is_main_frame_pinned_to_right_(false),
450 cached_has_main_frame_horizontal_scrollbar_(false),
451 cached_has_main_frame_vertical_scrollbar_(false),
[email protected]05a980d7a2012-02-07 22:16:42452 context_has_swapbuffers_complete_callback_(false),
453 queried_for_swapbuffers_complete_callback_(false),
[email protected]d0fb8a72012-03-10 18:54:52454 context_is_web_graphics_context_3d_command_buffer_impl_(false),
[email protected]3354d3e2010-06-10 19:53:02455 ALLOW_THIS_IN_INITIALIZER_LIST(cookie_jar_(this)),
[email protected]676126f72011-01-15 00:03:51456 geolocation_dispatcher_(NULL),
[email protected]c52b2892012-03-07 11:01:02457 input_tag_speech_dispatcher_(NULL),
[email protected]676126f72011-01-15 00:03:51458 device_orientation_dispatcher_(NULL),
[email protected]273558fb2012-01-12 15:03:51459 media_stream_dispatcher_(NULL),
[email protected]cae8c8492011-03-03 11:12:18460 p2p_socket_dispatcher_(NULL),
[email protected]c5c1d6d2011-07-28 18:42:41461 devtools_agent_(NULL),
[email protected]063afcb2011-09-29 07:54:32462 renderer_accessibility_(NULL),
[email protected]217690d2012-01-27 07:33:11463 mouse_lock_dispatcher_(NULL),
[email protected]4fb60142011-08-09 02:22:08464 session_storage_namespace_id_(session_storage_namespace_id),
[email protected]ef5e98e2011-12-06 09:49:18465 handling_select_range_(false),
466#if defined(OS_WIN)
467 focused_plugin_id_(-1),
468#endif
[email protected]8cca3da2012-03-20 08:26:34469 guest_(guest),
[email protected]ef5e98e2011-12-06 09:49:18470 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) {
[email protected]676126f72011-01-15 00:03:51471 routing_id_ = routing_id;
[email protected]9f4f3322012-01-18 22:29:56472 surface_id_ = surface_id;
[email protected]676126f72011-01-15 00:03:51473 if (opener_id != MSG_ROUTING_NONE)
474 opener_id_ = opener_id;
475
[email protected]74ce1ad2011-12-16 21:51:46476 // Ensure we start with a valid next_page_id_ from the browser.
477 DCHECK_GE(next_page_id_, 0);
478
[email protected]21b3a6ae2011-11-30 00:45:29479#if defined(ENABLE_NOTIFICATIONS)
480 notification_provider_ = new NotificationProvider(this);
481#else
482 notification_provider_ = NULL;
483#endif
484
[email protected]11fee2332011-03-29 20:36:35485 webwidget_ = WebView::create(this);
[email protected]217690d2012-01-27 07:33:11486 webwidget_mouse_lock_target_.reset(new WebWidgetLockTarget(webwidget_));
[email protected]11fee2332011-03-29 20:36:35487
[email protected]676126f72011-01-15 00:03:51488 if (counter) {
489 shared_popup_counter_ = counter;
490 shared_popup_counter_->data++;
491 decrement_shared_popup_at_destruction_ = true;
492 } else {
493 shared_popup_counter_ = new SharedRenderViewCounter(0);
494 decrement_shared_popup_at_destruction_ = false;
495 }
496
[email protected]380244092011-10-07 17:26:27497 RenderThread::Get()->AddRoute(routing_id_, this);
[email protected]676126f72011-01-15 00:03:51498 // Take a reference on behalf of the RenderThread. This will be balanced
[email protected]8a5e0ca2011-08-25 06:30:47499 // when we receive ViewMsg_ClosePage.
[email protected]676126f72011-01-15 00:03:51500 AddRef();
501
502 // If this is a popup, we must wait for the CreatingNew_ACK message before
503 // completing initialization. Otherwise, we can finish it now.
504 if (opener_id == MSG_ROUTING_NONE) {
505 did_show_ = true;
[email protected]2d7c8552011-06-27 19:21:55506 CompleteInit(parent_hwnd);
[email protected]676126f72011-01-15 00:03:51507 }
508
[email protected]34c61bd52011-05-02 19:38:33509 g_view_map.Get().insert(std::make_pair(webview(), this));
510 webkit_preferences_.Apply(webview());
511 webview()->initializeMainFrame(this);
[email protected]2024c922011-09-02 23:34:35512 if (!frame_name.empty())
513 webview()->mainFrame()->setName(frame_name);
[email protected]34c61bd52011-05-02 19:38:33514 webview()->settings()->setMinimumTimerInterval(
515 is_hidden() ? webkit_glue::kBackgroundTabTimerInterval :
516 webkit_glue::kForegroundTabTimerInterval);
517
518 OnSetRendererPrefs(renderer_prefs);
519
[email protected]676126f72011-01-15 00:03:51520 host_window_ = parent_hwnd;
521
[email protected]a026daa2011-04-20 15:49:51522#if defined(ENABLE_P2P_APIS)
[email protected]273558fb2012-01-12 15:03:51523 if (!p2p_socket_dispatcher_)
524 p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this);
[email protected]a026daa2011-04-20 15:49:51525#endif
[email protected]cae8c8492011-03-03 11:12:18526
[email protected]5b87e782012-02-09 18:19:32527#if defined(ENABLE_WEBRTC)
[email protected]735873d2012-01-25 23:31:02528 if (!media_stream_dispatcher_)
529 media_stream_dispatcher_ = new MediaStreamDispatcher(this);
[email protected]5b87e782012-02-09 18:19:32530#endif
[email protected]735873d2012-01-25 23:31:02531
[email protected]8f6a3b852011-07-19 16:48:56532 new MHTMLGenerator(this);
[email protected]86a7d3c2011-09-12 16:45:32533#if defined(OS_MACOSX)
534 new TextInputClientObserver(this);
535#endif // defined(OS_MACOSX)
[email protected]8f6a3b852011-07-19 16:48:56536
[email protected]217690d2012-01-27 07:33:11537 // The next group of objects all implement RenderViewObserver, so are deleted
538 // along with the RenderView automatically.
[email protected]c5c1d6d2011-07-28 18:42:41539 devtools_agent_ = new DevToolsAgent(this);
[email protected]063afcb2011-09-29 07:54:32540 renderer_accessibility_ = new RendererAccessibility(this);
[email protected]217690d2012-01-27 07:33:11541 mouse_lock_dispatcher_ = new MouseLockDispatcher(this);
[email protected]0fc7dea72012-02-09 03:47:40542 intents_host_ = new WebIntentsHost(this);
[email protected]063afcb2011-09-29 07:54:32543
[email protected]1784b2f2011-11-24 10:53:48544 new IdleUserDetector(this);
545
[email protected]766a7082012-02-03 23:39:15546 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
547 if (command_line.HasSwitch(switches::kDomAutomationController))
548 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION;
549
[email protected]5b52cd2f712012-03-28 02:12:48550 ProcessViewLayoutFlags(command_line);
[email protected]7ddea9802012-02-22 23:08:05551
[email protected]e48869a2011-04-01 19:56:03552 content::GetContentClient()->renderer()->RenderViewCreated(this);
initial.commit09911bf2008-07-26 23:55:29553}
554
[email protected]310ebd6302011-10-10 19:06:28555RenderViewImpl::~RenderViewImpl() {
[email protected]d466b8a2011-07-15 21:48:03556 history_page_ids_.clear();
557
[email protected]0aa55312008-10-17 21:53:08558 if (decrement_shared_popup_at_destruction_)
559 shared_popup_counter_->data--;
560
[email protected]a1128322009-10-06 18:38:46561 // If file chooser is still waiting for answer, dispatch empty answer.
[email protected]cdaf8d02010-03-30 19:52:47562 while (!file_chooser_completions_.empty()) {
563 if (file_chooser_completions_.front()->completion) {
564 file_chooser_completions_.front()->completion->didChooseFile(
565 WebVector<WebString>());
566 }
567 file_chooser_completions_.pop_front();
568 }
[email protected]a1128322009-10-06 18:38:46569
[email protected]83dde542009-09-11 20:59:55570#if defined(OS_MACOSX)
[email protected]c36a9b62010-10-14 00:41:11571 // Destroy all fake plugin window handles on the browser side.
572 while (!fake_plugin_window_handles_.empty()) {
573 // Make sure no NULL plugin window handles were inserted into this list.
574 DCHECK(*fake_plugin_window_handles_.begin());
575 // DestroyFakePluginWindowHandle modifies fake_plugin_window_handles_.
576 DestroyFakePluginWindowHandle(*fake_plugin_window_handles_.begin());
577 }
[email protected]83dde542009-09-11 20:59:55578#endif
[email protected]98324892009-09-09 21:16:05579
[email protected]60c42a8c72009-10-09 04:08:59580#ifndef NDEBUG
581 // Make sure we are no longer referenced by the ViewMap.
[email protected]625332e02010-12-14 07:48:49582 ViewMap* views = g_view_map.Pointer();
[email protected]60c42a8c72009-10-09 04:08:59583 for (ViewMap::iterator it = views->begin(); it != views->end(); ++it)
584 DCHECK_NE(this, it->second) << "Failed to call Close?";
585#endif
[email protected]676126f72011-01-15 00:03:51586
[email protected]273558fb2012-01-12 15:03:51587 // MediaStreamImpl holds weak references to RenderViewObserver objects,
588 // ensure it's deleted before the observers.
589 media_stream_impl_ = NULL;
590
[email protected]310ebd6302011-10-10 19:06:28591 FOR_EACH_OBSERVER(RenderViewObserver, observers_, RenderViewGone());
[email protected]676126f72011-01-15 00:03:51592 FOR_EACH_OBSERVER(RenderViewObserver, observers_, OnDestruct());
[email protected]60c42a8c72009-10-09 04:08:59593}
594
595/*static*/
[email protected]310ebd6302011-10-10 19:06:28596RenderViewImpl* RenderViewImpl::FromWebView(WebView* webview) {
[email protected]a2ef54c2011-10-10 16:20:31597 ViewMap* views = g_view_map.Pointer();
598 ViewMap::iterator it = views->find(webview);
599 return it == views->end() ? NULL : it->second;
600}
601
602/*static*/
603content::RenderView*
604 content::RenderView::FromWebView(WebKit::WebView* webview) {
[email protected]310ebd6302011-10-10 19:06:28605 return RenderViewImpl::FromWebView(webview);
[email protected]a2ef54c2011-10-10 16:20:31606}
607
608/*static*/
609void content::RenderView::ForEach(content::RenderViewVisitor* visitor) {
[email protected]625332e02010-12-14 07:48:49610 ViewMap* views = g_view_map.Pointer();
[email protected]60c42a8c72009-10-09 04:08:59611 for (ViewMap::iterator it = views->begin(); it != views->end(); ++it) {
612 if (!visitor->Visit(it->second))
613 return;
614 }
615}
616
617/*static*/
[email protected]310ebd6302011-10-10 19:06:28618RenderViewImpl* RenderViewImpl::Create(
[email protected]18bcc3c2009-01-27 21:39:15619 gfx::NativeViewId parent_hwnd,
[email protected]0aa55312008-10-17 21:53:08620 int32 opener_id,
[email protected]daf82f82011-10-31 22:35:31621 const content::RendererPreferences& renderer_prefs,
[email protected]0aa55312008-10-17 21:53:08622 const WebPreferences& webkit_prefs,
623 SharedRenderViewCounter* counter,
[email protected]4e6419c2010-01-15 04:50:34624 int32 routing_id,
[email protected]9f4f3322012-01-18 22:29:56625 int32 surface_id,
[email protected]8ab04652010-06-12 02:47:26626 int64 session_storage_namespace_id,
[email protected]74ce1ad2011-12-16 21:51:46627 const string16& frame_name,
[email protected]6fd35b72012-03-01 19:46:41628 int32 next_page_id,
[email protected]8cca3da2012-03-20 08:26:34629 const WebKit::WebScreenInfo& screen_info,
630 bool guest) {
initial.commit09911bf2008-07-26 23:55:29631 DCHECK(routing_id != MSG_ROUTING_NONE);
[email protected]310ebd6302011-10-10 19:06:28632 return new RenderViewImpl(
[email protected]676126f72011-01-15 00:03:51633 parent_hwnd,
634 opener_id,
635 renderer_prefs,
636 webkit_prefs,
637 counter,
638 routing_id,
[email protected]9f4f3322012-01-18 22:29:56639 surface_id,
[email protected]676126f72011-01-15 00:03:51640 session_storage_namespace_id,
[email protected]74ce1ad2011-12-16 21:51:46641 frame_name,
[email protected]6fd35b72012-03-01 19:46:41642 next_page_id,
[email protected]8cca3da2012-03-20 08:26:34643 screen_info,
644 guest);
initial.commit09911bf2008-07-26 23:55:29645}
646
[email protected]273558fb2012-01-12 15:03:51647WebKit::WebPeerConnectionHandler* RenderViewImpl::CreatePeerConnectionHandler(
648 WebKit::WebPeerConnectionHandlerClient* client) {
649 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
650 if (!cmd_line->HasSwitch(switches::kEnableMediaStream))
651 return NULL;
652 EnsureMediaStreamImpl();
[email protected]5b87e782012-02-09 18:19:32653 if (!media_stream_impl_.get())
654 return NULL;
[email protected]273558fb2012-01-12 15:03:51655 return media_stream_impl_->CreatePeerConnectionHandler(client);
656}
657
[email protected]310ebd6302011-10-10 19:06:28658void RenderViewImpl::AddObserver(RenderViewObserver* observer) {
[email protected]676126f72011-01-15 00:03:51659 observers_.AddObserver(observer);
660}
661
[email protected]310ebd6302011-10-10 19:06:28662void RenderViewImpl::RemoveObserver(RenderViewObserver* observer) {
663 observer->RenderViewGone();
[email protected]676126f72011-01-15 00:03:51664 observers_.RemoveObserver(observer);
665}
666
[email protected]310ebd6302011-10-10 19:06:28667WebKit::WebView* RenderViewImpl::webview() const {
[email protected]4d51d5bf2010-07-26 18:48:26668 return static_cast<WebKit::WebView*>(webwidget());
669}
670
[email protected]310ebd6302011-10-10 19:06:28671void RenderViewImpl::SetReportLoadProgressEnabled(bool enabled) {
[email protected]1a3c3cb2010-12-16 21:03:40672 if (!enabled) {
673 load_progress_tracker_.reset(NULL);
674 return;
675 }
676 if (load_progress_tracker_ == NULL)
677 load_progress_tracker_.reset(new LoadProgressTracker(this));
678}
679
[email protected]310ebd6302011-10-10 19:06:28680void RenderViewImpl::PluginCrashed(const FilePath& plugin_path) {
[email protected]a3a8fb6d2009-10-22 20:12:51681 Send(new ViewHostMsg_CrashedPlugin(routing_id_, plugin_path));
initial.commit09911bf2008-07-26 23:55:29682}
683
[email protected]310ebd6302011-10-10 19:06:28684void RenderViewImpl::RegisterPluginDelegate(WebPluginDelegateProxy* delegate) {
[email protected]d8fd6fa2010-02-01 15:54:26685 plugin_delegates_.insert(delegate);
[email protected]49232292010-09-03 19:07:30686 // If the renderer is visible, set initial visibility and focus state.
687 if (!is_hidden()) {
[email protected]784ea1ab2010-09-18 00:02:34688#if defined(OS_MACOSX)
[email protected]49232292010-09-03 19:07:30689 delegate->SetContainerVisibility(true);
690 if (webview() && webview()->isActive())
691 delegate->SetWindowFocus(true);
[email protected]784ea1ab2010-09-18 00:02:34692#endif
[email protected]49232292010-09-03 19:07:30693 }
[email protected]784ea1ab2010-09-18 00:02:34694 // Plugins start assuming the content has focus (so that they work in
695 // environments where RenderView isn't hosting them), so we always have to
696 // set the initial state. See webplugin_delegate_impl.h for details.
697 delegate->SetContentAreaFocus(has_focus());
[email protected]d8fd6fa2010-02-01 15:54:26698}
699
[email protected]310ebd6302011-10-10 19:06:28700void RenderViewImpl::UnregisterPluginDelegate(
701 WebPluginDelegateProxy* delegate) {
[email protected]d8fd6fa2010-02-01 15:54:26702 plugin_delegates_.erase(delegate);
703}
[email protected]d8fd6fa2010-02-01 15:54:26704
[email protected]310ebd6302011-10-10 19:06:28705bool RenderViewImpl::GetPluginInfo(const GURL& url,
706 const GURL& page_url,
707 const std::string& mime_type,
708 webkit::WebPluginInfo* plugin_info,
709 std::string* actual_mime_type) {
[email protected]4a7d6392011-09-19 20:55:08710 bool found = false;
711 Send(new ViewHostMsg_GetPluginInfo(
712 routing_id_, url, page_url, mime_type, &found, plugin_info,
713 actual_mime_type));
714 return found;
715}
716
[email protected]7a1ec28a2012-03-28 21:10:24717void RenderViewImpl::TransferActiveWheelFlingAnimation(
718 const WebKit::WebActiveWheelFlingParameters& params) {
719 if (webview())
720 webview()->transferActiveWheelFlingAnimation(params);
721}
722
[email protected]310ebd6302011-10-10 19:06:28723bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
[email protected]26aa0482009-09-30 16:55:27724 WebFrame* main_frame = webview() ? webview()->mainFrame() : NULL;
[email protected]a9f607e2009-10-23 19:59:27725 if (main_frame)
[email protected]b6cb3a842011-06-24 18:28:41726 content::GetContentClient()->SetActiveURL(main_frame->document().url());
[email protected]f8b6b6f2009-03-10 16:48:26727
[email protected]676126f72011-01-15 00:03:51728 ObserverListBase<RenderViewObserver>::Iterator it(observers_);
729 RenderViewObserver* observer;
730 while ((observer = it.GetNext()) != NULL)
731 if (observer->OnMessageReceived(message))
732 return true;
[email protected]b2abac72009-02-26 12:39:28733
[email protected]a95986a82010-12-24 06:19:28734 bool handled = true;
[email protected]ffc906f2011-10-04 22:55:40735 bool msg_is_ok = true;
[email protected]310ebd6302011-10-10 19:06:28736 IPC_BEGIN_MESSAGE_MAP_EX(RenderViewImpl, message, msg_is_ok)
initial.commit09911bf2008-07-26 23:55:29737 IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
738 IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
[email protected]1dda4022010-01-28 18:24:56739 IPC_MESSAGE_HANDLER(ViewMsg_ReloadFrame, OnReloadFrame)
initial.commit09911bf2008-07-26 23:55:29740 IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)
741 IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)
742 IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)
743 IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)
[email protected]c0cc3092009-09-12 08:27:27744#if defined(OS_MACOSX)
[email protected]a954bf72009-09-12 07:30:35745 IPC_MESSAGE_HANDLER(ViewMsg_CopyToFindPboard, OnCopyToFindPboard)
[email protected]c0cc3092009-09-12 08:27:27746#endif
initial.commit09911bf2008-07-26 23:55:29747 IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)
[email protected]44bf7002011-10-16 02:46:15748 IPC_MESSAGE_HANDLER(ViewMsg_PasteAndMatchStyle, OnPasteAndMatchStyle)
initial.commit09911bf2008-07-26 23:55:29749 IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)
750 IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)
751 IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)
[email protected]4fb60142011-08-09 02:22:08752 IPC_MESSAGE_HANDLER(ViewMsg_SelectRange, OnSelectRange)
initial.commit09911bf2008-07-26 23:55:29753 IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
[email protected]4b59ae602009-06-23 20:58:15754 IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand)
initial.commit09911bf2008-07-26 23:55:29755 IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
[email protected]24a7f3c2010-03-25 08:26:49756 IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
757 IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)
[email protected]630e26b2008-10-14 22:55:17758 IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
[email protected]d0b8d092010-10-25 04:05:17759 IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevel, OnSetZoomLevel)
[email protected]47578fa02011-11-02 19:34:41760 IPC_MESSAGE_HANDLER(ViewMsg_ZoomFactor, OnZoomFactor)
[email protected]9d797f32010-04-23 07:17:54761 IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForLoadingURL,
762 OnSetZoomLevelForLoadingURL)
initial.commit09911bf2008-07-26 23:55:29763 IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
[email protected]a697f4c2009-09-14 22:30:18764 IPC_MESSAGE_HANDLER(ViewMsg_ResetPageEncodingToDefault,
765 OnResetPageEncodingToDefault)
initial.commit09911bf2008-07-26 23:55:29766 IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
[email protected]1810e132009-03-24 23:35:48767 IPC_MESSAGE_HANDLER(ViewMsg_CSSInsertRequest, OnCSSInsertRequest)
[email protected]59f4f2fa2011-03-23 01:00:55768 IPC_MESSAGE_HANDLER(DragMsg_TargetDragEnter, OnDragTargetDragEnter)
769 IPC_MESSAGE_HANDLER(DragMsg_TargetDragOver, OnDragTargetDragOver)
770 IPC_MESSAGE_HANDLER(DragMsg_TargetDragLeave, OnDragTargetDragLeave)
771 IPC_MESSAGE_HANDLER(DragMsg_TargetDrop, OnDragTargetDrop)
772 IPC_MESSAGE_HANDLER(DragMsg_SourceEndedOrMoved, OnDragSourceEndedOrMoved)
773 IPC_MESSAGE_HANDLER(DragMsg_SourceSystemDragEnded,
774 OnDragSourceSystemDragEnded)
[email protected]18cb2572008-08-21 20:34:45775 IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)
[email protected]d0980792011-02-13 19:41:40776 IPC_MESSAGE_HANDLER(ViewMsg_SetWebUIProperty, OnSetWebUIProperty)
initial.commit09911bf2008-07-26 23:55:29777 IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)
[email protected]333ec8d02011-09-16 18:59:19778 IPC_MESSAGE_HANDLER(ViewMsg_ScrollFocusedEditableNodeIntoRect,
779 OnScrollFocusedEditableNodeIntoRect)
initial.commit09911bf2008-07-26 23:55:29780 IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)
781 IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
782 IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)
[email protected]600ea402011-04-12 00:01:51783 IPC_MESSAGE_HANDLER(ViewMsg_EnumerateDirectoryResponse,
784 OnEnumerateDirectoryResponse)
initial.commit09911bf2008-07-26 23:55:29785 IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
[email protected]9b18a84f2010-06-10 15:54:04786 IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnShouldClose)
[email protected]992db4c2011-05-12 15:37:15787 IPC_MESSAGE_HANDLER(ViewMsg_SwapOut, OnSwapOut)
initial.commit09911bf2008-07-26 23:55:29788 IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
789 IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)
[email protected]0aa55312008-10-17 21:53:08790 IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
791 OnDisassociateFromPopupCount)
[email protected]30f75e62009-02-25 22:01:00792 IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
[email protected]05d478752009-04-08 23:38:16793 IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
[email protected]699ab0d2009-04-23 23:19:14794 IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
[email protected]ab32b16c2009-10-16 14:57:25795 IPC_MESSAGE_HANDLER(ViewMsg_EnablePreferredSizeChangedMode,
796 OnEnablePreferredSizeChangedMode)
[email protected]244ac1892011-12-02 17:04:47797 IPC_MESSAGE_HANDLER(ViewMsg_EnableAutoResize, OnEnableAutoResize)
[email protected]61e2b3cc2012-03-02 16:13:34798 IPC_MESSAGE_HANDLER(ViewMsg_DisableAutoResize, OnDisableAutoResize)
[email protected]cda45c02010-02-25 19:28:10799 IPC_MESSAGE_HANDLER(ViewMsg_DisableScrollbarsForSmallWindows,
800 OnDisableScrollbarsForSmallWindows)
[email protected]80d96fa2009-06-10 22:34:51801 IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
[email protected]581b87eb2009-07-23 23:06:56802 IPC_MESSAGE_HANDLER(ViewMsg_MediaPlayerActionAt, OnMediaPlayerActionAt)
[email protected]81375e872012-01-11 21:40:36803 IPC_MESSAGE_HANDLER(ViewMsg_PluginActionAt, OnPluginActionAt)
[email protected]8c66c5a2009-07-22 17:26:34804 IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
[email protected]7a17bac02012-03-07 21:58:12805 IPC_MESSAGE_HANDLER(ViewMsg_SetNavigationStartTime,
806 OnSetNavigationStartTime)
[email protected]6ce7abc52010-02-02 18:40:14807#if defined(OS_MACOSX)
808 IPC_MESSAGE_HANDLER(ViewMsg_SetWindowVisibility, OnSetWindowVisibility)
[email protected]1e6e3c992010-02-08 15:52:13809 IPC_MESSAGE_HANDLER(ViewMsg_WindowFrameChanged, OnWindowFrameChanged)
[email protected]b7f75862011-01-21 21:15:13810 IPC_MESSAGE_HANDLER(ViewMsg_PluginImeCompositionCompleted,
811 OnPluginImeCompositionCompleted)
[email protected]6ce7abc52010-02-02 18:40:14812#endif
[email protected]446705872009-09-10 07:22:48813 IPC_MESSAGE_HANDLER(ViewMsg_SetEditCommandsForNextKeyEvent,
[email protected]a0c7153e2009-12-09 14:36:33814 OnSetEditCommandsForNextKeyEvent)
[email protected]a0c7153e2009-12-09 14:36:33815 IPC_MESSAGE_HANDLER(ViewMsg_CustomContextMenuAction,
816 OnCustomContextMenuAction)
[email protected]27a9ef32010-09-10 04:06:24817 IPC_MESSAGE_HANDLER(ViewMsg_AsyncOpenFile_ACK, OnAsyncFileOpened)
[email protected]eb415bf0e2011-04-14 02:45:42818 IPC_MESSAGE_HANDLER(ViewMsg_PpapiBrokerChannelCreated,
819 OnPpapiBrokerChannelCreated)
[email protected]18d5be92011-07-25 18:00:19820 IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,
821 OnGetAllSavableResourceLinksForCurrentPage)
822 IPC_MESSAGE_HANDLER(
823 ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,
824 OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)
[email protected]caf706f2010-10-26 17:54:08825#if defined(OS_MACOSX)
826 IPC_MESSAGE_HANDLER(ViewMsg_SelectPopupMenuItem, OnSelectPopupMenuItem)
827#endif
[email protected]521b2482011-01-15 00:10:10828 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed)
[email protected]f0557932011-01-25 20:20:51829 // TODO(viettrungluu): Move to a separate message filter.
[email protected]54ca3ca892011-06-07 21:14:54830#if defined(OS_MACOSX)
831 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize)
832#endif
[email protected]9e1ad4b2011-08-14 16:49:19833 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune,
834 OnSetHistoryLengthAndPrune)
[email protected]5a7b15a2011-08-22 22:48:18835 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)
[email protected]7f3c7af2011-10-20 22:52:51836 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit)
[email protected]9e1ad4b2011-08-14 16:49:19837
initial.commit09911bf2008-07-26 23:55:29838 // Have the super handle all other messages.
[email protected]a95986a82010-12-24 06:19:28839 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message))
initial.commit09911bf2008-07-26 23:55:29840 IPC_END_MESSAGE_MAP()
[email protected]ffc906f2011-10-04 22:55:40841
842 if (!msg_is_ok) {
843 // The message had a handler, but its deserialization failed.
844 // Kill the renderer to avoid potential spoofing attacks.
[email protected]310ebd6302011-10-10 19:06:28845 CHECK(false) << "Unable to deserialize message in RenderViewImpl.";
[email protected]ffc906f2011-10-04 22:55:40846 }
847
[email protected]a95986a82010-12-24 06:19:28848 return handled;
initial.commit09911bf2008-07-26 23:55:29849}
850
[email protected]310ebd6302011-10-10 19:06:28851void RenderViewImpl::OnNavigate(const ViewMsg_Navigate_Params& params) {
[email protected]8bf1048012012-02-08 01:22:18852 MaybeHandleDebugURL(params.url);
initial.commit09911bf2008-07-26 23:55:29853 if (!webview())
854 return;
855
[email protected]440a0e52011-09-13 17:38:58856 FOR_EACH_OBSERVER(RenderViewObserver, observers_, Navigate(params.url));
857
[email protected]007733c2011-11-17 00:34:07858 bool is_reload = IsReload(params);
[email protected]d466b8a2011-07-15 21:48:03859
860 // If this is a stale back/forward (due to a recent navigation the browser
861 // didn't know about), ignore it.
862 if (IsBackForwardToStaleEntry(params, is_reload))
863 return;
864
[email protected]992db4c2011-05-12 15:37:15865 // Swap this renderer back in if necessary.
866 if (is_swapped_out_)
867 SetSwappedOut(false);
868
[email protected]3cc72b12010-03-18 23:03:00869 history_list_offset_ = params.current_history_list_offset;
870 history_list_length_ = params.current_history_list_length;
[email protected]d466b8a2011-07-15 21:48:03871 if (history_list_length_ >= 0)
872 history_page_ids_.resize(history_list_length_, -1);
873 if (params.pending_history_list_offset >= 0 &&
874 params.pending_history_list_offset < history_list_length_)
875 history_page_ids_[params.pending_history_list_offset] = params.page_id;
[email protected]3cc72b12010-03-18 23:03:00876
[email protected]38b592902011-04-16 02:08:42877 content::GetContentClient()->SetActiveURL(params.url);
initial.commit09911bf2008-07-26 23:55:29878
[email protected]26aa0482009-09-30 16:55:27879 WebFrame* main_frame = webview()->mainFrame();
[email protected]dd7daa82009-08-10 05:46:45880 if (is_reload && main_frame->currentHistoryItem().isNull()) {
initial.commit09911bf2008-07-26 23:55:29881 // We cannot reload if we do not have any history state. This happens, for
882 // example, when recovering from a crash. Our workaround here is a bit of
883 // a hack since it means that reload after a crashed tab does not cause an
884 // end-to-end cache validation.
885 is_reload = false;
886 }
887
[email protected]007733c2011-11-17 00:34:07888 pending_navigation_params_.reset(new ViewMsg_Navigate_Params);
889 *pending_navigation_params_.get() = params;
[email protected]48a5c772011-04-18 23:50:50890
[email protected]04d3c6e2009-05-22 17:00:13891 // If we are reloading, then WebKit will use the history state of the current
892 // page, so we should just ignore any given history state. Otherwise, if we
893 // have history state, then we need to navigate to it, which corresponds to a
894 // back/forward navigation event.
[email protected]e6f546c32009-07-01 17:12:55895 if (is_reload) {
[email protected]ecbf10d2010-02-18 13:03:29896 bool ignore_cache = (params.navigation_type ==
[email protected]2c5569662011-03-22 20:45:02897 ViewMsg_Navigate_Type::RELOAD_IGNORING_CACHE);
[email protected]ecbf10d2010-02-18 13:03:29898 main_frame->reload(ignore_cache);
[email protected]e6f546c32009-07-01 17:12:55899 } else if (!params.state.empty()) {
[email protected]04d3c6e2009-05-22 17:00:13900 // We must know the page ID of the page we are navigating back to.
[email protected]f929f2f22009-06-12 16:56:58901 DCHECK_NE(params.page_id, -1);
[email protected]dd7daa82009-08-10 05:46:45902 main_frame->loadHistoryItem(
[email protected]ca948a22009-06-25 19:36:17903 webkit_glue::HistoryItemFromString(params.state));
[email protected]04d3c6e2009-05-22 17:00:13904 } else {
905 // Navigate to the given URL.
[email protected]726985e22009-06-18 21:09:28906 WebURLRequest request(params.url);
initial.commit09911bf2008-07-26 23:55:29907
[email protected]e6f546c32009-07-01 17:12:55908 // A session history navigation should have been accompanied by state.
[email protected]cbc0cb72011-12-06 18:58:23909 CHECK_EQ(params.page_id, -1);
[email protected]04d3c6e2009-05-22 17:00:13910
[email protected]dd7daa82009-08-10 05:46:45911 if (main_frame->isViewSourceModeEnabled())
[email protected]e6f546c32009-07-01 17:12:55912 request.setCachePolicy(WebURLRequest::ReturnCacheDataElseLoad);
[email protected]04d3c6e2009-05-22 17:00:13913
[email protected]445e1042011-12-03 21:03:15914 if (params.referrer.url.is_valid()) {
915 WebString referrer = WebSecurityPolicy::generateReferrerHeader(
916 params.referrer.policy,
917 params.url,
918 WebString::fromUTF8(params.referrer.url.spec()));
919 if (!referrer.isEmpty())
920 request.setHTTPHeaderField(WebString::fromUTF8("Referer"), referrer);
[email protected]726985e22009-06-18 21:09:28921 }
[email protected]04d3c6e2009-05-22 17:00:13922
[email protected]52c68652010-12-07 17:47:04923 if (!params.extra_headers.empty()) {
924 for (net::HttpUtil::HeadersIterator i(params.extra_headers.begin(),
925 params.extra_headers.end(), "\n");
926 i.GetNext(); ) {
927 request.addHTTPHeaderField(WebString::fromUTF8(i.name()),
928 WebString::fromUTF8(i.values()));
929 }
930 }
[email protected]dd7daa82009-08-10 05:46:45931 main_frame->loadRequest(request);
[email protected]c0588052008-10-27 23:01:50932 }
933
[email protected]77f17a82009-05-21 04:42:54934 // In case LoadRequest failed before DidCreateDataSource was called.
[email protected]007733c2011-11-17 00:34:07935 pending_navigation_params_.reset();
initial.commit09911bf2008-07-26 23:55:29936}
937
[email protected]310ebd6302011-10-10 19:06:28938bool RenderViewImpl::IsBackForwardToStaleEntry(
[email protected]d466b8a2011-07-15 21:48:03939 const ViewMsg_Navigate_Params& params,
940 bool is_reload) {
941 // Make sure this isn't a back/forward to an entry we have already cropped
942 // or replaced from our history, before the browser knew about it. If so,
943 // a new navigation has committed in the mean time, and we can ignore this.
944 bool is_back_forward = !is_reload && !params.state.empty();
945
946 // Note: if the history_list_length_ is 0 for a back/forward, we must be
947 // restoring from a previous session. We'll update our state in OnNavigate.
948 if (!is_back_forward || history_list_length_ <= 0)
949 return false;
950
951 DCHECK_EQ(static_cast<int>(history_page_ids_.size()), history_list_length_);
952
953 // Check for whether the forward history has been cropped due to a recent
954 // navigation the browser didn't know about.
955 if (params.pending_history_list_offset >= history_list_length_)
956 return true;
957
958 // Check for whether this entry has been replaced with a new one.
959 int expected_page_id =
960 history_page_ids_[params.pending_history_list_offset];
[email protected]9978b8f02011-08-13 16:17:44961 if (expected_page_id > 0 && params.page_id != expected_page_id) {
962 if (params.page_id < expected_page_id)
963 return true;
964
965 // Otherwise we've removed an earlier entry and should have shifted all
966 // entries left. For now, it's ok to lazily update the list.
967 // TODO(creis): Notify all live renderers when we remove entries from
968 // the front of the list, so that we don't hit this case.
969 history_page_ids_[params.pending_history_list_offset] = params.page_id;
970 }
[email protected]d466b8a2011-07-15 21:48:03971
972 return false;
973}
974
initial.commit09911bf2008-07-26 23:55:29975// Stop loading the current page
[email protected]310ebd6302011-10-10 19:06:28976void RenderViewImpl::OnStop() {
[email protected]6a8f5112011-05-13 16:38:44977 if (webview()) {
978 WebFrame* main_frame = webview()->mainFrame();
979 // Stop the alt error page fetcher. If we let it continue it may complete
980 // and cause RenderViewHostManager to swap to this RenderView, even though
981 // it may no longer be active.
982 StopAltErrorPageFetcher(main_frame->provisionalDataSource());
983 StopAltErrorPageFetcher(main_frame->dataSource());
984 main_frame->stopLoading();
985 }
initial.commit09911bf2008-07-26 23:55:29986}
987
[email protected]ecbf10d2010-02-18 13:03:29988// Reload current focused frame.
989// E.g. called by right-clicking on the frame and picking "reload this frame".
[email protected]310ebd6302011-10-10 19:06:28990void RenderViewImpl::OnReloadFrame() {
[email protected]ecbf10d2010-02-18 13:03:29991 if (webview() && webview()->focusedFrame()) {
992 // We always obey the cache (ignore_cache=false) here.
993 // TODO(evanm): perhaps we could allow shift-clicking the menu item to do
994 // a cache-ignoring reload of the frame.
995 webview()->focusedFrame()->reload(false);
996 }
[email protected]1dda4022010-01-28 18:24:56997}
998
[email protected]310ebd6302011-10-10 19:06:28999void RenderViewImpl::OnCopyImageAt(int x, int y) {
[email protected]26aa0482009-09-30 16:55:271000 webview()->copyImageAt(WebPoint(x, y));
initial.commit09911bf2008-07-26 23:55:291001}
1002
[email protected]310ebd6302011-10-10 19:06:281003void RenderViewImpl::OnExecuteEditCommand(const std::string& name,
[email protected]68b1e922009-06-23 16:00:251004 const std::string& value) {
[email protected]26aa0482009-09-30 16:55:271005 if (!webview() || !webview()->focusedFrame())
[email protected]68b1e922009-06-23 16:00:251006 return;
1007
[email protected]26aa0482009-09-30 16:55:271008 webview()->focusedFrame()->executeCommand(
[email protected]dd7daa82009-08-10 05:46:451009 WebString::fromUTF8(name), WebString::fromUTF8(value));
[email protected]68b1e922009-06-23 16:00:251010}
1011
[email protected]310ebd6302011-10-10 19:06:281012void RenderViewImpl::OnUpdateTargetURLAck() {
initial.commit09911bf2008-07-26 23:55:291013 // Check if there is a targeturl waiting to be sent.
1014 if (target_url_status_ == TARGET_PENDING) {
1015 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_,
1016 pending_target_url_));
1017 }
1018
1019 target_url_status_ = TARGET_NONE;
1020}
1021
[email protected]310ebd6302011-10-10 19:06:281022void RenderViewImpl::OnUndo() {
initial.commit09911bf2008-07-26 23:55:291023 if (!webview())
1024 return;
1025
[email protected]26aa0482009-09-30 16:55:271026 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Undo"));
initial.commit09911bf2008-07-26 23:55:291027}
1028
[email protected]310ebd6302011-10-10 19:06:281029void RenderViewImpl::OnRedo() {
initial.commit09911bf2008-07-26 23:55:291030 if (!webview())
1031 return;
1032
[email protected]26aa0482009-09-30 16:55:271033 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Redo"));
initial.commit09911bf2008-07-26 23:55:291034}
1035
[email protected]310ebd6302011-10-10 19:06:281036void RenderViewImpl::OnCut() {
initial.commit09911bf2008-07-26 23:55:291037 if (!webview())
1038 return;
1039
[email protected]26aa0482009-09-30 16:55:271040 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Cut"));
initial.commit09911bf2008-07-26 23:55:291041}
1042
[email protected]310ebd6302011-10-10 19:06:281043void RenderViewImpl::OnCopy() {
initial.commit09911bf2008-07-26 23:55:291044 if (!webview())
1045 return;
1046
[email protected]f6b1856b2011-06-29 22:02:531047 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Copy"),
1048 context_menu_node_);
initial.commit09911bf2008-07-26 23:55:291049}
1050
[email protected]c0cc3092009-09-12 08:27:271051#if defined(OS_MACOSX)
[email protected]310ebd6302011-10-10 19:06:281052void RenderViewImpl::OnCopyToFindPboard() {
[email protected]a954bf72009-09-12 07:30:351053 if (!webview())
1054 return;
1055
1056 // Since the find pasteboard supports only plain text, this can be simpler
1057 // than the |OnCopy()| case.
[email protected]26aa0482009-09-30 16:55:271058 WebFrame* frame = webview()->focusedFrame();
[email protected]a954bf72009-09-12 07:30:351059 if (frame->hasSelection()) {
1060 string16 selection = frame->selectionAsText();
[email protected]380244092011-10-07 17:26:271061 RenderThread::Get()->Send(
[email protected]7e3589742011-03-10 18:49:171062 new ClipboardHostMsg_FindPboardWriteStringAsync(selection));
[email protected]a954bf72009-09-12 07:30:351063 }
[email protected]a954bf72009-09-12 07:30:351064}
[email protected]c0cc3092009-09-12 08:27:271065#endif
[email protected]a954bf72009-09-12 07:30:351066
[email protected]310ebd6302011-10-10 19:06:281067void RenderViewImpl::OnPaste() {
initial.commit09911bf2008-07-26 23:55:291068 if (!webview())
1069 return;
1070
[email protected]26aa0482009-09-30 16:55:271071 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Paste"));
initial.commit09911bf2008-07-26 23:55:291072}
1073
[email protected]44bf7002011-10-16 02:46:151074void RenderViewImpl::OnPasteAndMatchStyle() {
1075 if (!webview())
1076 return;
1077
1078 webview()->focusedFrame()->executeCommand(
1079 WebString::fromUTF8("PasteAndMatchStyle"));
1080}
1081
[email protected]310ebd6302011-10-10 19:06:281082void RenderViewImpl::OnReplace(const string16& text) {
initial.commit09911bf2008-07-26 23:55:291083 if (!webview())
1084 return;
1085
[email protected]1ff7a032010-02-03 02:46:031086 WebFrame* frame = webview()->focusedFrame();
1087 if (!frame->hasSelection())
1088 frame->selectWordAroundCaret();
1089 frame->replaceSelection(text);
initial.commit09911bf2008-07-26 23:55:291090}
1091
[email protected]310ebd6302011-10-10 19:06:281092void RenderViewImpl::OnDelete() {
initial.commit09911bf2008-07-26 23:55:291093 if (!webview())
1094 return;
1095
[email protected]26aa0482009-09-30 16:55:271096 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Delete"));
initial.commit09911bf2008-07-26 23:55:291097}
1098
[email protected]310ebd6302011-10-10 19:06:281099void RenderViewImpl::OnSelectAll() {
initial.commit09911bf2008-07-26 23:55:291100 if (!webview())
1101 return;
1102
[email protected]26aa0482009-09-30 16:55:271103 webview()->focusedFrame()->executeCommand(
[email protected]a100d76bb2009-08-14 17:50:221104 WebString::fromUTF8("SelectAll"));
initial.commit09911bf2008-07-26 23:55:291105}
1106
[email protected]310ebd6302011-10-10 19:06:281107void RenderViewImpl::OnSelectRange(const gfx::Point& start,
1108 const gfx::Point& end) {
[email protected]4fb60142011-08-09 02:22:081109 if (!webview())
1110 return;
1111
1112 handling_select_range_ = true;
1113 webview()->focusedFrame()->selectRange(start, end);
1114 handling_select_range_ = false;
1115}
1116
[email protected]310ebd6302011-10-10 19:06:281117void RenderViewImpl::OnSetHistoryLengthAndPrune(int history_length,
1118 int32 minimum_page_id) {
[email protected]9e1ad4b2011-08-14 16:49:191119 DCHECK(history_length >= 0);
1120 DCHECK(history_list_offset_ == history_list_length_ - 1);
1121 DCHECK(minimum_page_id >= -1);
1122
1123 // Generate the new list.
1124 std::vector<int32> new_history_page_ids(history_length, -1);
1125 for (size_t i = 0; i < history_page_ids_.size(); ++i) {
1126 if (minimum_page_id >= 0 && history_page_ids_[i] < minimum_page_id)
1127 continue;
1128 new_history_page_ids.push_back(history_page_ids_[i]);
1129 }
1130 new_history_page_ids.swap(history_page_ids_);
1131
1132 // Update indexes.
1133 history_list_length_ = history_page_ids_.size();
1134 history_list_offset_ = history_list_length_ - 1;
1135}
1136
1137
[email protected]310ebd6302011-10-10 19:06:281138void RenderViewImpl::OnSetInitialFocus(bool reverse) {
initial.commit09911bf2008-07-26 23:55:291139 if (!webview())
1140 return;
[email protected]26aa0482009-09-30 16:55:271141 webview()->setInitialFocus(reverse);
initial.commit09911bf2008-07-26 23:55:291142}
1143
[email protected]54ca3ca892011-06-07 21:14:541144#if defined(OS_MACOSX)
[email protected]310ebd6302011-10-10 19:06:281145void RenderViewImpl::OnSetInLiveResize(bool in_live_resize) {
[email protected]4274b3e2011-08-09 19:09:331146 if (!webview())
1147 return;
1148 if (in_live_resize)
1149 webview()->willStartLiveResize();
1150 else
1151 webview()->willEndLiveResize();
[email protected]54ca3ca892011-06-07 21:14:541152}
1153#endif
1154
[email protected]310ebd6302011-10-10 19:06:281155void RenderViewImpl::OnScrollFocusedEditableNodeIntoRect(
1156 const gfx::Rect& rect) {
[email protected]13a1e4c3c2011-02-03 21:07:091157 WebKit::WebNode node = GetFocusedNode();
1158 if (!node.isNull()) {
1159 if (IsEditableNode(node))
[email protected]333ec8d02011-09-16 18:59:191160 webview()->scrollFocusedNodeIntoRect(rect);
[email protected]9b66f34bf2010-10-27 20:45:511161 }
1162}
1163
initial.commit09911bf2008-07-26 23:55:291164///////////////////////////////////////////////////////////////////////////////
1165
1166// Tell the embedding application that the URL of the active page has changed
[email protected]310ebd6302011-10-10 19:06:281167void RenderViewImpl::UpdateURL(WebFrame* frame) {
[email protected]dd7daa82009-08-10 05:46:451168 WebDataSource* ds = frame->dataSource();
initial.commit09911bf2008-07-26 23:55:291169 DCHECK(ds);
1170
[email protected]726985e22009-06-18 21:09:281171 const WebURLRequest& request = ds->request();
1172 const WebURLRequest& original_request = ds->originalRequest();
1173 const WebURLResponse& response = ds->response();
initial.commit09911bf2008-07-26 23:55:291174
[email protected]007733c2011-11-17 00:34:071175 DocumentState* document_state = DocumentState::FromDataSource(ds);
1176 NavigationState* navigation_state = document_state->navigation_state();
initial.commit09911bf2008-07-26 23:55:291177
1178 ViewHostMsg_FrameNavigate_Params params;
[email protected]726985e22009-06-18 21:09:281179 params.http_status_code = response.httpStatusCode();
initial.commit09911bf2008-07-26 23:55:291180 params.is_post = false;
[email protected]86cd9472012-02-03 19:51:051181 params.post_id = -1;
initial.commit09911bf2008-07-26 23:55:291182 params.page_id = page_id_;
[email protected]dabb0d12010-10-05 12:50:071183 params.frame_id = frame->identifier();
[email protected]6d81b482011-02-22 19:47:191184 params.socket_address.set_host(response.remoteIPAddress().utf8());
1185 params.socket_address.set_port(response.remotePort());
[email protected]b9a7c6d42011-02-25 02:13:031186 params.was_fetched_via_proxy = response.wasFetchedViaProxy();
[email protected]af15bed2010-08-25 21:12:091187 params.was_within_same_page = navigation_state->was_within_same_page();
[email protected]007733c2011-11-17 00:34:071188 if (!document_state->security_info().empty()) {
initial.commit09911bf2008-07-26 23:55:291189 // SSL state specified in the request takes precedence over the one in the
1190 // response.
1191 // So far this is only intended for error pages that are not expected to be
1192 // over ssl, so we should not get any clash.
[email protected]726985e22009-06-18 21:09:281193 DCHECK(response.securityInfo().isEmpty());
[email protected]007733c2011-11-17 00:34:071194 params.security_info = document_state->security_info();
initial.commit09911bf2008-07-26 23:55:291195 } else {
[email protected]726985e22009-06-18 21:09:281196 params.security_info = response.securityInfo();
initial.commit09911bf2008-07-26 23:55:291197 }
1198
1199 // Set the URL to be displayed in the browser UI to the user.
[email protected]69ddf852012-02-21 23:21:311200 params.url = GetLoadingUrl(frame);
initial.commit09911bf2008-07-26 23:55:291201
[email protected]5f9b8712011-11-23 08:55:571202 if (frame->document().baseURL() != params.url)
1203 params.base_url = frame->document().baseURL();
1204
[email protected]726985e22009-06-18 21:09:281205 GetRedirectChain(ds, &params.redirects);
[email protected]d94dc1e2010-03-04 09:29:241206 params.should_update_history = !ds->hasUnreachableURL() &&
[email protected]b7df1b72011-02-10 00:08:041207 !response.isMultipartPayload() && (response.httpStatusCode() != 404);
initial.commit09911bf2008-07-26 23:55:291208
[email protected]007733c2011-11-17 00:34:071209 params.searchable_form_url = document_state->searchable_form_url();
[email protected]ce0e250d2009-10-23 21:00:351210 params.searchable_form_encoding =
[email protected]007733c2011-11-17 00:34:071211 document_state->searchable_form_encoding();
initial.commit09911bf2008-07-26 23:55:291212
1213 const PasswordForm* password_form_data =
[email protected]007733c2011-11-17 00:34:071214 document_state->password_form_data();
initial.commit09911bf2008-07-26 23:55:291215 if (password_form_data)
1216 params.password_form = *password_form_data;
1217
1218 params.gesture = navigation_gesture_;
1219 navigation_gesture_ = NavigationGestureUnknown;
1220
[email protected]0f38dc4552011-02-25 11:24:001221 // Make navigation state a part of the FrameNavigate message so that commited
1222 // entry had it at all times.
1223 const WebHistoryItem& item = frame->currentHistoryItem();
1224 if (!item.isNull()) {
1225 params.content_state = webkit_glue::HistoryItemToString(item);
1226 } else {
1227 params.content_state =
1228 webkit_glue::CreateHistoryStateForURL(GURL(request.url()));
1229 }
1230
[email protected]dd7daa82009-08-10 05:46:451231 if (!frame->parent()) {
initial.commit09911bf2008-07-26 23:55:291232 // Top-level navigation.
1233
[email protected]b75b8292010-10-01 07:28:251234 // Set zoom level, but don't do it for full-page plugin since they don't use
1235 // the same zoom settings.
[email protected]f85f0702010-01-30 09:31:011236 HostZoomLevels::iterator host_zoom =
[email protected]9d797f32010-04-23 07:17:541237 host_zoom_levels_.find(GURL(request.url()));
[email protected]b75b8292010-10-01 07:28:251238 if (webview()->mainFrame()->document().isPluginDocument()) {
1239 // Reset the zoom levels for plugins.
[email protected]b75b8292010-10-01 07:28:251240 webview()->setZoomLevel(false, 0);
[email protected]b75b8292010-10-01 07:28:251241 } else {
1242 if (host_zoom != host_zoom_levels_.end())
[email protected]b75b8292010-10-01 07:28:251243 webview()->setZoomLevel(false, host_zoom->second);
[email protected]b75b8292010-10-01 07:28:251244 }
1245
[email protected]f85f0702010-01-30 09:31:011246 if (host_zoom != host_zoom_levels_.end()) {
[email protected]40bd6582009-12-04 23:49:511247 // This zoom level was merely recorded transiently for this load. We can
1248 // erase it now. If at some point we reload this page, the browser will
1249 // send us a new, up-to-date zoom level.
[email protected]f85f0702010-01-30 09:31:011250 host_zoom_levels_.erase(host_zoom);
[email protected]40bd6582009-12-04 23:49:511251 }
1252
[email protected]b75b8292010-10-01 07:28:251253 // Reset the zoom limits in case a plugin had changed them previously. This
1254 // will also call us back which will cause us to send a message to
1255 // update TabContents.
[email protected]b75b8292010-10-01 07:28:251256 webview()->zoomLimitsChanged(
[email protected]0f083402011-11-22 02:59:011257 WebView::zoomFactorToZoomLevel(content::kMinimumZoomFactor),
1258 WebView::zoomFactorToZoomLevel(content::kMaximumZoomFactor));
[email protected]b75b8292010-10-01 07:28:251259
initial.commit09911bf2008-07-26 23:55:291260 // Update contents MIME type for main frame.
[email protected]9c5645b2009-08-11 03:37:551261 params.contents_mime_type = ds->response().mimeType().utf8();
initial.commit09911bf2008-07-26 23:55:291262
[email protected]daa8c58e2009-06-15 17:21:101263 params.transition = navigation_state->transition_type();
[email protected]2905f742011-10-13 03:51:581264 if (!content::PageTransitionIsMainFrame(params.transition)) {
initial.commit09911bf2008-07-26 23:55:291265 // If the main frame does a load, it should not be reported as a subframe
1266 // navigation. This can occur in the following case:
1267 // 1. You're on a site with frames.
1268 // 2. You do a subframe navigation. This is stored with transition type
1269 // MANUAL_SUBFRAME.
1270 // 3. You navigate to some non-frame site, say, google.com.
1271 // 4. You navigate back to the page from step 2. Since it was initially
1272 // MANUAL_SUBFRAME, it will be that same transition type here.
1273 // We don't want that, because any navigation that changes the toplevel
1274 // frame should be tracked as a toplevel navigation (this allows us to
1275 // update the URL bar, etc).
[email protected]2905f742011-10-13 03:51:581276 params.transition = content::PAGE_TRANSITION_LINK;
initial.commit09911bf2008-07-26 23:55:291277 }
1278
initial.commit09911bf2008-07-26 23:55:291279 // If we have a valid consumed client redirect source,
1280 // the page contained a client redirect (meta refresh, document.loc...),
1281 // so we set the referrer and transition to match.
[email protected]445e1042011-12-03 21:03:151282 if (completed_client_redirect_src_.url.is_valid()) {
1283 DCHECK(completed_client_redirect_src_.url == params.redirects[0]);
initial.commit09911bf2008-07-26 23:55:291284 params.referrer = completed_client_redirect_src_;
[email protected]2905f742011-10-13 03:51:581285 params.transition = static_cast<content::PageTransition>(
1286 params.transition | content::PAGE_TRANSITION_CLIENT_REDIRECT);
initial.commit09911bf2008-07-26 23:55:291287 } else {
1288 // Bug 654101: the referrer will be empty on https->http transitions. It
1289 // would be nice if we could get the real referrer from somewhere.
[email protected]445e1042011-12-03 21:03:151290 params.referrer = Referrer(GURL(
1291 original_request.httpHeaderField(WebString::fromUTF8("Referer"))),
[email protected]b9fd01ba2012-02-28 01:50:401292 GetReferrerPolicyFromRequest(original_request));
initial.commit09911bf2008-07-26 23:55:291293 }
1294
[email protected]726985e22009-06-18 21:09:281295 string16 method = request.httpMethod();
[email protected]86cd9472012-02-03 19:51:051296 if (EqualsASCII(method, "POST")) {
initial.commit09911bf2008-07-26 23:55:291297 params.is_post = true;
[email protected]86cd9472012-02-03 19:51:051298 params.post_id = ExtractPostId(item);
1299 }
initial.commit09911bf2008-07-26 23:55:291300
[email protected]c2a797d2009-09-21 16:46:321301 // Save some histogram data so we can compute the average memory used per
1302 // page load of the glyphs.
1303 UMA_HISTOGRAM_COUNTS_10000("Memory.GlyphPagesPerLoad",
1304 webkit_glue::GetGlyphPageCount());
1305
[email protected]15cf526b2010-02-12 06:33:491306 // This message needs to be sent before any of allowScripts(),
1307 // allowImages(), allowPlugins() is called for the new page, so that when
1308 // these functions send a ViewHostMsg_ContentBlocked message, it arrives
1309 // after the ViewHostMsg_FrameNavigate message.
initial.commit09911bf2008-07-26 23:55:291310 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
1311 } else {
1312 // Subframe navigation: the type depends on whether this navigation
1313 // generated a new session history entry. When they do generate a session
1314 // history entry, it means the user initiated the navigation and we should
1315 // mark it as such. This test checks if this is the first time UpdateURL
1316 // has been called since WillNavigateToURL was called to initiate the load.
1317 if (page_id_ > last_page_id_sent_to_browser_)
[email protected]2905f742011-10-13 03:51:581318 params.transition = content::PAGE_TRANSITION_MANUAL_SUBFRAME;
initial.commit09911bf2008-07-26 23:55:291319 else
[email protected]2905f742011-10-13 03:51:581320 params.transition = content::PAGE_TRANSITION_AUTO_SUBFRAME;
initial.commit09911bf2008-07-26 23:55:291321
initial.commit09911bf2008-07-26 23:55:291322 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
1323 }
1324
1325 last_page_id_sent_to_browser_ =
1326 std::max(last_page_id_sent_to_browser_, page_id_);
1327
1328 // If we end up reusing this WebRequest (for example, due to a #ref click),
[email protected]daa8c58e2009-06-15 17:21:101329 // we don't want the transition type to persist. Just clear it.
[email protected]2905f742011-10-13 03:51:581330 navigation_state->set_transition_type(content::PAGE_TRANSITION_LINK);
initial.commit09911bf2008-07-26 23:55:291331}
1332
1333// Tell the embedding application that the title of the active page has changed
[email protected]310ebd6302011-10-10 19:06:281334void RenderViewImpl::UpdateTitle(WebFrame* frame,
1335 const string16& title,
1336 WebTextDirection title_direction) {
[email protected]a49e10b2011-08-01 23:57:461337 // Ignore all but top level navigations.
1338 if (frame->parent())
1339 return;
1340
1341 string16 shortened_title = title.substr(0, content::kMaxTitleChars);
1342 Send(new ViewHostMsg_UpdateTitle(routing_id_, page_id_, shortened_title,
1343 title_direction));
initial.commit09911bf2008-07-26 23:55:291344}
1345
[email protected]310ebd6302011-10-10 19:06:281346void RenderViewImpl::UpdateEncoding(WebFrame* frame,
1347 const std::string& encoding_name) {
initial.commit09911bf2008-07-26 23:55:291348 // Only update main frame's encoding_name.
[email protected]26aa0482009-09-30 16:55:271349 if (webview()->mainFrame() == frame &&
initial.commit09911bf2008-07-26 23:55:291350 last_encoding_name_ != encoding_name) {
[email protected]e38f40152008-09-12 23:08:301351 // Save the encoding name for later comparing.
initial.commit09911bf2008-07-26 23:55:291352 last_encoding_name_ = encoding_name;
1353
[email protected]e38f40152008-09-12 23:08:301354 Send(new ViewHostMsg_UpdateEncoding(routing_id_, last_encoding_name_));
initial.commit09911bf2008-07-26 23:55:291355 }
1356}
1357
[email protected]e15f680732010-11-23 22:30:201358// Sends the last committed session history state to the browser so it will be
1359// saved before we navigate to a new page. This must be called *before* the
1360// page ID has been updated so we know what it was.
[email protected]310ebd6302011-10-10 19:06:281361void RenderViewImpl::UpdateSessionHistory(WebFrame* frame) {
initial.commit09911bf2008-07-26 23:55:291362 // If we have a valid page ID at this point, then it corresponds to the page
1363 // we are navigating away from. Otherwise, this is the first navigation, so
1364 // there is no past session history to record.
1365 if (page_id_ == -1)
1366 return;
1367
[email protected]ca948a22009-06-25 19:36:171368 const WebHistoryItem& item =
[email protected]26aa0482009-09-30 16:55:271369 webview()->mainFrame()->previousHistoryItem();
[email protected]6459800a2012-03-27 23:57:051370 SendUpdateState(item);
1371}
1372
1373void RenderViewImpl::SendUpdateState(const WebHistoryItem& item) {
[email protected]ca948a22009-06-25 19:36:171374 if (item.isNull())
initial.commit09911bf2008-07-26 23:55:291375 return;
[email protected]ca948a22009-06-25 19:36:171376
[email protected]6459800a2012-03-27 23:57:051377 // Don't send state updates for chrome::kSwappedOutURL.
1378 if (item.urlString() == WebString::fromUTF8(chrome::kSwappedOutURL))
1379 return;
1380
[email protected]ca948a22009-06-25 19:36:171381 Send(new ViewHostMsg_UpdateState(
1382 routing_id_, page_id_, webkit_glue::HistoryItemToString(item)));
initial.commit09911bf2008-07-26 23:55:291383}
1384
[email protected]310ebd6302011-10-10 19:06:281385void RenderViewImpl::OpenURL(WebFrame* frame,
1386 const GURL& url,
[email protected]445e1042011-12-03 21:03:151387 const Referrer& referrer,
[email protected]310ebd6302011-10-10 19:06:281388 WebNavigationPolicy policy) {
[email protected]3d9689372009-09-10 04:29:171389 Send(new ViewHostMsg_OpenURL(
[email protected]ae5184d62011-10-06 19:25:581390 routing_id_,
1391 url,
1392 referrer,
1393 NavigationPolicyToDisposition(policy),
1394 frame->identifier()));
[email protected]3d9689372009-09-10 04:29:171395}
1396
[email protected]79dbc662009-09-04 05:42:511397// WebViewDelegate ------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291398
[email protected]310ebd6302011-10-10 19:06:281399void RenderViewImpl::LoadNavigationErrorPage(
1400 WebFrame* frame,
1401 const WebURLRequest& failed_request,
1402 const WebURLError& error,
1403 const std::string& html,
1404 bool replace) {
[email protected]d7b175e2011-10-11 15:31:581405 std::string alt_html;
1406 const std::string* error_html;
1407
1408 if (!html.empty()) {
1409 error_html = &html;
1410 } else {
1411 content::GetContentClient()->renderer()->GetNavigationErrorStrings(
1412 failed_request, error, &alt_html, NULL);
1413 error_html = &alt_html;
1414 }
1415
1416 frame->loadHTMLString(*error_html,
[email protected]144143c2010-10-28 08:17:361417 GURL(chrome::kUnreachableWebDataURL),
[email protected]21d61e52011-03-18 19:08:251418 error.unreachableURL,
[email protected]e6f546c32009-07-01 17:12:551419 replace);
initial.commit09911bf2008-07-26 23:55:291420}
1421
[email protected]269f86d2011-12-07 02:43:471422bool RenderViewImpl::RunJavaScriptMessage(ui::JavascriptMessageType type,
[email protected]310ebd6302011-10-10 19:06:281423 const string16& message,
1424 const string16& default_value,
1425 const GURL& frame_url,
1426 string16* result) {
initial.commit09911bf2008-07-26 23:55:291427 bool success = false;
[email protected]4f5ce842011-05-27 19:34:411428 string16 result_temp;
initial.commit09911bf2008-07-26 23:55:291429 if (!result)
1430 result = &result_temp;
initial.commit09911bf2008-07-26 23:55:291431
[email protected]12636df2009-09-28 22:32:211432 SendAndRunNestedMessageLoop(new ViewHostMsg_RunJavaScriptMessage(
1433 routing_id_, message, default_value, frame_url, type, &success, result));
initial.commit09911bf2008-07-26 23:55:291434 return success;
1435}
1436
[email protected]310ebd6302011-10-10 19:06:281437bool RenderViewImpl::SendAndRunNestedMessageLoop(IPC::SyncMessage* message) {
[email protected]c1f50aa2010-02-18 03:46:571438 // Before WebKit asks us to show an alert (etc.), it takes care of doing the
1439 // equivalent of WebView::willEnterModalLoop. In the case of showModalDialog
1440 // it is particularly important that we do not call willEnterModalLoop as
1441 // that would defer resource loads for the dialog itself.
[email protected]f1a29a02011-10-06 23:08:441442 if (RenderThreadImpl::current()) // Will be NULL during unit tests.
1443 RenderThreadImpl::current()->DoNotNotifyWebKitOfModalLoop();
[email protected]c1f50aa2010-02-18 03:46:571444
1445 message->EnableMessagePumping(); // Runs a nested message loop.
1446 return Send(message);
1447}
1448
[email protected]48c9cf2d2009-09-16 16:47:521449// WebKit::WebViewClient ------------------------------------------------------
1450
[email protected]916dfb62012-03-05 03:39:371451WebView* RenderViewImpl::createView(
1452 WebFrame* creator,
1453 const WebURLRequest& request,
1454 const WebWindowFeatures& features,
1455 const WebString& frame_name,
1456 WebNavigationPolicy policy) {
[email protected]48c9cf2d2009-09-16 16:47:521457 // Check to make sure we aren't overloading on popups.
1458 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups)
1459 return NULL;
1460
[email protected]8ab04652010-06-12 02:47:261461 ViewHostMsg_CreateWindow_Params params;
1462 params.opener_id = routing_id_;
1463 params.user_gesture = creator->isProcessingUserGesture();
1464 params.window_container_type = WindowFeaturesToContainerType(features);
1465 params.session_storage_namespace_id = session_storage_namespace_id_;
1466 params.frame_name = frame_name;
[email protected]41e65502011-01-21 09:29:111467 params.opener_frame_id = creator->identifier();
[email protected]b6cb3a842011-06-24 18:28:411468 params.opener_url = creator->document().url();
1469 params.opener_security_origin =
1470 creator->document().securityOrigin().toString().utf8();
[email protected]f92ce2b2012-03-06 18:02:591471 params.opener_suppressed = creator->willSuppressOpenerInNewFrame();
1472 params.disposition = NavigationPolicyToDisposition(policy);
[email protected]41e65502011-01-21 09:29:111473 if (!request.isNull())
1474 params.target_url = request.url();
[email protected]8ab04652010-06-12 02:47:261475
[email protected]48c9cf2d2009-09-16 16:47:521476 int32 routing_id = MSG_ROUTING_NONE;
[email protected]9f4f3322012-01-18 22:29:561477 int32 surface_id = 0;
[email protected]4e6419c2010-01-15 04:50:341478 int64 cloned_session_storage_namespace_id;
[email protected]48c9cf2d2009-09-16 16:47:521479
[email protected]380244092011-10-07 17:26:271480 RenderThread::Get()->Send(
[email protected]8ab04652010-06-12 02:47:261481 new ViewHostMsg_CreateWindow(params,
1482 &routing_id,
[email protected]9f4f3322012-01-18 22:29:561483 &surface_id,
[email protected]8ab04652010-06-12 02:47:261484 &cloned_session_storage_namespace_id));
[email protected]12636df2009-09-28 22:32:211485 if (routing_id == MSG_ROUTING_NONE)
[email protected]48c9cf2d2009-09-16 16:47:521486 return NULL;
[email protected]48c9cf2d2009-09-16 16:47:521487
[email protected]8cca3da2012-03-20 08:26:341488 // TODO(fsamuel): The host renderer needs to be able to control whether
1489 // the guest renderer is allowed to do this or not. This current
1490 // behavior is not well defined.
[email protected]310ebd6302011-10-10 19:06:281491 RenderViewImpl* view = RenderViewImpl::Create(
1492 0,
1493 routing_id_,
1494 renderer_preferences_,
1495 webkit_preferences_,
1496 shared_popup_counter_,
1497 routing_id,
[email protected]9f4f3322012-01-18 22:29:561498 surface_id,
[email protected]310ebd6302011-10-10 19:06:281499 cloned_session_storage_namespace_id,
[email protected]74ce1ad2011-12-16 21:51:461500 frame_name,
[email protected]6fd35b72012-03-01 19:46:411501 1,
[email protected]8cca3da2012-03-20 08:26:341502 screen_info_,
1503 guest_);
[email protected]8ab04652010-06-12 02:47:261504 view->opened_by_user_gesture_ = params.user_gesture;
[email protected]48c9cf2d2009-09-16 16:47:521505
[email protected]007a848b2009-10-26 15:55:461506 // Record whether the creator frame is trying to suppress the opener field.
[email protected]f92ce2b2012-03-06 18:02:591507 view->opener_suppressed_ = params.opener_suppressed;
[email protected]007a848b2009-10-26 15:55:461508
[email protected]48c9cf2d2009-09-16 16:47:521509 // Record the security origin of the creator.
[email protected]b6cb3a842011-06-24 18:28:411510 GURL creator_url(creator->document().securityOrigin().toString().utf8());
[email protected]48c9cf2d2009-09-16 16:47:521511 if (!creator_url.is_valid() || !creator_url.IsStandard())
1512 creator_url = GURL();
1513 view->creator_url_ = creator_url;
1514
1515 // Copy over the alternate error page URL so we can have alt error pages in
1516 // the new render view (we don't need the browser to send the URL back down).
1517 view->alternate_error_page_url_ = alternate_error_page_url_;
1518
1519 return view->webview();
1520}
1521
[email protected]310ebd6302011-10-10 19:06:281522WebWidget* RenderViewImpl::createPopupMenu(WebKit::WebPopupType popup_type) {
[email protected]6fd35b72012-03-01 19:46:411523 RenderWidget* widget =
1524 RenderWidget::Create(routing_id_, popup_type, screen_info_);
[email protected]48c9cf2d2009-09-16 16:47:521525 return widget->webwidget();
1526}
1527
[email protected]310ebd6302011-10-10 19:06:281528WebWidget* RenderViewImpl::createPopupMenu(const WebPopupMenuInfo& info) {
[email protected]8de12d942010-11-17 20:42:441529 // TODO(jcivelli): Remove this deprecated method when its been removed from
1530 // the WebViewClient interface. It's been replaced by
1531 // createExternalPopupMenu.
1532 NOTREACHED();
1533 return NULL;
[email protected]48c9cf2d2009-09-16 16:47:521534}
1535
[email protected]310ebd6302011-10-10 19:06:281536WebExternalPopupMenu* RenderViewImpl::createExternalPopupMenu(
[email protected]caf706f2010-10-26 17:54:081537 const WebPopupMenuInfo& popup_menu_info,
1538 WebExternalPopupMenuClient* popup_menu_client) {
1539 DCHECK(!external_popup_menu_.get());
1540 external_popup_menu_.reset(
1541 new ExternalPopupMenu(this, popup_menu_info, popup_menu_client));
1542 return external_popup_menu_.get();
1543}
1544
[email protected]310ebd6302011-10-10 19:06:281545RenderWidgetFullscreenPepper* RenderViewImpl::CreatePepperFullscreenContainer(
[email protected]0bd753682010-12-16 18:15:521546 webkit::ppapi::PluginInstance* plugin) {
[email protected]d91233b7e2011-03-29 20:33:531547 GURL active_url;
[email protected]d91ddfc2011-04-07 18:33:421548 if (webview() && webview()->mainFrame())
[email protected]b6cb3a842011-06-24 18:28:411549 active_url = GURL(webview()->mainFrame()->document().url());
[email protected]d91233b7e2011-03-29 20:33:531550 RenderWidgetFullscreenPepper* widget = RenderWidgetFullscreenPepper::Create(
[email protected]380244092011-10-07 17:26:271551 routing_id_, plugin, active_url);
[email protected]79c7bed2010-09-14 22:28:391552 widget->show(WebKit::WebNavigationPolicyIgnore);
[email protected]92abcb832011-01-06 20:39:561553 return widget;
[email protected]79c7bed2010-09-14 22:28:391554}
1555
[email protected]310ebd6302011-10-10 19:06:281556WebStorageNamespace* RenderViewImpl::createSessionStorageNamespace(
1557 unsigned quota) {
[email protected]c09f12c62012-03-24 00:03:561558#ifdef ENABLE_NEW_DOM_STORAGE_BACKEND
1559 CHECK(session_storage_namespace_id_ != kInvalidSessionStorageNamespaceId);
1560 return new RendererWebStorageNamespaceImpl(DOM_STORAGE_SESSION,
1561 session_storage_namespace_id_);
1562#else
[email protected]bd92c3a2010-01-13 05:02:341563 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess))
[email protected]68c50e52010-05-12 11:14:391564 return WebStorageNamespace::createSessionStorageNamespace(quota);
[email protected]59afea12010-01-20 04:48:291565 CHECK(session_storage_namespace_id_ != kInvalidSessionStorageNamespaceId);
1566 return new RendererWebStorageNamespaceImpl(DOM_STORAGE_SESSION,
1567 session_storage_namespace_id_);
[email protected]c09f12c62012-03-24 00:03:561568#endif
[email protected]bd92c3a2010-01-13 05:02:341569}
1570
[email protected]7e8b4d12012-01-20 23:39:511571WebGraphicsContext3D* RenderViewImpl::createGraphicsContext3D(
[email protected]40ec0c12012-03-08 12:34:401572 const WebGraphicsContext3D::Attributes& attributes) {
[email protected]7e8b4d12012-01-20 23:39:511573 if (!webview())
1574 return NULL;
1575 // The WebGraphicsContext3DInProcessImpl code path is used for
1576 // layout tests (though not through this code) as well as for
1577 // debugging and bringing up new ports.
[email protected]7e8b4d12012-01-20 23:39:511578 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessWebGL)) {
[email protected]56200f012012-02-03 23:13:571579 return webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWebView(
[email protected]29dea0e2012-03-16 01:46:581580 attributes, true);
[email protected]7e8b4d12012-01-20 23:39:511581 } else {
[email protected]b3e83de2012-02-07 03:33:281582 GURL url;
1583 if (webview()->mainFrame())
1584 url = GURL(webview()->mainFrame()->document().url());
1585
[email protected]b3e83de2012-02-07 03:33:281586 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
1587 new WebGraphicsContext3DCommandBufferImpl(
[email protected]29dea0e2012-03-16 01:46:581588 surface_id(), url, RenderThreadImpl::current(), AsWeakPtr()));
[email protected]b3e83de2012-02-07 03:33:281589
1590 if (!context->Initialize(attributes))
[email protected]56200f012012-02-03 23:13:571591 return NULL;
[email protected]d0fb8a72012-03-10 18:54:521592 context_is_web_graphics_context_3d_command_buffer_impl_ = true;
[email protected]56200f012012-02-03 23:13:571593 return context.release();
[email protected]7e8b4d12012-01-20 23:39:511594 }
[email protected]7e8b4d12012-01-20 23:39:511595}
1596
[email protected]310ebd6302011-10-10 19:06:281597void RenderViewImpl::didAddMessageToConsole(
[email protected]48c9cf2d2009-09-16 16:47:521598 const WebConsoleMessage& message, const WebString& source_name,
1599 unsigned source_line) {
[email protected]d09df4b2011-04-11 19:01:081600 logging::LogSeverity log_severity = logging::LOG_VERBOSE;
[email protected]f7eb0a392011-07-12 10:19:511601 switch (message.level) {
[email protected]d09df4b2011-04-11 19:01:081602 case WebConsoleMessage::LevelTip:
1603 log_severity = logging::LOG_VERBOSE;
1604 break;
1605 case WebConsoleMessage::LevelLog:
1606 log_severity = logging::LOG_INFO;
1607 break;
1608 case WebConsoleMessage::LevelWarning:
1609 log_severity = logging::LOG_WARNING;
1610 break;
1611 case WebConsoleMessage::LevelError:
1612 log_severity = logging::LOG_ERROR;
1613 break;
1614 default:
1615 NOTREACHED();
1616 }
1617
[email protected]48c9cf2d2009-09-16 16:47:521618 Send(new ViewHostMsg_AddMessageToConsole(routing_id_,
[email protected]d09df4b2011-04-11 19:01:081619 static_cast<int32>(log_severity),
[email protected]aa21d2a2011-08-08 23:56:311620 message.text,
[email protected]48c9cf2d2009-09-16 16:47:521621 static_cast<int32>(source_line),
[email protected]aa21d2a2011-08-08 23:56:311622 source_name));
[email protected]48c9cf2d2009-09-16 16:47:521623}
1624
[email protected]310ebd6302011-10-10 19:06:281625void RenderViewImpl::printPage(WebFrame* frame) {
[email protected]d91ddfc2011-04-07 18:33:421626 FOR_EACH_OBSERVER(RenderViewObserver, observers_, PrintPage(frame));
[email protected]48c9cf2d2009-09-16 16:47:521627}
1628
[email protected]310ebd6302011-10-10 19:06:281629WebKit::WebNotificationPresenter* RenderViewImpl::notificationPresenter() {
[email protected]676126f72011-01-15 00:03:511630 return notification_provider_;
[email protected]3354d3e2010-06-10 19:53:021631}
1632
[email protected]310ebd6302011-10-10 19:06:281633bool RenderViewImpl::enumerateChosenDirectory(
[email protected]8a58c1c2011-04-19 18:40:121634 const WebString& path,
1635 WebFileChooserCompletion* chooser_completion) {
1636 int id = enumeration_completion_id_++;
1637 enumeration_completions_[id] = chooser_completion;
1638 return Send(new ViewHostMsg_EnumerateDirectory(
1639 routing_id_,
1640 id,
1641 webkit_glue::WebStringToFilePath(path)));
1642}
1643
[email protected]310ebd6302011-10-10 19:06:281644void RenderViewImpl::didStartLoading() {
[email protected]48c9cf2d2009-09-16 16:47:521645 if (is_loading_) {
[email protected]511754da2012-01-24 20:48:141646 DVLOG(1) << "didStartLoading called while loading";
[email protected]48c9cf2d2009-09-16 16:47:521647 return;
1648 }
1649
1650 is_loading_ = true;
[email protected]48c9cf2d2009-09-16 16:47:521651
1652 Send(new ViewHostMsg_DidStartLoading(routing_id_));
[email protected]93b9d692011-04-13 00:44:311653
1654 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStartLoading());
[email protected]48c9cf2d2009-09-16 16:47:521655}
1656
[email protected]310ebd6302011-10-10 19:06:281657void RenderViewImpl::didStopLoading() {
[email protected]48c9cf2d2009-09-16 16:47:521658 if (!is_loading_) {
[email protected]511754da2012-01-24 20:48:141659 DVLOG(1) << "DidStopLoading called while not loading";
[email protected]48c9cf2d2009-09-16 16:47:521660 return;
1661 }
1662
1663 is_loading_ = false;
1664
1665 // NOTE: For now we're doing the safest thing, and sending out notification
1666 // when done loading. This currently isn't an issue as the favicon is only
1667 // displayed when done loading. Ideally we would send notification when
1668 // finished parsing the head, but webkit doesn't support that yet.
1669 // The feed discovery code would also benefit from access to the head.
[email protected]48c9cf2d2009-09-16 16:47:521670 Send(new ViewHostMsg_DidStopLoading(routing_id_));
1671
[email protected]90109412010-12-15 17:14:241672 if (load_progress_tracker_ != NULL)
1673 load_progress_tracker_->DidStopLoading();
1674
[email protected]93b9d692011-04-13 00:44:311675 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStopLoading());
[email protected]48c9cf2d2009-09-16 16:47:521676}
1677
[email protected]310ebd6302011-10-10 19:06:281678void RenderViewImpl::didChangeLoadProgress(WebFrame* frame,
1679 double load_progress) {
[email protected]90109412010-12-15 17:14:241680 if (load_progress_tracker_ != NULL)
1681 load_progress_tracker_->DidChangeLoadProgress(frame, load_progress);
1682}
1683
[email protected]310ebd6302011-10-10 19:06:281684bool RenderViewImpl::isSmartInsertDeleteEnabled() {
[email protected]f55039a2010-02-17 14:12:061685#if defined(OS_MACOSX)
1686 return true;
1687#else
1688 return false;
1689#endif
1690}
1691
[email protected]310ebd6302011-10-10 19:06:281692bool RenderViewImpl::isSelectTrailingWhitespaceEnabled() {
[email protected]04fc9482009-09-18 22:13:031693#if defined(OS_WIN)
1694 return true;
1695#else
1696 return false;
1697#endif
1698}
1699
[email protected]310ebd6302011-10-10 19:06:281700void RenderViewImpl::didChangeSelection(bool is_empty_selection) {
[email protected]4fb60142011-08-09 02:22:081701 if (!handling_input_event_ && !handling_select_range_)
[email protected]04fc9482009-09-18 22:13:031702 return;
[email protected]4fb60142011-08-09 02:22:081703 handling_select_range_ = false;
[email protected]d4cff272011-05-02 15:46:011704
[email protected]b781ff282011-08-20 06:19:361705 SyncSelectionIfRequired();
[email protected]04fc9482009-09-18 22:13:031706}
1707
[email protected]310ebd6302011-10-10 19:06:281708void RenderViewImpl::didExecuteCommand(const WebString& command_name) {
[email protected]afe3a1672009-11-17 19:04:121709 const std::string& name = UTF16ToUTF8(command_name);
1710 if (StartsWithASCII(name, "Move", true) ||
1711 StartsWithASCII(name, "Insert", true) ||
1712 StartsWithASCII(name, "Delete", true))
[email protected]04fc9482009-09-18 22:13:031713 return;
[email protected]f1a29a02011-10-06 23:08:441714 RenderThreadImpl::current()->RecordUserMetrics(name);
[email protected]04fc9482009-09-18 22:13:031715}
1716
[email protected]310ebd6302011-10-10 19:06:281717bool RenderViewImpl::handleCurrentKeyboardEvent() {
[email protected]b2528b72009-09-24 06:57:101718 if (edit_commands_.empty())
1719 return false;
1720
[email protected]26aa0482009-09-30 16:55:271721 WebFrame* frame = webview()->focusedFrame();
[email protected]b2528b72009-09-24 06:57:101722 if (!frame)
1723 return false;
1724
1725 EditCommands::iterator it = edit_commands_.begin();
1726 EditCommands::iterator end = edit_commands_.end();
1727
[email protected]507b33ea2009-09-29 03:56:511728 bool did_execute_command = false;
[email protected]b2528b72009-09-24 06:57:101729 for (; it != end; ++it) {
[email protected]e6e15012009-09-30 14:59:331730 // In gtk and cocoa, it's possible to bind multiple edit commands to one
1731 // key (but it's the exception). Once one edit command is not executed, it
1732 // seems safest to not execute the rest.
[email protected]b2528b72009-09-24 06:57:101733 if (!frame->executeCommand(WebString::fromUTF8(it->name),
1734 WebString::fromUTF8(it->value)))
1735 break;
[email protected]507b33ea2009-09-29 03:56:511736 did_execute_command = true;
[email protected]b2528b72009-09-24 06:57:101737 }
1738
[email protected]507b33ea2009-09-29 03:56:511739 return did_execute_command;
[email protected]b2528b72009-09-24 06:57:101740}
1741
[email protected]da8543762012-03-20 08:52:201742WebKit::WebColorChooser* RenderViewImpl::createColorChooser(
1743 WebKit::WebColorChooserClient* client,
1744 const WebKit::WebColor& initial_color) {
1745 RendererWebColorChooserImpl* color_chooser =
1746 new RendererWebColorChooserImpl(this, client);
1747 color_chooser->Open(static_cast<SkColor>(initial_color));
1748 return color_chooser;
1749}
1750
[email protected]310ebd6302011-10-10 19:06:281751bool RenderViewImpl::runFileChooser(
[email protected]01178b52010-01-15 06:59:351752 const WebKit::WebFileChooserParams& params,
[email protected]cdaf8d02010-03-30 19:52:471753 WebFileChooserCompletion* chooser_completion) {
[email protected]7ef03e02010-10-23 11:58:351754 // Do not open the file dialog in a hidden RenderView.
1755 if (is_hidden())
1756 return false;
[email protected]8caadeb2011-11-22 02:45:231757 content::FileChooserParams ipc_params;
[email protected]b5977a0c2010-08-24 19:46:261758 if (params.directory)
[email protected]8caadeb2011-11-22 02:45:231759 ipc_params.mode = content::FileChooserParams::OpenFolder;
[email protected]b5977a0c2010-08-24 19:46:261760 else if (params.multiSelect)
[email protected]8caadeb2011-11-22 02:45:231761 ipc_params.mode = content::FileChooserParams::OpenMultiple;
[email protected]459fba82011-10-13 02:48:501762 else if (params.saveAs)
[email protected]8caadeb2011-11-22 02:45:231763 ipc_params.mode = content::FileChooserParams::Save;
[email protected]b5977a0c2010-08-24 19:46:261764 else
[email protected]8caadeb2011-11-22 02:45:231765 ipc_params.mode = content::FileChooserParams::Open;
[email protected]cdaf8d02010-03-30 19:52:471766 ipc_params.title = params.title;
1767 ipc_params.default_file_name =
1768 webkit_glue::WebStringToFilePath(params.initialValue);
[email protected]3314c2b12011-11-02 08:05:461769 ipc_params.accept_types.reserve(params.acceptMIMETypes.size());
1770 for (size_t i = 0; i < params.acceptMIMETypes.size(); ++i)
1771 ipc_params.accept_types.push_back(params.acceptMIMETypes[i]);
[email protected]cdaf8d02010-03-30 19:52:471772
1773 return ScheduleFileChooser(ipc_params, chooser_completion);
[email protected]a1128322009-10-06 18:38:461774}
1775
[email protected]269f86d2011-12-07 02:43:471776void RenderViewImpl::runModalAlertDialog(WebFrame* frame,
1777 const WebString& message) {
1778 RunJavaScriptMessage(ui::JAVASCRIPT_MESSAGE_TYPE_ALERT,
[email protected]4f5ce842011-05-27 19:34:411779 message,
1780 string16(),
[email protected]b6cb3a842011-06-24 18:28:411781 frame->document().url(),
[email protected]48c9cf2d2009-09-16 16:47:521782 NULL);
1783}
1784
[email protected]269f86d2011-12-07 02:43:471785bool RenderViewImpl::runModalConfirmDialog(WebFrame* frame,
1786 const WebString& message) {
1787 return RunJavaScriptMessage(ui::JAVASCRIPT_MESSAGE_TYPE_CONFIRM,
[email protected]4f5ce842011-05-27 19:34:411788 message,
1789 string16(),
[email protected]b6cb3a842011-06-24 18:28:411790 frame->document().url(),
[email protected]48c9cf2d2009-09-16 16:47:521791 NULL);
1792}
1793
[email protected]269f86d2011-12-07 02:43:471794bool RenderViewImpl::runModalPromptDialog(WebFrame* frame,
1795 const WebString& message,
1796 const WebString& default_value,
1797 WebString* actual_value) {
[email protected]4f5ce842011-05-27 19:34:411798 string16 result;
[email protected]269f86d2011-12-07 02:43:471799 bool ok = RunJavaScriptMessage(ui::JAVASCRIPT_MESSAGE_TYPE_PROMPT,
[email protected]4f5ce842011-05-27 19:34:411800 message,
1801 default_value,
[email protected]b6cb3a842011-06-24 18:28:411802 frame->document().url(),
[email protected]48c9cf2d2009-09-16 16:47:521803 &result);
1804 if (ok)
[email protected]4f5ce842011-05-27 19:34:411805 actual_value->assign(result);
[email protected]48c9cf2d2009-09-16 16:47:521806 return ok;
1807}
1808
[email protected]310ebd6302011-10-10 19:06:281809bool RenderViewImpl::runModalBeforeUnloadDialog(
[email protected]48c9cf2d2009-09-16 16:47:521810 WebFrame* frame, const WebString& message) {
[email protected]992db4c2011-05-12 15:37:151811 // If we are swapping out, we have already run the beforeunload handler.
1812 // TODO(creis): Fix OnSwapOut to clear the frame without running beforeunload
1813 // at all, to avoid running it twice.
1814 if (is_swapped_out_)
1815 return true;
1816
[email protected]3b3301f62012-02-29 04:32:321817 bool is_reload = false;
1818 WebDataSource* ds = frame->provisionalDataSource();
1819 if (ds)
1820 is_reload = (ds->navigationType() == WebKit::WebNavigationTypeReload);
1821
[email protected]48c9cf2d2009-09-16 16:47:521822 bool success = false;
1823 // This is an ignored return value, but is included so we can accept the same
1824 // response as RunJavaScriptMessage.
[email protected]4f5ce842011-05-27 19:34:411825 string16 ignored_result;
[email protected]12636df2009-09-28 22:32:211826 SendAndRunNestedMessageLoop(new ViewHostMsg_RunBeforeUnloadConfirm(
[email protected]3b3301f62012-02-29 04:32:321827 routing_id_, frame->document().url(), message, is_reload,
[email protected]b6cb3a842011-06-24 18:28:411828 &success, &ignored_result));
[email protected]48c9cf2d2009-09-16 16:47:521829 return success;
1830}
1831
[email protected]310ebd6302011-10-10 19:06:281832void RenderViewImpl::showContextMenu(
[email protected]79e37442009-10-09 18:17:441833 WebFrame* frame, const WebContextMenuData& data) {
[email protected]35be7ec2012-02-12 20:42:511834 content::ContextMenuParams params(data);
[email protected]7fcd9b72011-07-27 16:52:371835
1836 // frame is NULL if invoked by BlockedPlugin.
1837 if (frame)
1838 params.frame_id = frame->identifier();
1839
[email protected]db803aae2011-03-05 02:00:421840 // Serializing a GURL longer than content::kMaxURLChars will fail, so don't do
[email protected]216932c2010-08-26 21:44:271841 // it. We replace it with an empty GURL so the appropriate items are disabled
1842 // in the context menu.
1843 // TODO(jcivelli): http://crbug.com/45160 This prevents us from saving large
1844 // data encoded images. We should have a way to save them.
[email protected]db803aae2011-03-05 02:00:421845 if (params.src_url.spec().size() > content::kMaxURLChars)
[email protected]216932c2010-08-26 21:44:271846 params.src_url = GURL();
[email protected]521b2482011-01-15 00:10:101847 context_menu_node_ = data.node;
[email protected]c27324b2009-11-19 22:44:291848 Send(new ViewHostMsg_ContextMenu(routing_id_, params));
[email protected]79e37442009-10-09 18:17:441849}
1850
[email protected]310ebd6302011-10-10 19:06:281851void RenderViewImpl::setStatusText(const WebString& text) {
[email protected]48c9cf2d2009-09-16 16:47:521852}
1853
[email protected]310ebd6302011-10-10 19:06:281854void RenderViewImpl::UpdateTargetURL(const GURL& url,
1855 const GURL& fallback_url) {
[email protected]aa6b90b32010-04-26 15:49:581856 GURL latest_url = url.is_empty() ? fallback_url : url;
[email protected]48c9cf2d2009-09-16 16:47:521857 if (latest_url == target_url_)
1858 return;
[email protected]163f8242009-10-30 20:19:551859
[email protected]48c9cf2d2009-09-16 16:47:521860 // Tell the browser to display a destination link.
1861 if (target_url_status_ == TARGET_INFLIGHT ||
1862 target_url_status_ == TARGET_PENDING) {
1863 // If we have a request in-flight, save the URL to be sent when we
1864 // receive an ACK to the in-flight request. We can happily overwrite
1865 // any existing pending sends.
1866 pending_target_url_ = latest_url;
1867 target_url_status_ = TARGET_PENDING;
1868 } else {
[email protected]c85f0212011-11-04 16:54:411869 // URLs larger than |content::kMaxURLChars| cannot be sent through IPC -
1870 // see |ParamTraits<GURL>|.
1871 if (latest_url.possibly_invalid_spec().size() > content::kMaxURLChars)
1872 latest_url = GURL();
[email protected]48c9cf2d2009-09-16 16:47:521873 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_, latest_url));
1874 target_url_ = latest_url;
1875 target_url_status_ = TARGET_INFLIGHT;
1876 }
1877}
1878
[email protected]310ebd6302011-10-10 19:06:281879void RenderViewImpl::StartNavStateSyncTimerIfNecessary() {
[email protected]882daa92009-11-05 16:31:311880 int delay;
1881 if (send_content_state_immediately_)
1882 delay = 0;
1883 else if (is_hidden())
1884 delay = kDelaySecondsForContentStateSyncHidden;
1885 else
1886 delay = kDelaySecondsForContentStateSync;
1887
1888 if (nav_state_sync_timer_.IsRunning()) {
1889 // The timer is already running. If the delay of the timer maches the amount
1890 // we want to delay by, then return. Otherwise stop the timer so that it
1891 // gets started with the right delay.
1892 if (nav_state_sync_timer_.GetCurrentDelay().InSeconds() == delay)
1893 return;
1894 nav_state_sync_timer_.Stop();
1895 }
1896
[email protected]d323a172011-09-02 18:23:021897 nav_state_sync_timer_.Start(FROM_HERE, TimeDelta::FromSeconds(delay), this,
[email protected]310ebd6302011-10-10 19:06:281898 &RenderViewImpl::SyncNavigationState);
[email protected]882daa92009-11-05 16:31:311899}
1900
[email protected]310ebd6302011-10-10 19:06:281901void RenderViewImpl::setMouseOverURL(const WebURL& url) {
[email protected]163f8242009-10-30 20:19:551902 mouse_over_url_ = GURL(url);
1903 UpdateTargetURL(mouse_over_url_, focus_url_);
1904}
1905
[email protected]310ebd6302011-10-10 19:06:281906void RenderViewImpl::setKeyboardFocusURL(const WebURL& url) {
[email protected]163f8242009-10-30 20:19:551907 focus_url_ = GURL(url);
1908 UpdateTargetURL(focus_url_, mouse_over_url_);
1909}
1910
[email protected]310ebd6302011-10-10 19:06:281911void RenderViewImpl::startDragging(const WebDragData& data,
1912 WebDragOperationsMask mask,
1913 const WebImage& image,
1914 const WebPoint& imageOffset) {
[email protected]c27ae592010-03-18 15:24:411915#if WEBKIT_USING_SKIA
1916 SkBitmap bitmap(image.getSkBitmap());
1917#elif WEBKIT_USING_CG
[email protected]78043bdd2010-04-05 18:45:331918 SkBitmap bitmap = gfx::CGImageToSkBitmap(image.getCGImageRef());
[email protected]c27ae592010-03-18 15:24:411919#endif
1920
[email protected]59f4f2fa2011-03-23 01:00:551921 Send(new DragHostMsg_StartDragging(routing_id_,
[email protected]48c9cf2d2009-09-16 16:47:521922 WebDropData(data),
[email protected]c27ae592010-03-18 15:24:411923 mask,
1924 bitmap,
1925 imageOffset));
[email protected]48c9cf2d2009-09-16 16:47:521926}
1927
[email protected]310ebd6302011-10-10 19:06:281928bool RenderViewImpl::acceptsLoadDrops() {
[email protected]28b92df2009-09-25 17:35:451929 return renderer_preferences_.can_accept_load_drops;
1930}
1931
[email protected]310ebd6302011-10-10 19:06:281932void RenderViewImpl::focusNext() {
[email protected]48c9cf2d2009-09-16 16:47:521933 Send(new ViewHostMsg_TakeFocus(routing_id_, false));
1934}
1935
[email protected]310ebd6302011-10-10 19:06:281936void RenderViewImpl::focusPrevious() {
[email protected]48c9cf2d2009-09-16 16:47:521937 Send(new ViewHostMsg_TakeFocus(routing_id_, true));
1938}
1939
[email protected]310ebd6302011-10-10 19:06:281940void RenderViewImpl::focusedNodeChanged(const WebNode& node) {
[email protected]9b66f34bf2010-10-27 20:45:511941 Send(new ViewHostMsg_FocusedNodeChanged(routing_id_, IsEditableNode(node)));
[email protected]a4b103b2010-10-05 18:46:071942
[email protected]38b592902011-04-16 02:08:421943 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FocusedNodeChanged(node));
[email protected]08e9e132010-06-01 16:58:491944}
1945
[email protected]169d4282011-11-30 19:33:591946void RenderViewImpl::didUpdateLayout() {
1947 // We don't always want to set up a timer, only if we've been put in that
1948 // mode by getting a |ViewMsg_EnablePreferredSizeChangedMode|
1949 // message.
1950 if (!send_preferred_size_changes_ || !webview())
1951 return;
1952
1953 if (check_preferred_size_timer_.IsRunning())
1954 return;
1955 check_preferred_size_timer_.Start(FROM_HERE,
1956 TimeDelta::FromMilliseconds(0), this,
1957 &RenderViewImpl::CheckPreferredSize);
1958}
1959
[email protected]310ebd6302011-10-10 19:06:281960void RenderViewImpl::navigateBackForwardSoon(int offset) {
[email protected]48c9cf2d2009-09-16 16:47:521961 Send(new ViewHostMsg_GoToEntryAtOffset(routing_id_, offset));
1962}
1963
[email protected]310ebd6302011-10-10 19:06:281964int RenderViewImpl::historyBackListCount() {
[email protected]3cc72b12010-03-18 23:03:001965 return history_list_offset_ < 0 ? 0 : history_list_offset_;
[email protected]48c9cf2d2009-09-16 16:47:521966}
1967
[email protected]310ebd6302011-10-10 19:06:281968int RenderViewImpl::historyForwardListCount() {
[email protected]3cc72b12010-03-18 23:03:001969 return history_list_length_ - historyBackListCount() - 1;
[email protected]48c9cf2d2009-09-16 16:47:521970}
1971
[email protected]310ebd6302011-10-10 19:06:281972void RenderViewImpl::postAccessibilityNotification(
[email protected]063afcb2011-09-29 07:54:321973 const WebAccessibilityObject& obj,
1974 WebAccessibilityNotification notification) {
1975 renderer_accessibility_->PostAccessibilityNotification(obj, notification);
1976}
1977
[email protected]310ebd6302011-10-10 19:06:281978void RenderViewImpl::didUpdateInspectorSetting(const WebString& key,
[email protected]c4e98902010-06-01 10:20:141979 const WebString& value) {
1980 Send(new ViewHostMsg_UpdateInspectorSetting(routing_id_,
1981 key.utf8(),
1982 value.utf8()));
[email protected]8922e1f2009-10-03 05:01:261983}
1984
[email protected]79dbc662009-09-04 05:42:511985// WebKit::WebWidgetClient ----------------------------------------------------
1986
[email protected]310ebd6302011-10-10 19:06:281987void RenderViewImpl::didFocus() {
[email protected]ea42e7782010-08-23 23:58:121988 // TODO(jcivelli): when https://bugs.webkit.org/show_bug.cgi?id=33389 is fixed
1989 // we won't have to test for user gesture anymore and we can
1990 // move that code back to render_widget.cc
1991 if (webview() && webview()->mainFrame() &&
1992 webview()->mainFrame()->isProcessingUserGesture()) {
1993 Send(new ViewHostMsg_Focus(routing_id_));
1994 }
1995}
1996
[email protected]310ebd6302011-10-10 19:06:281997void RenderViewImpl::didBlur() {
[email protected]ea42e7782010-08-23 23:58:121998 // TODO(jcivelli): see TODO above in didFocus().
1999 if (webview() && webview()->mainFrame() &&
2000 webview()->mainFrame()->isProcessingUserGesture()) {
2001 Send(new ViewHostMsg_Blur(routing_id_));
2002 }
2003}
2004
initial.commit09911bf2008-07-26 23:55:292005// We are supposed to get a single call to Show for a newly created RenderView
[email protected]310ebd6302011-10-10 19:06:282006// that was created via RenderViewImpl::CreateWebView. So, we wait until this
initial.commit09911bf2008-07-26 23:55:292007// point to dispatch the ShowView message.
2008//
2009// This method provides us with the information about how to display the newly
[email protected]5f9de5882011-09-30 23:36:282010// created RenderView (i.e., as a blocked popup or as a new tab).
initial.commit09911bf2008-07-26 23:55:292011//
[email protected]310ebd6302011-10-10 19:06:282012void RenderViewImpl::show(WebNavigationPolicy policy) {
initial.commit09911bf2008-07-26 23:55:292013 DCHECK(!did_show_) << "received extraneous Show call";
2014 DCHECK(opener_id_ != MSG_ROUTING_NONE);
2015
2016 if (did_show_)
2017 return;
2018 did_show_ = true;
2019
[email protected]6779aa12011-03-29 17:32:242020 if (content::GetContentClient()->renderer()->AllowPopup(creator_url_))
[email protected]4026ce1e2010-09-14 19:35:042021 opened_by_user_gesture_ = true;
[email protected]4026ce1e2010-09-14 19:35:042022
[email protected]28295ec2009-10-16 05:34:332023 // Force new windows to a popup if they were not opened with a user gesture.
2024 if (!opened_by_user_gesture_) {
2025 // We exempt background tabs for compat with older versions of Chrome.
2026 // TODO(darin): This seems bogus. These should have a user gesture, so
2027 // we probably don't need this check.
2028 if (policy != WebKit::WebNavigationPolicyNewBackgroundTab)
2029 policy = WebKit::WebNavigationPolicyNewPopup;
2030 }
2031
initial.commit09911bf2008-07-26 23:55:292032 // NOTE: initial_pos_ may still have its default values at this point, but
2033 // that's okay. It'll be ignored if disposition is not NEW_POPUP, or the
2034 // browser process will impose a default position otherwise.
[email protected]4873c7d2009-07-16 06:36:282035 Send(new ViewHostMsg_ShowView(opener_id_, routing_id_,
2036 NavigationPolicyToDisposition(policy), initial_pos_,
[email protected]7e7414ae2010-01-26 20:19:292037 opened_by_user_gesture_));
[email protected]2533ce12009-05-09 00:02:242038 SetPendingWindowRect(initial_pos_);
initial.commit09911bf2008-07-26 23:55:292039}
2040
[email protected]310ebd6302011-10-10 19:06:282041void RenderViewImpl::runModal() {
initial.commit09911bf2008-07-26 23:55:292042 DCHECK(did_show_) << "should already have shown the view";
2043
[email protected]c1f50aa2010-02-18 03:46:572044 // We must keep WebKit's shared timer running in this case in order to allow
2045 // showModalDialog to function properly.
2046 //
2047 // TODO(darin): WebKit should really be smarter about suppressing events and
2048 // timers so that we do not need to manage the shared timer in such a heavy
2049 // handed manner.
2050 //
[email protected]f1a29a02011-10-06 23:08:442051 if (RenderThreadImpl::current()) // Will be NULL during unit tests.
2052 RenderThreadImpl::current()->DoNotSuspendWebKitSharedTimer();
[email protected]c1f50aa2010-02-18 03:46:572053
[email protected]12636df2009-09-28 22:32:212054 SendAndRunNestedMessageLoop(new ViewHostMsg_RunModal(routing_id_));
initial.commit09911bf2008-07-26 23:55:292055}
2056
[email protected]2b624c562011-10-27 22:58:262057bool RenderViewImpl::enterFullScreen() {
2058 Send(new ViewHostMsg_ToggleFullscreen(routing_id_, true));
2059 return true;
2060}
2061
2062void RenderViewImpl::exitFullScreen() {
2063 Send(new ViewHostMsg_ToggleFullscreen(routing_id_, false));
2064}
2065
[email protected]217690d2012-01-27 07:33:112066bool RenderViewImpl::requestPointerLock() {
2067 return mouse_lock_dispatcher_->LockMouse(webwidget_mouse_lock_target_.get());
2068}
2069
2070void RenderViewImpl::requestPointerUnlock() {
2071 mouse_lock_dispatcher_->UnlockMouse(webwidget_mouse_lock_target_.get());
2072}
2073
2074bool RenderViewImpl::isPointerLocked() {
2075 return mouse_lock_dispatcher_->IsMouseLockedTo(
2076 webwidget_mouse_lock_target_.get());
2077}
2078
[email protected]7a1ec28a2012-03-28 21:10:242079void RenderViewImpl::didActivateCompositor(int input_handler_identifier) {
2080 CompositorThread* compositor_thread =
2081 RenderThreadImpl::current()->compositor_thread();
2082 if (compositor_thread)
2083 compositor_thread->AddInputHandler(
2084 routing_id_, input_handler_identifier, AsWeakPtr());
2085
2086 RenderWidget::didActivateCompositor(input_handler_identifier);
2087}
2088
[email protected]3d9689372009-09-10 04:29:172089// WebKit::WebFrameClient -----------------------------------------------------
2090
[email protected]310ebd6302011-10-10 19:06:282091WebPlugin* RenderViewImpl::createPlugin(WebFrame* frame,
2092 const WebPluginParams& params) {
[email protected]0361b942012-03-14 06:42:532093 // The browser plugin is a special kind of pepper plugin
2094 // that loads asynchronously. We first create a placeholder here.
2095 // When a guest is ready to be displayed, we swap out the placeholder
2096 // with the guest.
2097 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2098 if (command_line.HasSwitch(switches::kEnableBrowserPlugin) &&
2099 UTF16ToASCII(params.mimeType) == kBrowserPluginMimeType)
2100 return BrowserPluginPlaceholder::Create(this, frame, params);
2101
[email protected]eaacd1f2011-09-23 02:32:552102 WebPlugin* plugin = NULL;
2103 if (content::GetContentClient()->renderer()->OverrideCreatePlugin(
2104 this, frame, params, &plugin)) {
2105 return plugin;
2106 }
2107
[email protected]a813c8e2011-10-08 01:34:112108 webkit::WebPluginInfo info;
2109 std::string mime_type;
2110 bool found = GetPluginInfo(params.url, frame->top()->document().url(),
2111 params.mimeType.utf8(), &info, &mime_type);
2112 if (!found)
2113 return NULL;
2114
2115 WebPluginParams params_to_use = params;
2116 params_to_use.mimeType = WebString::fromUTF8(mime_type);
[email protected]a2ef54c2011-10-10 16:20:312117 return CreatePlugin(frame, info, params_to_use);
[email protected]3d9689372009-09-10 04:29:172118}
2119
[email protected]310ebd6302011-10-10 19:06:282120WebSharedWorker* RenderViewImpl::createSharedWorker(
[email protected]9c00f002009-11-05 22:37:422121 WebFrame* frame, const WebURL& url, const WebString& name,
[email protected]30447b62009-11-13 01:13:372122 unsigned long long document_id) {
[email protected]9c00f002009-11-05 22:37:422123
[email protected]30447b62009-11-13 01:13:372124 int route_id = MSG_ROUTING_NONE;
[email protected]6de0bcf2010-02-17 22:00:512125 bool exists = false;
[email protected]30447b62009-11-13 01:13:372126 bool url_mismatch = false;
[email protected]6de0bcf2010-02-17 22:00:512127 ViewHostMsg_CreateWorker_Params params;
2128 params.url = url;
[email protected]6de0bcf2010-02-17 22:00:512129 params.name = name;
2130 params.document_id = document_id;
2131 params.render_view_route_id = routing_id_;
2132 params.route_id = MSG_ROUTING_NONE;
[email protected]f9bc9c02010-05-24 19:19:232133 params.script_resource_appcache_id = 0;
[email protected]30447b62009-11-13 01:13:372134 Send(new ViewHostMsg_LookupSharedWorker(
[email protected]6de0bcf2010-02-17 22:00:512135 params, &exists, &route_id, &url_mismatch));
[email protected]30447b62009-11-13 01:13:372136 if (url_mismatch) {
2137 return NULL;
2138 } else {
[email protected]f1a29a02011-10-06 23:08:442139 return new WebSharedWorkerProxy(RenderThreadImpl::current(),
[email protected]0791d3a2010-01-28 01:28:492140 document_id,
[email protected]6de0bcf2010-02-17 22:00:512141 exists,
[email protected]30447b62009-11-13 01:13:372142 route_id,
2143 routing_id_);
2144 }
[email protected]9c00f002009-11-05 22:37:422145}
2146
[email protected]310ebd6302011-10-10 19:06:282147WebMediaPlayer* RenderViewImpl::createMediaPlayer(
[email protected]3d9689372009-09-10 04:29:172148 WebFrame* frame, WebMediaPlayerClient* client) {
[email protected]16e923d2011-04-30 00:41:442149 FOR_EACH_OBSERVER(
2150 RenderViewObserver, observers_, WillCreateMediaPlayer(frame, client));
[email protected]7198402c2011-04-11 12:15:172151
[email protected]bb6fd402011-12-09 02:45:442152 media::MessageLoopFactory* message_loop_factory =
[email protected]b80322902012-03-06 01:33:502153 new media::MessageLoopFactory();
[email protected]bb6fd402011-12-09 02:45:442154 media::FilterCollection* collection = new media::FilterCollection();
2155 RenderMediaLog* render_media_log = new RenderMediaLog();
[email protected]457d8342010-10-23 01:20:372156
[email protected]9e2269d2012-01-07 00:06:212157 RenderAudioSourceProvider* audio_source_provider = NULL;
2158
[email protected]3d9689372009-09-10 04:29:172159 // Add in any custom filter factories first.
2160 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
2161 if (!cmd_line->HasSwitch(switches::kDisableAudio)) {
[email protected]9e2269d2012-01-07 00:06:212162 // audio_source_provider is a "provider" to WebKit, and a sink
2163 // from the perspective of the audio renderer.
2164 audio_source_provider = new RenderAudioSourceProvider();
2165
2166 // Add the chrome specific audio renderer, using audio_source_provider
2167 // as the sink.
2168 AudioRendererImpl* audio_renderer =
2169 new AudioRendererImpl(audio_source_provider);
2170 collection->AddAudioRenderer(audio_renderer);
[email protected]3d9689372009-09-10 04:29:172171 }
2172
[email protected]e1d69d762011-12-13 05:12:182173 // Currently only cros/arm has any HW video decode support in
2174 // GpuVideoDecodeAccelerator so we don't even try to use it on other
2175 // platforms. This is a startup-time optimization. When new VDA
2176 // implementations are added, relax the #if above.
[email protected]d0fb8a72012-03-10 18:54:522177#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)
2178 // Note we don't actually use the result of this blind down-cast unless it's
2179 // valid (not NULL and of the right type).
[email protected]43567302012-02-16 23:21:392180 WebGraphicsContext3DCommandBufferImpl* context3d =
2181 static_cast<WebGraphicsContext3DCommandBufferImpl*>(
2182 webview()->graphicsContext3D());
[email protected]d0fb8a72012-03-10 18:54:522183 if (context_is_web_graphics_context_3d_command_buffer_impl_ && context3d) {
[email protected]84a83e192012-03-09 18:43:402184 MessageLoop* factories_loop =
2185 RenderThreadImpl::current()->compositor_thread() ?
2186 RenderThreadImpl::current()->compositor_thread()->GetWebThread()
2187 ->message_loop() :
2188 MessageLoop::current();
[email protected]e1d69d762011-12-13 05:12:182189 GpuChannelHost* gpu_channel_host =
2190 RenderThreadImpl::current()->EstablishGpuChannelSync(
2191 content::CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE);
2192 collection->AddVideoDecoder(new media::GpuVideoDecoder(
[email protected]8d4359282012-01-14 00:53:312193 message_loop_factory->GetMessageLoop("GpuVideoDecoder"),
[email protected]84a83e192012-03-09 18:43:402194 factories_loop,
[email protected]8d4359282012-01-14 00:53:312195 new RendererGpuVideoDecoderFactories(
[email protected]84a83e192012-03-09 18:43:402196 gpu_channel_host, factories_loop, context3d)));
[email protected]e1d69d762011-12-13 05:12:182197 }
2198#endif
2199
[email protected]da952fd2012-01-13 03:49:252200 webkit_media::WebMediaPlayerImpl* media_player =
2201 content::GetContentClient()->renderer()->OverrideCreateWebMediaPlayer(
2202 this, frame, client, AsWeakPtr(), collection, audio_source_provider,
2203 message_loop_factory, media_stream_impl_.get(), render_media_log);
[email protected]c4dabe452012-02-08 23:58:122204#if defined(OS_ANDROID)
2205 // TODO(qinmin): Implement for android.
2206 // http://crbug.com/113218
2207#else
[email protected]da952fd2012-01-13 03:49:252208 if (!media_player) {
[email protected]cec4eb82012-01-12 17:51:562209 media_player = new webkit_media::WebMediaPlayerImpl(
[email protected]da952fd2012-01-13 03:49:252210 frame, client, AsWeakPtr(), collection, audio_source_provider,
[email protected]9e2269d2012-01-07 00:06:212211 message_loop_factory, media_stream_impl_.get(), render_media_log);
[email protected]bb6fd402011-12-09 02:45:442212 }
[email protected]c4dabe452012-02-08 23:58:122213#endif
[email protected]cec4eb82012-01-12 17:51:562214 return media_player;
[email protected]3d9689372009-09-10 04:29:172215}
2216
[email protected]310ebd6302011-10-10 19:06:282217WebApplicationCacheHost* RenderViewImpl::createApplicationCacheHost(
[email protected]035545f2010-04-09 13:10:212218 WebFrame* frame, WebApplicationCacheHostClient* client) {
[email protected]cdeeeb22012-01-11 07:44:232219 if (!frame || !frame->view())
2220 return NULL;
[email protected]035545f2010-04-09 13:10:212221 return new RendererWebApplicationCacheHostImpl(
2222 FromWebView(frame->view()), client,
[email protected]f1a29a02011-10-06 23:08:442223 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy());
[email protected]035545f2010-04-09 13:10:212224}
2225
[email protected]310ebd6302011-10-10 19:06:282226WebCookieJar* RenderViewImpl::cookieJar(WebFrame* frame) {
[email protected]8ff181072010-11-29 17:09:382227 return &cookie_jar_;
2228}
2229
[email protected]310ebd6302011-10-10 19:06:282230void RenderViewImpl::frameDetached(WebFrame* frame) {
[email protected]676126f72011-01-15 00:03:512231 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame));
[email protected]5041f982010-08-11 21:40:452232}
2233
[email protected]310ebd6302011-10-10 19:06:282234void RenderViewImpl::willClose(WebFrame* frame) {
[email protected]676126f72011-01-15 00:03:512235 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame));
[email protected]3d9689372009-09-10 04:29:172236}
2237
[email protected]310ebd6302011-10-10 19:06:282238void RenderViewImpl::loadURLExternally(
[email protected]3d9689372009-09-10 04:29:172239 WebFrame* frame, const WebURLRequest& request,
2240 WebNavigationPolicy policy) {
[email protected]0622875ab2011-07-27 12:10:342241 loadURLExternally(frame, request, policy, WebString());
2242}
2243
[email protected]310ebd6302011-10-10 19:06:282244void RenderViewImpl::loadURLExternally(
[email protected]0622875ab2011-07-27 12:10:342245 WebFrame* frame, const WebURLRequest& request,
2246 WebNavigationPolicy policy,
2247 const WebString& suggested_name) {
[email protected]efce17b2009-09-11 18:04:592248 GURL referrer(request.httpHeaderField(WebString::fromUTF8("Referer")));
2249 if (policy == WebKit::WebNavigationPolicyDownload) {
[email protected]0622875ab2011-07-27 12:10:342250 Send(new ViewHostMsg_DownloadUrl(routing_id_, request.url(), referrer,
2251 suggested_name));
[email protected]efce17b2009-09-11 18:04:592252 } else {
[email protected]445e1042011-12-03 21:03:152253 OpenURL(frame, request.url(),
[email protected]b9fd01ba2012-02-28 01:50:402254 Referrer(referrer, GetReferrerPolicyFromRequest(request)), policy);
[email protected]efce17b2009-09-11 18:04:592255 }
[email protected]3d9689372009-09-10 04:29:172256}
2257
[email protected]310ebd6302011-10-10 19:06:282258WebNavigationPolicy RenderViewImpl::decidePolicyForNavigation(
[email protected]3d9689372009-09-10 04:29:172259 WebFrame* frame, const WebURLRequest& request, WebNavigationType type,
[email protected]65b95cd2009-10-09 05:10:222260 const WebNode&, WebNavigationPolicy default_policy, bool is_redirect) {
[email protected]0639c063a2012-03-22 20:55:332261 Referrer referrer(
2262 GURL(request.httpHeaderField(WebString::fromUTF8("Referer"))),
2263 GetReferrerPolicyFromRequest(request));
2264
[email protected]992db4c2011-05-12 15:37:152265 if (is_swapped_out_) {
[email protected]0639c063a2012-03-22 20:55:332266 if (request.url() != GURL(chrome::kSwappedOutURL)) {
2267 // Targeted links may try to navigate a swapped out frame. Allow the
2268 // browser process to navigate the tab instead. Note that it is also
2269 // possible for non-targeted navigations (from this view) to arrive
2270 // here just after we are swapped out. It's ok to send them to the
2271 // browser, as long as they're for the top level frame.
2272 // TODO(creis): Ensure this supports targeted form submissions when
2273 // fixing http://crbug.com/101395.
2274 if (frame->parent() == NULL) {
2275 OpenURL(frame, request.url(), referrer, default_policy);
2276 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
2277 }
2278
2279 // We should otherwise ignore in-process iframe navigations, if they
2280 // arrive just after we are swapped out.
[email protected]73eb2602012-02-09 19:50:552281 return WebKit::WebNavigationPolicyIgnore;
[email protected]0639c063a2012-03-22 20:55:332282 }
[email protected]73eb2602012-02-09 19:50:552283
[email protected]58436a12012-03-21 17:10:262284 // Allow chrome::kSwappedOutURL to complete.
[email protected]992db4c2011-05-12 15:37:152285 return default_policy;
2286 }
2287
[email protected]3d9689372009-09-10 04:29:172288 // Webkit is asking whether to navigate to a new URL.
2289 // This is fine normally, except if we're showing UI from one security
2290 // context and they're trying to navigate to a different context.
2291 const GURL& url = request.url();
2292
[email protected]d19ea342011-04-20 20:31:132293 // A content initiated navigation may have originated from a link-click,
2294 // script, drag-n-drop operation, etc.
2295 bool is_content_initiated =
[email protected]007733c2011-11-17 00:34:072296 DocumentState::FromDataSource(frame->provisionalDataSource())->
2297 navigation_state()->is_content_initiated();
[email protected]d19ea342011-04-20 20:31:132298
[email protected]a8c269a2011-10-25 20:17:222299 // Experimental:
2300 // If --enable-strict-site-isolation is enabled, send all top-level
2301 // navigations to the browser to let it swap processes when crossing site
2302 // boundaries. This is currently expected to break some script calls and
2303 // navigations, such as form submissions.
2304 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]313b80bd2011-11-23 03:49:102305 if (command_line.HasSwitch(switches::kEnableStrictSiteIsolation) &&
2306 !frame->parent() && (is_content_initiated || is_redirect)) {
2307 WebString origin_str = frame->document().securityOrigin().toString();
2308 GURL frame_url(origin_str.utf8().data());
2309 // TODO(cevans): revisit whether this origin check is still necessary once
2310 // crbug.com/101395 is fixed.
2311 if (frame_url.GetOrigin() != url.GetOrigin()) {
[email protected]313b80bd2011-11-23 03:49:102312 OpenURL(frame, url, referrer, default_policy);
2313 return WebKit::WebNavigationPolicyIgnore;
2314 }
[email protected]a8c269a2011-10-25 20:17:222315 }
2316
[email protected]3d9689372009-09-10 04:29:172317 // If the browser is interested, then give it a chance to look at top level
[email protected]3a8eecb2010-04-22 23:56:302318 // navigations.
[email protected]5f000f272012-01-19 05:25:082319 if (is_content_initiated) {
2320 bool browser_handles_top_level_requests =
2321 renderer_preferences_.browser_handles_top_level_requests &&
2322 IsNonLocalTopLevelNavigation(url, frame, type);
2323 if (browser_handles_top_level_requests ||
2324 renderer_preferences_.browser_handles_all_requests) {
[email protected]5f000f272012-01-19 05:25:082325 // Reset these counters as the RenderView could be reused for the next
2326 // navigation.
2327 page_id_ = -1;
2328 last_page_id_sent_to_browser_ = -1;
2329 OpenURL(frame, url, referrer, default_policy);
2330 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
2331 }
[email protected]3d9689372009-09-10 04:29:172332 }
2333
[email protected]6101c342010-12-16 22:44:372334 // Detect when we're crossing a permission-based boundary (e.g. into or out of
[email protected]c39f9bf2011-02-12 00:43:552335 // an extension or app origin, leaving a WebUI page, etc). We only care about
[email protected]744c2a22012-03-15 18:42:042336 // top-level navigations (not iframes). But we sometimes navigate to
2337 // about:blank to clear a tab, and we want to still allow that.
[email protected]6101c342010-12-16 22:44:372338 //
[email protected]744c2a22012-03-15 18:42:042339 // Note: this is known to break POST submissions when crossing process
2340 // boundaries until http://crbug.com/101395 is fixed. This is better for
2341 // security than loading a WebUI, extension or app page in the wrong process.
2342 // POST requests don't work because this mechanism does not preserve form
2343 // POST data. We will need to send the request's httpBody data up to the
2344 // browser process, and issue a special POST navigation in WebKit (via
[email protected]8f4da8c2011-02-09 19:49:572345 // FrameLoader::loadFrameRequest). See ResourceDispatcher and WebURLLoaderImpl
2346 // for examples of how to send the httpBody data.
[email protected]2762a1b2011-12-09 15:25:222347 if (!frame->parent() && is_content_initiated &&
[email protected]744c2a22012-03-15 18:42:042348 !url.SchemeIs(chrome::kAboutScheme)) {
[email protected]6101c342010-12-16 22:44:372349 bool send_referrer = false;
[email protected]744c2a22012-03-15 18:42:042350
2351 // All navigations to WebUI URLs or within WebUI-enabled RenderProcesses
2352 // must be handled by the browser process so that the correct bindings and
2353 // data sources can be registered.
2354 // Similarly, navigations to view-source URLs or within ViewSource mode
2355 // must be handled by the browser process.
2356 int cumulative_bindings =
2357 RenderProcess::current()->GetEnabledBindings();
[email protected]6101c342010-12-16 22:44:372358 bool should_fork =
[email protected]744c2a22012-03-15 18:42:042359 content::GetContentClient()->HasWebUIScheme(url) ||
2360 (cumulative_bindings & content::BINDINGS_POLICY_WEB_UI) ||
2361 url.SchemeIs(chrome::kViewSourceScheme) ||
2362 frame->isViewSourceModeEnabled();
[email protected]5351dbc2010-08-27 15:22:112363
[email protected]e48869a2011-04-01 19:56:032364 if (!should_fork) {
2365 // Give the embedder a chance.
[email protected]744c2a22012-03-15 18:42:042366 // For now, we skip this for POST submissions. This is because
2367 // http://crbug.com/101395 is more likely to cause compatibility issues
2368 // with hosted apps and extensions than WebUI pages. We will remove this
2369 // check when cross-process POST submissions are supported.
2370 if (request.httpMethod() == "GET") {
2371 bool is_initial_navigation = page_id_ == -1;
2372 should_fork = content::GetContentClient()->renderer()->ShouldFork(
2373 frame, url, is_initial_navigation, &send_referrer);
2374 }
[email protected]6101c342010-12-16 22:44:372375 }
2376
2377 if (should_fork) {
[email protected]445e1042011-12-03 21:03:152378 OpenURL(
2379 frame, url, send_referrer ? referrer : Referrer(), default_policy);
[email protected]5351dbc2010-08-27 15:22:112380 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
2381 }
[email protected]3d9689372009-09-10 04:29:172382 }
2383
[email protected]43763f982011-08-26 18:33:402384 // Use the frame's original request's URL rather than the document's URL for
2385 // this check. For a popup, the document's URL may become the opener window's
2386 // URL if the opener has called document.write. See http://crbug.com/93517.
2387 GURL old_url(frame->dataSource()->request().url());
2388
[email protected]3d9689372009-09-10 04:29:172389 // Detect when a page is "forking" a new tab that can be safely rendered in
2390 // its own process. This is done by sites like Gmail that try to open links
2391 // in new windows without script connections back to the original page. We
2392 // treat such cases as browser navigations (in which we will create a new
2393 // renderer for a cross-site navigation), rather than WebKit navigations.
2394 //
2395 // We use the following heuristic to decide whether to fork a new page in its
2396 // own process:
2397 // The parent page must open a new tab to about:blank, set the new tab's
2398 // window.opener to null, and then redirect the tab to a cross-site URL using
2399 // JavaScript.
[email protected]007a848b2009-10-26 15:55:462400 //
2401 // TODO(creis): Deprecate this logic once we can rely on rel=noreferrer
2402 // (see below).
[email protected]3d9689372009-09-10 04:29:172403 bool is_fork =
2404 // Must start from a tab showing about:blank, which is later redirected.
[email protected]a6b960ad972010-09-01 19:53:582405 old_url == GURL(chrome::kAboutBlankURL) &&
[email protected]3d9689372009-09-10 04:29:172406 // Must be the first real navigation of the tab.
[email protected]48c9cf2d2009-09-16 16:47:522407 historyBackListCount() < 1 &&
2408 historyForwardListCount() < 1 &&
[email protected]3d9689372009-09-10 04:29:172409 // The parent page must have set the child's window.opener to null before
2410 // redirecting to the desired URL.
2411 frame->opener() == NULL &&
2412 // Must be a top-level frame.
2413 frame->parent() == NULL &&
2414 // Must not have issued the request from this page.
2415 is_content_initiated &&
2416 // Must be targeted at the current tab.
2417 default_policy == WebKit::WebNavigationPolicyCurrentTab &&
2418 // Must be a JavaScript navigation, which appears as "other".
2419 type == WebKit::WebNavigationTypeOther;
[email protected]007a848b2009-10-26 15:55:462420
[email protected]f92ce2b2012-03-06 18:02:592421 if (is_fork) {
[email protected]3d9689372009-09-10 04:29:172422 // Open the URL via the browser, not via WebKit.
[email protected]445e1042011-12-03 21:03:152423 OpenURL(frame, url, Referrer(), default_policy);
[email protected]3d9689372009-09-10 04:29:172424 return WebKit::WebNavigationPolicyIgnore;
2425 }
2426
2427 return default_policy;
2428}
2429
[email protected]310ebd6302011-10-10 19:06:282430bool RenderViewImpl::canHandleRequest(
[email protected]6069da8c2009-10-20 20:33:492431 WebFrame* frame, const WebURLRequest& request) {
2432 // We allow WebKit to think that everything can be handled even though
2433 // browser-side we limit what we load.
[email protected]7b7a7dc2009-10-19 02:23:342434 return true;
2435}
2436
[email protected]310ebd6302011-10-10 19:06:282437WebURLError RenderViewImpl::cannotHandleRequestError(
[email protected]6069da8c2009-10-20 20:33:492438 WebFrame* frame, const WebURLRequest& request) {
2439 NOTREACHED(); // Since we said we can handle all requests.
2440 return WebURLError();
2441}
2442
[email protected]310ebd6302011-10-10 19:06:282443WebURLError RenderViewImpl::cancelledError(
[email protected]6069da8c2009-10-20 20:33:492444 WebFrame* frame, const WebURLRequest& request) {
2445 WebURLError error;
2446 error.domain = WebString::fromUTF8(net::kErrorDomain);
2447 error.reason = net::ERR_ABORTED;
2448 error.unreachableURL = request.url();
2449 return error;
[email protected]7b7a7dc2009-10-19 02:23:342450}
2451
[email protected]310ebd6302011-10-10 19:06:282452void RenderViewImpl::unableToImplementPolicyWithError(
[email protected]6069da8c2009-10-20 20:33:492453 WebFrame*, const WebURLError&) {
2454 NOTREACHED(); // Since we said we can handle all requests.
[email protected]7b7a7dc2009-10-19 02:23:342455}
2456
[email protected]310ebd6302011-10-10 19:06:282457void RenderViewImpl::willSendSubmitEvent(WebKit::WebFrame* frame,
[email protected]90eeddb2010-05-06 21:06:432458 const WebKit::WebFormElement& form) {
2459 // Some login forms have onSubmit handlers that put a hash of the password
2460 // into a hidden field and then clear the password. (Issue 28910.)
2461 // This method gets called before any of those handlers run, so save away
2462 // a copy of the password in case it gets lost.
[email protected]007733c2011-11-17 00:34:072463 DocumentState* document_state =
2464 DocumentState::FromDataSource(frame->dataSource());
2465 document_state->set_password_form_data(
[email protected]90eeddb2010-05-06 21:06:432466 PasswordFormDomManager::CreatePasswordForm(form));
2467}
2468
[email protected]310ebd6302011-10-10 19:06:282469void RenderViewImpl::willSubmitForm(WebFrame* frame,
2470 const WebFormElement& form) {
[email protected]007733c2011-11-17 00:34:072471 DocumentState* document_state =
2472 DocumentState::FromDataSource(frame->provisionalDataSource());
2473 NavigationState* navigation_state = document_state->navigation_state();
[email protected]3d9689372009-09-10 04:29:172474
[email protected]2905f742011-10-13 03:51:582475 if (navigation_state->transition_type() == content::PAGE_TRANSITION_LINK)
2476 navigation_state->set_transition_type(content::PAGE_TRANSITION_FORM_SUBMIT);
[email protected]3d9689372009-09-10 04:29:172477
2478 // Save these to be processed when the ensuing navigation is committed.
[email protected]ce0e250d2009-10-23 21:00:352479 WebSearchableFormData web_searchable_form_data(form);
[email protected]007733c2011-11-17 00:34:072480 document_state->set_searchable_form_url(web_searchable_form_data.url());
2481 document_state->set_searchable_form_encoding(
[email protected]b7910b3a2010-01-13 18:33:212482 web_searchable_form_data.encoding().utf8());
[email protected]90eeddb2010-05-06 21:06:432483 PasswordForm* password_form_data =
2484 PasswordFormDomManager::CreatePasswordForm(form);
[email protected]007733c2011-11-17 00:34:072485 document_state->set_password_form_data(password_form_data);
[email protected]90eeddb2010-05-06 21:06:432486
[email protected]098c95cb2011-04-28 16:49:012487 // In order to save the password that the user actually typed and not one
2488 // that may have gotten transformed by the site prior to submit, recover it
2489 // from the form contents already stored by |willSendSubmitEvent| into the
2490 // dataSource's NavigationState (as opposed to the provisionalDataSource's,
2491 // which is what we're storing into now.)
2492 if (password_form_data) {
[email protected]007733c2011-11-17 00:34:072493 DocumentState* old_document_state =
2494 DocumentState::FromDataSource(frame->dataSource());
2495 if (old_document_state) {
2496 PasswordForm* old_form_data = old_document_state->password_form_data();
[email protected]90eeddb2010-05-06 21:06:432497 if (old_form_data && old_form_data->action == password_form_data->action)
2498 password_form_data->password_value = old_form_data->password_value;
2499 }
2500 }
[email protected]3d9689372009-09-10 04:29:172501
[email protected]2a5b1732011-04-01 23:55:552502 FOR_EACH_OBSERVER(
2503 RenderViewObserver, observers_, WillSubmitForm(frame, form));
[email protected]3d9689372009-09-10 04:29:172504}
2505
[email protected]310ebd6302011-10-10 19:06:282506void RenderViewImpl::willPerformClientRedirect(
[email protected]3d9689372009-09-10 04:29:172507 WebFrame* frame, const WebURL& from, const WebURL& to, double interval,
2508 double fire_time) {
[email protected]eb0bff942011-04-07 22:08:382509 FOR_EACH_OBSERVER(
2510 RenderViewObserver, observers_,
2511 WillPerformClientRedirect(frame, from, to, interval, fire_time));
[email protected]3d9689372009-09-10 04:29:172512}
2513
[email protected]310ebd6302011-10-10 19:06:282514void RenderViewImpl::didCancelClientRedirect(WebFrame* frame) {
[email protected]eb0bff942011-04-07 22:08:382515 FOR_EACH_OBSERVER(
2516 RenderViewObserver, observers_, DidCancelClientRedirect(frame));
[email protected]3d9689372009-09-10 04:29:172517}
2518
[email protected]310ebd6302011-10-10 19:06:282519void RenderViewImpl::didCompleteClientRedirect(
[email protected]3d9689372009-09-10 04:29:172520 WebFrame* frame, const WebURL& from) {
[email protected]445e1042011-12-03 21:03:152521 if (!frame->parent()) {
2522 WebDataSource* ds = frame->provisionalDataSource();
2523 // If there's no provisional data source, it's a reference fragment
2524 // navigation.
2525 completed_client_redirect_src_ = Referrer(
[email protected]b9fd01ba2012-02-28 01:50:402526 from, ds ? GetReferrerPolicyFromRequest(ds->request()) :
[email protected]445e1042011-12-03 21:03:152527 frame->referrerPolicy());
2528 }
[email protected]eb0bff942011-04-07 22:08:382529 FOR_EACH_OBSERVER(
2530 RenderViewObserver, observers_, DidCompleteClientRedirect(frame, from));
[email protected]3d9689372009-09-10 04:29:172531}
2532
[email protected]310ebd6302011-10-10 19:06:282533void RenderViewImpl::didCreateDataSource(WebFrame* frame, WebDataSource* ds) {
[email protected]007733c2011-11-17 00:34:072534 DocumentState* document_state = DocumentState::FromDataSource(ds);
2535 if (!document_state) {
2536 document_state = new DocumentState;
2537 ds->setExtraData(document_state);
2538 }
2539
[email protected]3d9689372009-09-10 04:29:172540 // The rest of RenderView assumes that a WebDataSource will always have a
2541 // non-null NavigationState.
[email protected]007733c2011-11-17 00:34:072542 bool content_initiated = !pending_navigation_params_.get();
2543 if (content_initiated)
2544 document_state->set_navigation_state(
2545 NavigationState::CreateContentInitiated());
2546 else
2547 PopulateStateFromPendingNavigationParams(document_state);
[email protected]8a3125a712010-08-09 18:58:512548
[email protected]007733c2011-11-17 00:34:072549 // DocumentState::referred_by_prefetcher_ is true if we are
[email protected]8a3125a712010-08-09 18:58:512550 // navigating from a page that used prefetching using a link on that
2551 // page. We are early enough in the request process here that we
[email protected]007733c2011-11-17 00:34:072552 // can still see the DocumentState of the previous page and set
[email protected]8a3125a712010-08-09 18:58:512553 // this value appropriately.
2554 // TODO(gavinp): catch the important case of navigation in a new
2555 // renderer process.
2556 if (webview()) {
[email protected]e47aec52010-08-12 00:50:302557 if (WebFrame* old_frame = webview()->mainFrame()) {
[email protected]05c8e502010-08-15 15:13:522558 const WebURLRequest& original_request = ds->originalRequest();
[email protected]8a3125a712010-08-09 18:58:512559 const GURL referrer(
2560 original_request.httpHeaderField(WebString::fromUTF8("Referer")));
2561 if (!referrer.is_empty() &&
[email protected]007733c2011-11-17 00:34:072562 DocumentState::FromDataSource(
[email protected]8a3125a712010-08-09 18:58:512563 old_frame->dataSource())->was_prefetcher()) {
[email protected]82114f52012-03-20 22:53:412564 for (; old_frame; old_frame = old_frame->traverseNext(false)) {
[email protected]8a3125a712010-08-09 18:58:512565 WebDataSource* old_frame_ds = old_frame->dataSource();
2566 if (old_frame_ds && referrer == GURL(old_frame_ds->request().url())) {
[email protected]007733c2011-11-17 00:34:072567 document_state->set_was_referred_by_prefetcher(true);
[email protected]8a3125a712010-08-09 18:58:512568 break;
2569 }
2570 }
2571 }
2572 }
2573 }
2574
[email protected]4c1b6f0b2010-02-07 16:38:182575 if (content_initiated) {
[email protected]05c8e502010-08-15 15:13:522576 const WebURLRequest& request = ds->request();
[email protected]8a3125a712010-08-09 18:58:512577 switch (request.cachePolicy()) {
[email protected]4c1b6f0b2010-02-07 16:38:182578 case WebURLRequest::UseProtocolCachePolicy: // normal load.
[email protected]007733c2011-11-17 00:34:072579 document_state->set_load_type(DocumentState::LINK_LOAD_NORMAL);
[email protected]4c1b6f0b2010-02-07 16:38:182580 break;
2581 case WebURLRequest::ReloadIgnoringCacheData: // reload.
[email protected]007733c2011-11-17 00:34:072582 document_state->set_load_type(DocumentState::LINK_LOAD_RELOAD);
[email protected]4c1b6f0b2010-02-07 16:38:182583 break;
2584 case WebURLRequest::ReturnCacheDataElseLoad: // allow stale data.
[email protected]007733c2011-11-17 00:34:072585 document_state->set_load_type(
2586 DocumentState::LINK_LOAD_CACHE_STALE_OK);
[email protected]4c1b6f0b2010-02-07 16:38:182587 break;
2588 case WebURLRequest::ReturnCacheDataDontLoad: // Don't re-post.
[email protected]007733c2011-11-17 00:34:072589 document_state->set_load_type(DocumentState::LINK_LOAD_CACHE_ONLY);
[email protected]4c1b6f0b2010-02-07 16:38:182590 break;
2591 }
2592 }
[email protected]fa7b6b542009-11-03 05:02:302593
[email protected]946a0032011-03-31 18:42:282594 FOR_EACH_OBSERVER(
2595 RenderViewObserver, observers_, DidCreateDataSource(frame, ds));
[email protected]3d9689372009-09-10 04:29:172596}
2597
[email protected]007733c2011-11-17 00:34:072598void RenderViewImpl::PopulateStateFromPendingNavigationParams(
2599 DocumentState* document_state) {
2600 const ViewMsg_Navigate_Params& params = *pending_navigation_params_.get();
2601
2602 if (document_state->request_time().is_null())
2603 document_state->set_request_time(params.request_time);
2604
2605 // A navigation resulting from loading a javascript URL should not be treated
2606 // as a browser initiated event. Instead, we want it to look as if the page
2607 // initiated any load resulting from JS execution.
2608 if (!params.url.SchemeIs(chrome::kJavaScriptScheme)) {
2609 NavigationState* navigation_state = NavigationState::CreateBrowserInitiated(
2610 params.page_id,
2611 params.pending_history_list_offset,
2612 params.transition);
[email protected]4ad5d77d2011-12-03 02:00:482613 navigation_state->set_transferred_request_child_id(
2614 params.transferred_request_child_id);
2615 navigation_state->set_transferred_request_request_id(
2616 params.transferred_request_request_id);
[email protected]007733c2011-11-17 00:34:072617 if (params.navigation_type == ViewMsg_Navigate_Type::RESTORE) {
2618 // We're doing a load of a page that was restored from the last session.
2619 // By default this prefers the cache over loading (LOAD_PREFERRING_CACHE)
2620 // which can result in stale data for pages that are set to expire. We
2621 // explicitly override that by setting the policy here so that as
2622 // necessary we load from the network.
2623 document_state->set_cache_policy_override(
2624 WebURLRequest::UseProtocolCachePolicy);
2625 }
2626 document_state->set_navigation_state(navigation_state);
2627 } else {
2628 document_state->set_navigation_state(
2629 NavigationState::CreateContentInitiated());
2630 }
2631
2632 if (IsReload(params))
2633 document_state->set_load_type(DocumentState::RELOAD);
2634 else if (!params.state.empty())
2635 document_state->set_load_type(DocumentState::HISTORY_LOAD);
2636 else
2637 document_state->set_load_type(DocumentState::NORMAL_LOAD);
2638
2639 pending_navigation_params_.reset();
2640}
2641
[email protected]5b52cd2f712012-03-28 02:12:482642void RenderViewImpl::ProcessViewLayoutFlags(const CommandLine& command_line) {
2643 bool enable_viewport =
2644 command_line.HasSwitch(switches::kEnableViewport);
2645 bool enable_fixed_layout =
2646 command_line.HasSwitch(switches::kEnableFixedLayout);
2647
2648 webview()->enableFixedLayoutMode(enable_fixed_layout || enable_viewport);
2649 webview()->settings()->setFixedElementsLayoutRelativeToFrame(true);
2650
2651 if (enable_viewport) {
2652 webview()->settings()->setViewportEnabled(true);
2653 } else if (enable_fixed_layout) {
2654 std::string str =
2655 command_line.GetSwitchValueASCII(switches::kEnableFixedLayout);
2656 std::vector<std::string> tokens;
2657 base::SplitString(str, ',', &tokens);
2658 if (tokens.size() == 2) {
2659 int width, height;
2660 if (base::StringToInt(tokens[0], &width) &&
2661 base::StringToInt(tokens[1], &height))
2662 webview()->setFixedLayoutSize(WebSize(width,height));
2663 }
2664 }
2665}
2666
[email protected]310ebd6302011-10-10 19:06:282667void RenderViewImpl::didStartProvisionalLoad(WebFrame* frame) {
[email protected]3d9689372009-09-10 04:29:172668 WebDataSource* ds = frame->provisionalDataSource();
[email protected]007733c2011-11-17 00:34:072669 DocumentState* document_state = DocumentState::FromDataSource(ds);
[email protected]3d9689372009-09-10 04:29:172670
[email protected]3d9689372009-09-10 04:29:172671 // Update the request time if WebKit has better knowledge of it.
[email protected]007733c2011-11-17 00:34:072672 if (document_state->request_time().is_null()) {
[email protected]3d9689372009-09-10 04:29:172673 double event_time = ds->triggeringEventTime();
2674 if (event_time != 0.0)
[email protected]007733c2011-11-17 00:34:072675 document_state->set_request_time(Time::FromDoubleT(event_time));
[email protected]3d9689372009-09-10 04:29:172676 }
2677
[email protected]05c8e502010-08-15 15:13:522678 // Start time is only set after request time.
[email protected]007733c2011-11-17 00:34:072679 document_state->set_start_load_time(Time::Now());
[email protected]05c8e502010-08-15 15:13:522680
[email protected]3d9689372009-09-10 04:29:172681 bool is_top_most = !frame->parent();
2682 if (is_top_most) {
2683 navigation_gesture_ = frame->isProcessingUserGesture() ?
[email protected]cd448092010-12-06 23:49:132684 NavigationGestureUser : NavigationGestureAuto;
[email protected]3d9689372009-09-10 04:29:172685
2686 // Make sure redirect tracking state is clear for the new load.
[email protected]445e1042011-12-03 21:03:152687 completed_client_redirect_src_ = Referrer();
[email protected]3d9689372009-09-10 04:29:172688 } else if (frame->parent()->isLoading()) {
2689 // Take note of AUTO_SUBFRAME loads here, so that we can know how to
[email protected]4fb66842009-12-04 21:41:002690 // load an error page. See didFailProvisionalLoad.
[email protected]007733c2011-11-17 00:34:072691 document_state->navigation_state()->set_transition_type(
[email protected]2905f742011-10-13 03:51:582692 content::PAGE_TRANSITION_AUTO_SUBFRAME);
[email protected]3d9689372009-09-10 04:29:172693 }
2694
[email protected]28685da92011-02-07 21:49:172695 FOR_EACH_OBSERVER(
2696 RenderViewObserver, observers_, DidStartProvisionalLoad(frame));
2697
[email protected]3d9689372009-09-10 04:29:172698 Send(new ViewHostMsg_DidStartProvisionalLoadForFrame(
[email protected]57b9396c2011-10-07 19:11:592699 routing_id_, frame->identifier(), is_top_most, GetOpenerUrl(),
[email protected]eacb080b2011-05-22 19:40:262700 ds->request().url()));
[email protected]3d9689372009-09-10 04:29:172701}
2702
[email protected]310ebd6302011-10-10 19:06:282703void RenderViewImpl::didReceiveServerRedirectForProvisionalLoad(
2704 WebFrame* frame) {
[email protected]3d9689372009-09-10 04:29:172705 if (frame->parent())
2706 return;
2707 // Received a redirect on the main frame.
2708 WebDataSource* data_source = frame->provisionalDataSource();
2709 if (!data_source) {
2710 // Should only be invoked when we have a data source.
2711 NOTREACHED();
2712 return;
2713 }
2714 std::vector<GURL> redirects;
2715 GetRedirectChain(data_source, &redirects);
2716 if (redirects.size() >= 2) {
[email protected]40bd6582009-12-04 23:49:512717 Send(new ViewHostMsg_DidRedirectProvisionalLoad(routing_id_, page_id_,
[email protected]57b9396c2011-10-07 19:11:592718 GetOpenerUrl(), redirects[redirects.size() - 2], redirects.back()));
[email protected]3d9689372009-09-10 04:29:172719 }
2720}
2721
[email protected]310ebd6302011-10-10 19:06:282722void RenderViewImpl::didFailProvisionalLoad(WebFrame* frame,
2723 const WebURLError& error) {
[email protected]3d9689372009-09-10 04:29:172724 // Notify the browser that we failed a provisional load with an error.
2725 //
2726 // Note: It is important this notification occur before DidStopLoading so the
2727 // SSL manager can react to the provisional load failure before being
2728 // notified the load stopped.
2729 //
2730 WebDataSource* ds = frame->provisionalDataSource();
2731 DCHECK(ds);
2732
2733 const WebURLRequest& failed_request = ds->request();
2734
[email protected]28685da92011-02-07 21:49:172735 FOR_EACH_OBSERVER(
2736 RenderViewObserver, observers_, DidFailProvisionalLoad(frame, error));
2737
[email protected]3d9689372009-09-10 04:29:172738 bool show_repost_interstitial =
2739 (error.reason == net::ERR_CACHE_MISS &&
2740 EqualsASCII(failed_request.httpMethod(), "POST"));
[email protected]d7b175e2011-10-11 15:31:582741
2742 ViewHostMsg_DidFailProvisionalLoadWithError_Params params;
2743 params.frame_id = frame->identifier();
2744 params.is_main_frame = !frame->parent();
2745 params.error_code = error.reason;
2746 content::GetContentClient()->renderer()->GetNavigationErrorStrings(
2747 failed_request,
2748 error,
2749 NULL,
2750 &params.error_description);
2751 params.url = error.unreachableURL;
2752 params.showing_repost_interstitial = show_repost_interstitial;
[email protected]3d9689372009-09-10 04:29:172753 Send(new ViewHostMsg_DidFailProvisionalLoadWithError(
[email protected]d7b175e2011-10-11 15:31:582754 routing_id_, params));
[email protected]3d9689372009-09-10 04:29:172755
2756 // Don't display an error page if this is simply a cancelled load. Aside
2757 // from being dumb, WebCore doesn't expect it and it will cause a crash.
2758 if (error.reason == net::ERR_ABORTED)
2759 return;
[email protected]b553edd52012-01-10 12:15:232760 // Don't display an error message if the request was handled by an
2761 // external protocol handler.
2762 if (error.reason == net::ERR_UNKNOWN_URL_SCHEME)
2763 return;
[email protected]3d9689372009-09-10 04:29:172764
2765 // Make sure we never show errors in view source mode.
2766 frame->enableViewSourceMode(false);
2767
[email protected]007733c2011-11-17 00:34:072768 DocumentState* document_state = DocumentState::FromDataSource(ds);
2769 NavigationState* navigation_state = document_state->navigation_state();
[email protected]3d9689372009-09-10 04:29:172770
2771 // If this is a failed back/forward/reload navigation, then we need to do a
2772 // 'replace' load. This is necessary to avoid messing up session history.
2773 // Otherwise, we do a normal load, which simulates a 'go' navigation as far
2774 // as session history is concerned.
2775 //
2776 // AUTO_SUBFRAME loads should always be treated as loads that do not advance
2777 // the page id.
2778 //
2779 bool replace =
2780 navigation_state->pending_page_id() != -1 ||
[email protected]2905f742011-10-13 03:51:582781 navigation_state->transition_type() ==
2782 content::PAGE_TRANSITION_AUTO_SUBFRAME;
[email protected]3d9689372009-09-10 04:29:172783
2784 // If we failed on a browser initiated request, then make sure that our error
2785 // page load is regarded as the same browser initiated request.
2786 if (!navigation_state->is_content_initiated()) {
[email protected]007733c2011-11-17 00:34:072787 pending_navigation_params_.reset(new ViewMsg_Navigate_Params);
2788 pending_navigation_params_->page_id =
2789 navigation_state->pending_page_id();
2790 pending_navigation_params_->pending_history_list_offset =
2791 navigation_state->pending_history_list_offset();
2792 pending_navigation_params_->transition =
2793 navigation_state->transition_type();
2794 pending_navigation_params_->request_time =
2795 document_state->request_time();
[email protected]3d9689372009-09-10 04:29:172796 }
2797
2798 // Provide the user with a more helpful error page?
2799 if (MaybeLoadAlternateErrorPage(frame, error, replace))
2800 return;
2801
2802 // Fallback to a local error page.
[email protected]3f853a52010-09-13 19:15:082803 LoadNavigationErrorPage(frame, failed_request, error, std::string(), replace);
[email protected]3d9689372009-09-10 04:29:172804}
2805
[email protected]310ebd6302011-10-10 19:06:282806void RenderViewImpl::didReceiveDocumentData(
[email protected]3d9689372009-09-10 04:29:172807 WebFrame* frame, const char* data, size_t data_len,
2808 bool& prevent_default) {
[email protected]007733c2011-11-17 00:34:072809 DocumentState* document_state =
2810 DocumentState::FromDataSource(frame->dataSource());
2811 document_state->set_use_error_page(false);
[email protected]3d9689372009-09-10 04:29:172812}
2813
[email protected]310ebd6302011-10-10 19:06:282814void RenderViewImpl::didCommitProvisionalLoad(WebFrame* frame,
2815 bool is_new_navigation) {
[email protected]007733c2011-11-17 00:34:072816 DocumentState* document_state =
2817 DocumentState::FromDataSource(frame->dataSource());
2818 NavigationState* navigation_state = document_state->navigation_state();
[email protected]3d9689372009-09-10 04:29:172819
[email protected]007733c2011-11-17 00:34:072820 if (document_state->commit_load_time().is_null())
2821 document_state->set_commit_load_time(Time::Now());
2822
[email protected]3d9689372009-09-10 04:29:172823 if (is_new_navigation) {
[email protected]e15f680732010-11-23 22:30:202824 // When we perform a new navigation, we need to update the last committed
2825 // session history entry with state for the page we are leaving.
[email protected]3d9689372009-09-10 04:29:172826 UpdateSessionHistory(frame);
2827
2828 // We bump our Page ID to correspond with the new session history entry.
2829 page_id_ = next_page_id_++;
2830
[email protected]58436a12012-03-21 17:10:262831 // Don't update history_page_ids_ (etc) for chrome::kSwappedOutURL, since
2832 // we don't want to forget the entry that was there, and since we will
2833 // never come back to chrome::kSwappedOutURL. Note that we have to call
[email protected]69ddf852012-02-21 23:21:312834 // UpdateSessionHistory and update page_id_ even in this case, so that
2835 // the current entry gets a state update and so that we don't send a
2836 // state update to the wrong entry when we swap back in.
[email protected]58436a12012-03-21 17:10:262837 if (GetLoadingUrl(frame) != GURL(chrome::kSwappedOutURL)) {
[email protected]69ddf852012-02-21 23:21:312838 // Advance our offset in session history, applying the length limit.
2839 // There is now no forward history.
2840 history_list_offset_++;
2841 if (history_list_offset_ >= content::kMaxSessionHistoryEntries)
2842 history_list_offset_ = content::kMaxSessionHistoryEntries - 1;
2843 history_list_length_ = history_list_offset_ + 1;
2844 history_page_ids_.resize(history_list_length_, -1);
2845 history_page_ids_[history_list_offset_] = page_id_;
2846 }
[email protected]3d9689372009-09-10 04:29:172847 } else {
2848 // Inspect the navigation_state on this frame to see if the navigation
2849 // corresponds to a session history navigation... Note: |frame| may or
2850 // may not be the toplevel frame, but for the case of capturing session
2851 // history, the first committed frame suffices. We keep track of whether
2852 // we've seen this commit before so that only capture session history once
2853 // per navigation.
2854 //
2855 // Note that we need to check if the page ID changed. In the case of a
2856 // reload, the page ID doesn't change, and UpdateSessionHistory gets the
2857 // previous URL and the current page ID, which would be wrong.
2858 if (navigation_state->pending_page_id() != -1 &&
2859 navigation_state->pending_page_id() != page_id_ &&
2860 !navigation_state->request_committed()) {
2861 // This is a successful session history navigation!
2862 UpdateSessionHistory(frame);
2863 page_id_ = navigation_state->pending_page_id();
[email protected]3cc72b12010-03-18 23:03:002864
2865 history_list_offset_ = navigation_state->pending_history_list_offset();
[email protected]d466b8a2011-07-15 21:48:032866
2867 // If the history list is valid, our list of page IDs should be correct.
2868 DCHECK(history_list_length_ <= 0 ||
2869 history_list_offset_ < 0 ||
2870 history_list_offset_ >= history_list_length_ ||
2871 history_page_ids_[history_list_offset_] == page_id_);
[email protected]3d9689372009-09-10 04:29:172872 }
2873 }
2874
[email protected]28685da92011-02-07 21:49:172875 FOR_EACH_OBSERVER(RenderViewObserver, observers_,
2876 DidCommitProvisionalLoad(frame, is_new_navigation));
2877
[email protected]3d9689372009-09-10 04:29:172878 // Remember that we've already processed this request, so we don't update
2879 // the session history again. We do this regardless of whether this is
2880 // a session history navigation, because if we attempted a session history
2881 // navigation without valid HistoryItem state, WebCore will think it is a
2882 // new navigation.
2883 navigation_state->set_request_committed(true);
2884
2885 UpdateURL(frame);
2886
2887 // If this committed load was initiated by a client redirect, we're
2888 // at the last stop now, so clear it.
[email protected]445e1042011-12-03 21:03:152889 completed_client_redirect_src_ = Referrer();
[email protected]3d9689372009-09-10 04:29:172890
2891 // Check whether we have new encoding name.
[email protected]26aa0482009-09-30 16:55:272892 UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
[email protected]3d9689372009-09-10 04:29:172893}
2894
[email protected]310ebd6302011-10-10 19:06:282895void RenderViewImpl::didClearWindowObject(WebFrame* frame) {
[email protected]9966325b2011-04-18 05:00:102896 FOR_EACH_OBSERVER(RenderViewObserver, observers_,
2897 DidClearWindowObject(frame));
2898
[email protected]b6cb3a842011-06-24 18:28:412899 GURL frame_url = frame->document().url();
[email protected]e091df82011-10-11 18:13:212900 if ((enabled_bindings_ & content::BINDINGS_POLICY_WEB_UI) &&
[email protected]bfa83eb82010-10-06 08:41:252901 (frame_url.SchemeIs(chrome::kChromeUIScheme) ||
2902 frame_url.SchemeIs(chrome::kDataScheme))) {
[email protected]c50008512011-02-03 01:17:272903 GetWebUIBindings()->BindToJavascript(frame, "chrome");
[email protected]3d9689372009-09-10 04:29:172904 }
[email protected]766a7082012-02-03 23:39:152905
2906 if (enabled_bindings_ & content::BINDINGS_POLICY_DOM_AUTOMATION) {
2907 if (!dom_automation_controller_.get())
2908 dom_automation_controller_.reset(new DomAutomationController());
2909 dom_automation_controller_->set_message_sender(
2910 static_cast<content::RenderView*>(this));
2911 dom_automation_controller_->set_routing_id(routing_id());
2912 dom_automation_controller_->BindToJavascript(frame,
2913 "domAutomationController");
2914 }
[email protected]3d9689372009-09-10 04:29:172915}
2916
[email protected]310ebd6302011-10-10 19:06:282917void RenderViewImpl::didCreateDocumentElement(WebFrame* frame) {
[email protected]3d9689372009-09-10 04:29:172918 // Notify the browser about non-blank documents loading in the top frame.
[email protected]b6cb3a842011-06-24 18:28:412919 GURL url = frame->document().url();
[email protected]e0d481582009-09-15 21:06:252920 if (url.is_valid() && url.spec() != chrome::kAboutBlankURL) {
[email protected]26aa0482009-09-30 16:55:272921 if (frame == webview()->mainFrame())
[email protected]3d9689372009-09-10 04:29:172922 Send(new ViewHostMsg_DocumentAvailableInMainFrame(routing_id_));
2923 }
[email protected]e48869a2011-04-01 19:56:032924
2925 FOR_EACH_OBSERVER(RenderViewObserver, observers_,
2926 DidCreateDocumentElement(frame));
[email protected]3d9689372009-09-10 04:29:172927}
2928
[email protected]310ebd6302011-10-10 19:06:282929void RenderViewImpl::didReceiveTitle(WebFrame* frame, const WebString& title,
2930 WebTextDirection direction) {
[email protected]a49e10b2011-08-01 23:57:462931 UpdateTitle(frame, title, direction);
[email protected]3d9689372009-09-10 04:29:172932
2933 // Also check whether we have new encoding name.
[email protected]26aa0482009-09-30 16:55:272934 UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
[email protected]3d9689372009-09-10 04:29:172935}
2936
[email protected]310ebd6302011-10-10 19:06:282937void RenderViewImpl::didChangeIcon(WebFrame* frame, WebIconURL::Type type) {
[email protected]42054a252011-05-17 18:02:132938 FOR_EACH_OBSERVER(RenderViewObserver, observers_,
2939 DidChangeIcon(frame, type));
[email protected]5019ef12010-04-27 17:26:582940}
2941
[email protected]310ebd6302011-10-10 19:06:282942void RenderViewImpl::didFinishDocumentLoad(WebFrame* frame) {
[email protected]3d9689372009-09-10 04:29:172943 WebDataSource* ds = frame->dataSource();
[email protected]007733c2011-11-17 00:34:072944 DocumentState* document_state = DocumentState::FromDataSource(ds);
2945 document_state->set_finish_document_load_time(Time::Now());
[email protected]3d9689372009-09-10 04:29:172946
[email protected]622474d2010-11-04 09:21:082947 Send(new ViewHostMsg_DocumentLoadedInFrame(routing_id_, frame->identifier()));
[email protected]3d9689372009-09-10 04:29:172948
[email protected]28685da92011-02-07 21:49:172949 FOR_EACH_OBSERVER(RenderViewObserver, observers_,
2950 DidFinishDocumentLoad(frame));
[email protected]3d9689372009-09-10 04:29:172951
2952 // Check whether we have new encoding name.
[email protected]26aa0482009-09-30 16:55:272953 UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
[email protected]3d9689372009-09-10 04:29:172954}
2955
[email protected]310ebd6302011-10-10 19:06:282956void RenderViewImpl::didHandleOnloadEvents(WebFrame* frame) {
[email protected]25497492010-09-11 15:15:082957 if (webview()->mainFrame() == frame) {
2958 Send(new ViewHostMsg_DocumentOnLoadCompletedInMainFrame(routing_id_,
2959 page_id_));
2960 }
[email protected]3d9689372009-09-10 04:29:172961}
2962
[email protected]310ebd6302011-10-10 19:06:282963void RenderViewImpl::didFailLoad(WebFrame* frame, const WebURLError& error) {
[email protected]1a55c5be2011-11-29 11:36:312964 WebDataSource* ds = frame->dataSource();
2965 DCHECK(ds);
2966
2967
[email protected]28685da92011-02-07 21:49:172968 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidFailLoad(frame, error));
[email protected]1a55c5be2011-11-29 11:36:312969
2970 const WebURLRequest& failed_request = ds->request();
2971 string16 error_description;
2972 content::GetContentClient()->renderer()->GetNavigationErrorStrings(
2973 failed_request,
2974 error,
2975 NULL,
2976 &error_description);
2977 Send(new ViewHostMsg_DidFailLoadWithError(routing_id_,
2978 frame->identifier(),
2979 failed_request.url(),
2980 !frame->parent(),
2981 error.reason,
2982 error_description));
[email protected]3d9689372009-09-10 04:29:172983}
2984
[email protected]310ebd6302011-10-10 19:06:282985void RenderViewImpl::didFinishLoad(WebFrame* frame) {
[email protected]3d9689372009-09-10 04:29:172986 WebDataSource* ds = frame->dataSource();
[email protected]007733c2011-11-17 00:34:072987 DocumentState* document_state = DocumentState::FromDataSource(ds);
2988 if (document_state->finish_load_time().is_null())
2989 document_state->set_finish_load_time(Time::Now());
[email protected]4d44a1c2010-04-28 19:20:412990
[email protected]676126f72011-01-15 00:03:512991 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidFinishLoad(frame));
[email protected]fdd94a02010-11-05 08:07:172992
[email protected]1a55c5be2011-11-29 11:36:312993 Send(new ViewHostMsg_DidFinishLoad(routing_id_,
2994 frame->identifier(),
2995 ds->request().url(),
2996 !frame->parent()));
[email protected]3d9689372009-09-10 04:29:172997}
2998
[email protected]310ebd6302011-10-10 19:06:282999void RenderViewImpl::didNavigateWithinPage(
[email protected]3d9689372009-09-10 04:29:173000 WebFrame* frame, bool is_new_navigation) {
3001 // If this was a reference fragment navigation that we initiated, then we
[email protected]007733c2011-11-17 00:34:073002 // could end up having a non-null pending navigation params. We just need to
[email protected]3d9689372009-09-10 04:29:173003 // update the ExtraData on the datasource so that others who read the
3004 // ExtraData will get the new NavigationState. Similarly, if we did not
3005 // initiate this navigation, then we need to take care to reset any pre-
3006 // existing navigation state to a content-initiated navigation state.
3007 // DidCreateDataSource conveniently takes care of this for us.
3008 didCreateDataSource(frame, frame->dataSource());
3009
[email protected]007733c2011-11-17 00:34:073010 DocumentState* document_state =
3011 DocumentState::FromDataSource(frame->dataSource());
3012 NavigationState* new_state = document_state->navigation_state();
[email protected]af15bed2010-08-25 21:12:093013 new_state->set_was_within_same_page(true);
3014
[email protected]3d9689372009-09-10 04:29:173015 didCommitProvisionalLoad(frame, is_new_navigation);
3016
[email protected]750fcf872011-08-03 23:10:473017 WebDataSource* datasource = frame->view()->mainFrame()->dataSource();
3018 UpdateTitle(frame, datasource->pageTitle(), datasource->pageTitleDirection());
[email protected]3d9689372009-09-10 04:29:173019}
3020
[email protected]310ebd6302011-10-10 19:06:283021void RenderViewImpl::didUpdateCurrentHistoryItem(WebFrame* frame) {
[email protected]882daa92009-11-05 16:31:313022 StartNavStateSyncTimerIfNecessary();
[email protected]476b6f82009-09-10 21:00:593023}
3024
[email protected]310ebd6302011-10-10 19:06:283025void RenderViewImpl::assignIdentifierToRequest(
[email protected]3d9689372009-09-10 04:29:173026 WebFrame* frame, unsigned identifier, const WebURLRequest& request) {
3027 // Ignore
3028}
3029
[email protected]310ebd6302011-10-10 19:06:283030void RenderViewImpl::willSendRequest(WebFrame* frame,
3031 unsigned identifier,
3032 WebURLRequest& request,
3033 const WebURLResponse& redirect_response) {
[email protected]5e369672009-11-03 23:48:303034 WebFrame* top_frame = frame->top();
3035 if (!top_frame)
3036 top_frame = frame;
[email protected]8a3125a712010-08-09 18:58:513037 WebDataSource* provisional_data_source = top_frame->provisionalDataSource();
3038 WebDataSource* top_data_source = top_frame->dataSource();
3039 WebDataSource* data_source =
3040 provisional_data_source ? provisional_data_source : top_data_source;
[email protected]78d5cfe2011-02-04 08:43:223041
[email protected]78d5cfe2011-02-04 08:43:223042 GURL request_url(request.url());
[email protected]e48869a2011-04-01 19:56:033043 GURL new_url;
3044 if (content::GetContentClient()->renderer()->WillSendRequest(
3045 frame, request_url, &new_url)) {
3046 request.setURL(WebURL(new_url));
[email protected]78d5cfe2011-02-04 08:43:223047 }
3048
[email protected]2905f742011-10-13 03:51:583049 content::PageTransition transition_type = content::PAGE_TRANSITION_LINK;
[email protected]007733c2011-11-17 00:34:073050 DocumentState* document_state = DocumentState::FromDataSource(data_source);
3051 NavigationState* navigation_state = document_state->navigation_state();
3052 if (document_state) {
3053 if (document_state->is_cache_policy_override_set())
3054 request.setCachePolicy(document_state->cache_policy_override());
3055 transition_type = navigation_state->transition_type();
[email protected]5e369672009-11-03 23:48:303056 }
[email protected]8a3125a712010-08-09 18:58:513057
[email protected]91043a8232011-11-04 16:41:193058 request.setExtraData(
[email protected]537fbe02011-11-24 00:58:063059 new RequestExtraData(frame->referrerPolicy(),
3060 (frame == top_frame),
[email protected]91043a8232011-11-04 16:41:193061 frame->identifier(),
3062 frame->parent() == top_frame,
3063 frame->parent() ? frame->parent()->identifier() : -1,
[email protected]4ad5d77d2011-12-03 02:00:483064 transition_type,
3065 navigation_state->transferred_request_child_id(),
3066 navigation_state->transferred_request_request_id()));
[email protected]d88bf0a2011-08-30 23:55:573067
[email protected]007733c2011-11-17 00:34:073068 DocumentState* top_document_state =
3069 DocumentState::FromDataSource(top_data_source);
[email protected]d88bf0a2011-08-30 23:55:573070 // TODO(gavinp): separate out prefetching and prerender field trials
3071 // if the rel=prerender rel type is sticking around.
[email protected]007733c2011-11-17 00:34:073072 if (top_document_state &&
[email protected]d88bf0a2011-08-30 23:55:573073 (request.targetType() == WebURLRequest::TargetIsPrefetch ||
3074 request.targetType() == WebURLRequest::TargetIsPrerender))
[email protected]007733c2011-11-17 00:34:073075 top_document_state->set_was_prefetcher(true);
[email protected]8a3125a712010-08-09 18:58:513076
[email protected]3d9689372009-09-10 04:29:173077 request.setRequestorID(routing_id_);
[email protected]cd448092010-12-06 23:49:133078 request.setHasUserGesture(frame->isProcessingUserGesture());
3079
[email protected]0a8db0d2011-04-13 15:15:403080 if (!renderer_preferences_.enable_referrers)
[email protected]7deade42010-03-05 09:33:133081 request.clearHTTPHeaderField("Referer");
[email protected]3d9689372009-09-10 04:29:173082}
3083
[email protected]310ebd6302011-10-10 19:06:283084void RenderViewImpl::didReceiveResponse(
[email protected]3d9689372009-09-10 04:29:173085 WebFrame* frame, unsigned identifier, const WebURLResponse& response) {
[email protected]fa0a3432010-03-30 16:53:493086
[email protected]3d9689372009-09-10 04:29:173087 // Only do this for responses that correspond to a provisional data source
3088 // of the top-most frame. If we have a provisional data source, then we
3089 // can't have any sub-resources yet, so we know that this response must
3090 // correspond to a frame load.
3091 if (!frame->provisionalDataSource() || frame->parent())
3092 return;
3093
3094 // If we are in view source mode, then just let the user see the source of
[email protected]3f853a52010-09-13 19:15:083095 // the server's error page.
[email protected]3d9689372009-09-10 04:29:173096 if (frame->isViewSourceModeEnabled())
3097 return;
3098
[email protected]007733c2011-11-17 00:34:073099 DocumentState* document_state =
3100 DocumentState::FromDataSource(frame->provisionalDataSource());
[email protected]3f853a52010-09-13 19:15:083101 int http_status_code = response.httpStatusCode();
[email protected]65041fa2010-05-21 06:56:533102
[email protected]972ebdff2010-06-10 22:59:073103 // Record page load flags.
[email protected]007733c2011-11-17 00:34:073104 document_state->set_was_fetched_via_spdy(response.wasFetchedViaSPDY());
3105 document_state->set_was_npn_negotiated(response.wasNpnNegotiated());
[email protected]b9fd01ba2012-02-28 01:50:403106 WebURLResponseExtraDataImpl* extra_data = GetExtraDataFromResponse(response);
3107 if (extra_data) {
3108 document_state->set_npn_negotiated_protocol(
3109 extra_data->npn_negotiated_protocol());
3110 }
[email protected]007733c2011-11-17 00:34:073111 document_state->set_was_alternate_protocol_available(
[email protected]193b0b892010-06-26 03:57:573112 response.wasAlternateProtocolAvailable());
[email protected]007733c2011-11-17 00:34:073113 document_state->set_was_fetched_via_proxy(response.wasFetchedViaProxy());
3114 document_state->set_http_status_code(http_status_code);
[email protected]06333afe2011-02-24 14:55:093115 // Whether or not the http status code actually corresponds to an error is
3116 // only checked when the page is done loading, if |use_error_page| is
3117 // still true.
[email protected]007733c2011-11-17 00:34:073118 document_state->set_use_error_page(true);
[email protected]3d9689372009-09-10 04:29:173119}
3120
[email protected]310ebd6302011-10-10 19:06:283121void RenderViewImpl::didFinishResourceLoad(
[email protected]3d9689372009-09-10 04:29:173122 WebFrame* frame, unsigned identifier) {
[email protected]007733c2011-11-17 00:34:073123 DocumentState* document_state =
3124 DocumentState::FromDataSource(frame->dataSource());
3125 if (!document_state->use_error_page())
[email protected]3d9689372009-09-10 04:29:173126 return;
3127
[email protected]7bfc153f2011-09-23 22:00:203128 // Do not show error page when DevTools is attached.
3129 if (devtools_agent_->IsAttached())
3130 return;
3131
[email protected]06333afe2011-02-24 14:55:093132 // Display error page, if appropriate.
[email protected]007733c2011-11-17 00:34:073133 int http_status_code = document_state->http_status_code();
[email protected]3f853a52010-09-13 19:15:083134 if (http_status_code == 404) {
3135 // On 404s, try a remote search page as a fallback.
[email protected]b6cb3a842011-06-24 18:28:413136 const GURL& document_url = frame->document().url();
[email protected]3d9689372009-09-10 04:29:173137
[email protected]b6cb3a842011-06-24 18:28:413138 const GURL& error_page_url =
3139 GetAlternateErrorPageURL(document_url, HTTP_404);
[email protected]06333afe2011-02-24 14:55:093140 if (error_page_url.is_valid()) {
3141 WebURLError original_error;
[email protected]2e9706c2011-06-09 16:49:473142 original_error.domain = "http";
3143 original_error.reason = 404;
[email protected]b6cb3a842011-06-24 18:28:413144 original_error.unreachableURL = document_url;
[email protected]3d9689372009-09-10 04:29:173145
[email protected]007733c2011-11-17 00:34:073146 document_state->set_alt_error_page_fetcher(
[email protected]06333afe2011-02-24 14:55:093147 new AltErrorPageResourceFetcher(
3148 error_page_url, frame, original_error,
[email protected]6e806822011-11-19 01:51:083149 base::Bind(&RenderViewImpl::AltErrorPageFinished,
3150 base::Unretained(this))));
[email protected]06333afe2011-02-24 14:55:093151 return;
3152 }
3153 }
[email protected]3d9689372009-09-10 04:29:173154
[email protected]e6a2ce52011-10-08 01:40:133155 std::string error_domain;
3156 if (content::GetContentClient()->renderer()->HasErrorPage(
3157 http_status_code, &error_domain)) {
3158 WebURLError error;
3159 error.unreachableURL = frame->document().url();
3160 error.domain = WebString::fromUTF8(error_domain);
3161 error.reason = http_status_code;
3162
3163 LoadNavigationErrorPage(
3164 frame, frame->dataSource()->request(), error, std::string(), true);
3165 }
[email protected]3d9689372009-09-10 04:29:173166}
3167
[email protected]310ebd6302011-10-10 19:06:283168void RenderViewImpl::didFailResourceLoad(
[email protected]3d9689372009-09-10 04:29:173169 WebFrame* frame, unsigned identifier, const WebURLError& error) {
3170 // Ignore
3171}
3172
[email protected]310ebd6302011-10-10 19:06:283173void RenderViewImpl::didLoadResourceFromMemoryCache(
[email protected]3d9689372009-09-10 04:29:173174 WebFrame* frame, const WebURLRequest& request,
3175 const WebURLResponse& response) {
[email protected]84703292011-10-28 20:44:003176 // The recipients of this message have no use for data: URLs: they don't
3177 // affect the page's insecure content list and are not in the disk cache. To
3178 // prevent large (1M+) data: URLs from crashing in the IPC system, we simply
3179 // filter them out here.
3180 GURL url(request.url());
3181 if (url.SchemeIs("data"))
3182 return;
3183
[email protected]3d9689372009-09-10 04:29:173184 // Let the browser know we loaded a resource from the memory cache. This
3185 // message is needed to display the correct SSL indicators.
3186 Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(
3187 routing_id_,
[email protected]84703292011-10-28 20:44:003188 url,
[email protected]70435962011-08-02 20:13:283189 response.securityInfo(),
3190 request.httpMethod().utf8(),
3191 ResourceType::FromTargetType(request.targetType())));
[email protected]3d9689372009-09-10 04:29:173192}
3193
[email protected]310ebd6302011-10-10 19:06:283194void RenderViewImpl::didDisplayInsecureContent(WebFrame* frame) {
[email protected]e3d60e5d2009-09-25 21:08:293195 Send(new ViewHostMsg_DidDisplayInsecureContent(routing_id_));
3196}
3197
[email protected]310ebd6302011-10-10 19:06:283198void RenderViewImpl::didRunInsecureContent(
[email protected]92771112011-01-20 00:13:023199 WebFrame* frame, const WebSecurityOrigin& origin, const WebURL& target) {
[email protected]e3d60e5d2009-09-25 21:08:293200 Send(new ViewHostMsg_DidRunInsecureContent(
3201 routing_id_,
[email protected]92771112011-01-20 00:13:023202 origin.toString().utf8(),
3203 target));
[email protected]e3d60e5d2009-09-25 21:08:293204}
3205
[email protected]310ebd6302011-10-10 19:06:283206void RenderViewImpl::didAdoptURLLoader(WebKit::WebURLLoader* loader) {
[email protected]b00ba702011-08-17 01:41:033207 webkit_glue::WebURLLoaderImpl* loader_impl =
3208 static_cast<webkit_glue::WebURLLoaderImpl*>(loader);
3209 loader_impl->UpdateRoutingId(routing_id_);
3210}
3211
[email protected]310ebd6302011-10-10 19:06:283212void RenderViewImpl::didExhaustMemoryAvailableForScript(WebFrame* frame) {
[email protected]3d9689372009-09-10 04:29:173213 Send(new ViewHostMsg_JSOutOfMemory(routing_id_));
3214}
3215
[email protected]310ebd6302011-10-10 19:06:283216void RenderViewImpl::didCreateScriptContext(WebFrame* frame,
3217 v8::Handle<v8::Context> context,
[email protected]a00fe692012-02-27 05:52:583218 int extension_group,
[email protected]310ebd6302011-10-10 19:06:283219 int world_id) {
[email protected]5bc10932011-09-21 21:03:303220 content::GetContentClient()->renderer()->DidCreateScriptContext(
[email protected]a00fe692012-02-27 05:52:583221 frame, context, extension_group, world_id);
3222}
3223
3224void RenderViewImpl::didCreateScriptContext(WebFrame* frame,
3225 v8::Handle<v8::Context> context,
3226 int world_id) {
3227 content::GetContentClient()->renderer()->DidCreateScriptContext(
3228 frame, context, -1, world_id);
[email protected]0c882b282009-10-07 17:01:283229}
3230
[email protected]310ebd6302011-10-10 19:06:283231void RenderViewImpl::willReleaseScriptContext(WebFrame* frame,
3232 v8::Handle<v8::Context> context,
3233 int world_id) {
[email protected]5bc10932011-09-21 21:03:303234 content::GetContentClient()->renderer()->WillReleaseScriptContext(
3235 frame, context, world_id);
[email protected]0c882b282009-10-07 17:01:283236}
3237
[email protected]310ebd6302011-10-10 19:06:283238void RenderViewImpl::CheckPreferredSize() {
[email protected]d812fd12011-05-27 23:05:073239 // We don't always want to send the change messages over IPC, only if we've
3240 // been put in that mode by getting a |ViewMsg_EnablePreferredSizeChangedMode|
3241 // message.
3242 if (!send_preferred_size_changes_ || !webview())
3243 return;
3244
[email protected]705243f2010-05-05 19:58:073245 gfx::Size size(webview()->mainFrame()->contentsPreferredWidth(),
3246 webview()->mainFrame()->documentElementScrollHeight());
[email protected]8205d742010-10-22 23:51:533247
3248 // In the presence of zoom, these sizes are still reported as if unzoomed,
3249 // so we need to adjust.
3250 double zoom_factor = WebView::zoomLevelToZoomFactor(webview()->zoomLevel());
3251 size.set_width(static_cast<int>(size.width() * zoom_factor));
3252 size.set_height(static_cast<int>(size.height() * zoom_factor));
3253
[email protected]705243f2010-05-05 19:58:073254 if (size == preferred_size_)
3255 return;
[email protected]c27324b2009-11-19 22:44:293256
[email protected]705243f2010-05-05 19:58:073257 preferred_size_ = size;
3258 Send(new ViewHostMsg_DidContentsPreferredSizeChange(routing_id_,
3259 preferred_size_));
[email protected]3d9689372009-09-10 04:29:173260}
3261
[email protected]273558fb2012-01-12 15:03:513262void RenderViewImpl::EnsureMediaStreamImpl() {
3263#if defined(ENABLE_P2P_APIS)
3264 if (!p2p_socket_dispatcher_)
3265 p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this);
3266#endif
3267
[email protected]5b87e782012-02-09 18:19:323268#if defined(ENABLE_WEBRTC)
[email protected]273558fb2012-01-12 15:03:513269 if (!media_stream_dispatcher_)
3270 media_stream_dispatcher_ = new MediaStreamDispatcher(this);
3271
3272 if (!media_stream_impl_.get()) {
3273 MediaStreamDependencyFactory* factory = new MediaStreamDependencyFactory();
3274 media_stream_impl_ = new MediaStreamImpl(
3275 media_stream_dispatcher_,
3276 p2p_socket_dispatcher_,
3277 RenderThreadImpl::current()->video_capture_impl_manager(),
3278 factory);
3279 }
[email protected]5b87e782012-02-09 18:19:323280#endif
[email protected]273558fb2012-01-12 15:03:513281}
3282
[email protected]310ebd6302011-10-10 19:06:283283void RenderViewImpl::didChangeContentsSize(WebFrame* frame,
3284 const WebSize& size) {
[email protected]dd6afca2011-08-13 03:44:313285 if (webview()->mainFrame() != frame)
3286 return;
3287 WebView* frameView = frame->view();
3288 if (!frameView)
3289 return;
3290
3291 bool has_horizontal_scrollbar = frame->hasHorizontalScrollbar();
3292 bool has_vertical_scrollbar = frame->hasVerticalScrollbar();
3293
3294 if (has_horizontal_scrollbar != cached_has_main_frame_horizontal_scrollbar_ ||
3295 has_vertical_scrollbar != cached_has_main_frame_vertical_scrollbar_) {
3296 Send(new ViewHostMsg_DidChangeScrollbarsForMainFrame(
3297 routing_id_, has_horizontal_scrollbar, has_vertical_scrollbar));
3298
3299 cached_has_main_frame_horizontal_scrollbar_ = has_horizontal_scrollbar;
3300 cached_has_main_frame_vertical_scrollbar_ = has_vertical_scrollbar;
3301 }
3302}
3303
[email protected]310ebd6302011-10-10 19:06:283304void RenderViewImpl::UpdateScrollState(WebFrame* frame) {
[email protected]dd6afca2011-08-13 03:44:313305 WebSize offset = frame->scrollOffset();
3306 WebSize minimum_offset = frame->minimumScrollOffset();
3307 WebSize maximum_offset = frame->maximumScrollOffset();
3308
3309 bool is_pinned_to_left = offset.width <= minimum_offset.width;
3310 bool is_pinned_to_right = offset.width >= maximum_offset.width;
3311
3312 if (is_pinned_to_left != cached_is_main_frame_pinned_to_left_ ||
3313 is_pinned_to_right != cached_is_main_frame_pinned_to_right_) {
3314 Send(new ViewHostMsg_DidChangeScrollOffsetPinningForMainFrame(
3315 routing_id_, is_pinned_to_left, is_pinned_to_right));
3316
3317 cached_is_main_frame_pinned_to_left_ = is_pinned_to_left;
3318 cached_is_main_frame_pinned_to_right_ = is_pinned_to_right;
3319 }
3320}
3321
[email protected]310ebd6302011-10-10 19:06:283322void RenderViewImpl::didChangeScrollOffset(WebFrame* frame) {
[email protected]143dcd592009-11-06 21:33:493323 StartNavStateSyncTimerIfNecessary();
[email protected]dd6afca2011-08-13 03:44:313324
3325 if (webview()->mainFrame() == frame)
3326 UpdateScrollState(frame);
3327}
3328
[email protected]310ebd6302011-10-10 19:06:283329void RenderViewImpl::numberOfWheelEventHandlersChanged(unsigned num_handlers) {
[email protected]dd6afca2011-08-13 03:44:313330 Send(new ViewHostMsg_DidChangeNumWheelEvents(routing_id_, num_handlers));
[email protected]143dcd592009-11-06 21:33:493331}
3332
[email protected]ea931252012-02-15 22:01:033333void RenderViewImpl::numberOfTouchEventHandlersChanged(unsigned num_handlers) {
3334 Send(new ViewHostMsg_DidChangeNumTouchEvents(routing_id_, num_handlers));
3335}
3336
[email protected]310ebd6302011-10-10 19:06:283337void RenderViewImpl::reportFindInPageMatchCount(int request_id, int count,
3338 bool final_update) {
[email protected]e7c58a32010-08-13 19:47:113339 int active_match_ordinal = -1; // -1 = don't update active match ordinal
3340 if (!count)
3341 active_match_ordinal = 0;
3342
3343 IPC::Message* msg = new ViewHostMsg_Find_Reply(
3344 routing_id_,
3345 request_id,
3346 count,
3347 gfx::Rect(),
3348 active_match_ordinal,
3349 final_update);
3350
[email protected]8922e1f2009-10-03 05:01:263351 // If we have a message that has been queued up, then we should just replace
3352 // it. The ACK from the browser will make sure it gets sent when the browser
3353 // wants it.
3354 if (queued_find_reply_message_.get()) {
[email protected]8922e1f2009-10-03 05:01:263355 queued_find_reply_message_.reset(msg);
3356 } else {
3357 // Send the search result over to the browser process.
[email protected]e7c58a32010-08-13 19:47:113358 Send(msg);
[email protected]8922e1f2009-10-03 05:01:263359 }
3360}
3361
[email protected]310ebd6302011-10-10 19:06:283362void RenderViewImpl::reportFindInPageSelection(int request_id,
3363 int active_match_ordinal,
3364 const WebRect& selection_rect) {
[email protected]8922e1f2009-10-03 05:01:263365 // Send the search result over to the browser process.
3366 Send(new ViewHostMsg_Find_Reply(routing_id_,
3367 request_id,
3368 -1,
3369 selection_rect,
3370 active_match_ordinal,
3371 false));
3372}
3373
[email protected]310ebd6302011-10-10 19:06:283374void RenderViewImpl::openFileSystem(
[email protected]2b06a992010-08-21 05:48:223375 WebFrame* frame,
3376 WebFileSystem::Type type,
3377 long long size,
[email protected]d275d7a2010-11-03 01:34:493378 bool create,
[email protected]2b06a992010-08-21 05:48:223379 WebFileSystemCallbacks* callbacks) {
[email protected]c5a272d2010-09-27 18:37:083380 DCHECK(callbacks);
[email protected]2b06a992010-08-21 05:48:223381
[email protected]b6cb3a842011-06-24 18:28:413382 WebSecurityOrigin origin = frame->document().securityOrigin();
[email protected]753ab8c82011-11-21 20:25:563383 if (origin.isUnique()) {
3384 // Unique origins cannot store persistent state.
[email protected]c5a272d2010-09-27 18:37:083385 callbacks->didFail(WebKit::WebFileErrorAbort);
3386 return;
3387 }
[email protected]2b06a992010-08-21 05:48:223388
[email protected]c5a272d2010-09-27 18:37:083389 ChildThread::current()->file_system_dispatcher()->OpenFileSystem(
3390 GURL(origin.toString()), static_cast<fileapi::FileSystemType>(type),
[email protected]d275d7a2010-11-03 01:34:493391 size, create, new WebFileSystemCallbackDispatcher(callbacks));
[email protected]2b06a992010-08-21 05:48:223392}
3393
[email protected]310ebd6302011-10-10 19:06:283394void RenderViewImpl::queryStorageUsageAndQuota(
[email protected]10e5cf12011-04-13 04:10:403395 WebFrame* frame,
3396 WebStorageQuotaType type,
3397 WebStorageQuotaCallbacks* callbacks) {
3398 DCHECK(frame);
[email protected]b6cb3a842011-06-24 18:28:413399 WebSecurityOrigin origin = frame->document().securityOrigin();
[email protected]753ab8c82011-11-21 20:25:563400 if (origin.isUnique()) {
3401 // Unique origins cannot store persistent state.
[email protected]10e5cf12011-04-13 04:10:403402 callbacks->didFail(WebKit::WebStorageQuotaErrorAbort);
3403 return;
3404 }
3405 ChildThread::current()->quota_dispatcher()->QueryStorageUsageAndQuota(
[email protected]666bcc5c2011-07-29 06:25:533406 GURL(origin.toString()),
3407 static_cast<quota::StorageType>(type),
3408 QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks));
[email protected]10e5cf12011-04-13 04:10:403409}
3410
[email protected]310ebd6302011-10-10 19:06:283411void RenderViewImpl::requestStorageQuota(
[email protected]10e5cf12011-04-13 04:10:403412 WebFrame* frame,
3413 WebStorageQuotaType type,
3414 unsigned long long requested_size,
3415 WebStorageQuotaCallbacks* callbacks) {
3416 DCHECK(frame);
[email protected]b6cb3a842011-06-24 18:28:413417 WebSecurityOrigin origin = frame->document().securityOrigin();
[email protected]753ab8c82011-11-21 20:25:563418 if (origin.isUnique()) {
3419 // Unique origins cannot store persistent state.
[email protected]10e5cf12011-04-13 04:10:403420 callbacks->didFail(WebKit::WebStorageQuotaErrorAbort);
3421 return;
3422 }
3423 ChildThread::current()->quota_dispatcher()->RequestStorageQuota(
[email protected]666bcc5c2011-07-29 06:25:533424 routing_id(), GURL(origin.toString()),
3425 static_cast<quota::StorageType>(type), requested_size,
3426 QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks));
[email protected]10e5cf12011-04-13 04:10:403427}
3428
[email protected]8b5af492011-11-28 21:50:583429void RenderViewImpl::registerIntentService(
[email protected]ffc8bed2012-01-21 01:23:153430 WebFrame* frame, const WebIntentServiceInfo& service) {
[email protected]e6e35cd2011-12-22 19:37:063431 string16 title = service.title();
3432 if (title.empty())
3433 title = webview()->mainFrame()->document().title();
3434
[email protected]8b5af492011-11-28 21:50:583435 Send(new IntentsHostMsg_RegisterIntentService(routing_id_,
3436 service.action(),
3437 service.type(),
3438 service.url().spec().utf16(),
[email protected]e6e35cd2011-12-22 19:37:063439 title,
[email protected]8b5af492011-11-28 21:50:583440 service.disposition()));
3441}
3442
[email protected]ffc8bed2012-01-21 01:23:153443void RenderViewImpl::dispatchIntent(
3444 WebFrame* frame, const WebIntentRequest& intentRequest) {
3445 webkit_glue::WebIntentData intent_data(intentRequest.intent());
3446 int id = intents_host_->RegisterWebIntent(intentRequest);
[email protected]8b5af492011-11-28 21:50:583447 Send(new IntentsHostMsg_WebIntentDispatch(
[email protected]ffc8bed2012-01-21 01:23:153448 routing_id_, intent_data, id));
[email protected]8b5af492011-11-28 21:50:583449}
3450
[email protected]5fa3a062012-03-21 15:39:343451void RenderViewImpl::willOpenSocketStream(
3452 WebSocketStreamHandle* handle) {
3453 SocketStreamHandleData::AddToHandle(handle, routing_id_);
3454}
3455
[email protected]18d5be92011-07-25 18:00:193456// WebKit::WebPageSerializerClient implementation ------------------------------
3457
[email protected]310ebd6302011-10-10 19:06:283458void RenderViewImpl::didSerializeDataForFrame(
[email protected]18d5be92011-07-25 18:00:193459 const WebURL& frame_url,
3460 const WebCString& data,
3461 WebPageSerializerClient::PageSerializationStatus status) {
3462 Send(new ViewHostMsg_SendSerializedHtmlData(
3463 routing_id(),
3464 frame_url,
3465 data.data(),
3466 static_cast<int32>(status)));
3467}
3468
[email protected]a2ef54c2011-10-10 16:20:313469// content::RenderView implementation ------------------------------------------
3470
[email protected]310ebd6302011-10-10 19:06:283471bool RenderViewImpl::Send(IPC::Message* message) {
[email protected]a2ef54c2011-10-10 16:20:313472 return RenderWidget::Send(message);
3473}
3474
[email protected]82114f52012-03-20 22:53:413475int RenderViewImpl::GetRoutingID() const {
[email protected]a2ef54c2011-10-10 16:20:313476 return routing_id_;
3477}
3478
[email protected]82114f52012-03-20 22:53:413479int RenderViewImpl::GetPageId() const {
[email protected]a2ef54c2011-10-10 16:20:313480 return page_id_;
3481}
3482
[email protected]82114f52012-03-20 22:53:413483gfx::Size RenderViewImpl::GetSize() const {
[email protected]a2ef54c2011-10-10 16:20:313484 return size();
3485}
3486
[email protected]82114f52012-03-20 22:53:413487gfx::NativeViewId RenderViewImpl::GetHostWindow() const {
[email protected]a2ef54c2011-10-10 16:20:313488 return host_window();
3489}
3490
[email protected]82114f52012-03-20 22:53:413491WebPreferences& RenderViewImpl::GetWebkitPreferences() {
[email protected]a2ef54c2011-10-10 16:20:313492 return webkit_preferences_;
3493}
3494
[email protected]82114f52012-03-20 22:53:413495WebKit::WebView* RenderViewImpl::GetWebView() {
[email protected]a2ef54c2011-10-10 16:20:313496 return webview();
3497}
3498
[email protected]82114f52012-03-20 22:53:413499WebKit::WebNode RenderViewImpl::GetFocusedNode() const {
[email protected]a2ef54c2011-10-10 16:20:313500 if (!webview())
3501 return WebNode();
3502 WebFrame* focused_frame = webview()->focusedFrame();
3503 if (focused_frame) {
3504 WebDocument doc = focused_frame->document();
3505 if (!doc.isNull())
3506 return doc.focusedNode();
3507 }
3508
3509 return WebNode();
3510}
3511
[email protected]82114f52012-03-20 22:53:413512WebKit::WebNode RenderViewImpl::GetContextMenuNode() const {
[email protected]a2ef54c2011-10-10 16:20:313513 return context_menu_node_;
3514}
3515
[email protected]82114f52012-03-20 22:53:413516bool RenderViewImpl::IsEditableNode(const WebKit::WebNode& node) const {
[email protected]a2ef54c2011-10-10 16:20:313517 bool is_editable_node = false;
3518 if (!node.isNull()) {
3519 if (node.isContentEditable()) {
3520 is_editable_node = true;
3521 } else if (node.isElementNode()) {
3522 is_editable_node =
3523 node.toConst<WebElement>().isTextFormControlElement();
3524 }
3525 }
3526 return is_editable_node;
3527}
3528
[email protected]310ebd6302011-10-10 19:06:283529WebKit::WebPlugin* RenderViewImpl::CreatePlugin(
[email protected]a2ef54c2011-10-10 16:20:313530 WebKit::WebFrame* frame,
3531 const webkit::WebPluginInfo& info,
[email protected]82114f52012-03-20 22:53:413532 const WebKit::WebPluginParams& params) {
[email protected]a2ef54c2011-10-10 16:20:313533 bool pepper_plugin_was_registered = false;
3534 scoped_refptr<webkit::ppapi::PluginModule> pepper_module(
3535 pepper_delegate_.CreatePepperPluginModule(info,
3536 &pepper_plugin_was_registered));
3537 if (pepper_plugin_was_registered) {
3538 if (!pepper_module)
3539 return NULL;
3540 return new webkit::ppapi::WebPluginImpl(
3541 pepper_module.get(), params, pepper_delegate_.AsWeakPtr());
3542 }
3543
[email protected]34b27e442012-01-20 20:07:413544#if defined(USE_AURA)
3545 return NULL;
3546#else
[email protected]a2ef54c2011-10-10 16:20:313547 return new webkit::npapi::WebPluginImpl(
3548 frame, params, info.path, AsWeakPtr());
[email protected]34b27e442012-01-20 20:07:413549#endif
[email protected]a2ef54c2011-10-10 16:20:313550}
3551
[email protected]310ebd6302011-10-10 19:06:283552void RenderViewImpl::EvaluateScript(const string16& frame_xpath,
3553 const string16& jscript,
3554 int id,
3555 bool notify_result) {
[email protected]a2ef54c2011-10-10 16:20:313556 v8::Handle<v8::Value> result;
3557 WebFrame* web_frame = GetChildFrame(frame_xpath);
3558 if (web_frame)
3559 result = web_frame->executeScriptAndReturnValue(WebScriptSource(jscript));
3560 if (notify_result) {
3561 ListValue list;
3562 if (!result.IsEmpty() && web_frame) {
3563 v8::HandleScope handle_scope;
3564 v8::Local<v8::Context> context = web_frame->mainWorldScriptContext();
3565 v8::Context::Scope context_scope(context);
3566 V8ValueConverterImpl converter;
3567 converter.set_allow_date(true);
3568 converter.set_allow_regexp(true);
3569 list.Set(0, converter.FromV8Value(result, context));
3570 } else {
3571 list.Set(0, Value::CreateNullValue());
3572 }
3573 Send(new ViewHostMsg_ScriptEvalResponse(routing_id_, id, list));
3574 }
3575}
3576
[email protected]310ebd6302011-10-10 19:06:283577bool RenderViewImpl::ShouldDisplayScrollbars(int width, int height) const {
[email protected]a2ef54c2011-10-10 16:20:313578 return (!send_preferred_size_changes_ ||
3579 (disable_scrollbars_size_limit_.width() <= width ||
3580 disable_scrollbars_size_limit_.height() <= height));
3581}
3582
[email protected]82114f52012-03-20 22:53:413583int RenderViewImpl::GetEnabledBindings() const {
[email protected]a2ef54c2011-10-10 16:20:313584 return enabled_bindings_;
3585}
3586
[email protected]82114f52012-03-20 22:53:413587bool RenderViewImpl::GetContentStateImmediately() const {
[email protected]a2ef54c2011-10-10 16:20:313588 return send_content_state_immediately_;
3589}
3590
[email protected]82114f52012-03-20 22:53:413591float RenderViewImpl::GetFilteredTimePerFrame() const {
[email protected]a2ef54c2011-10-10 16:20:313592 return filtered_time_per_frame();
3593}
3594
[email protected]310ebd6302011-10-10 19:06:283595void RenderViewImpl::ShowContextMenu(WebKit::WebFrame* frame,
[email protected]82114f52012-03-20 22:53:413596 const WebKit::WebContextMenuData& data) {
[email protected]a2ef54c2011-10-10 16:20:313597 showContextMenu(frame, data);
3598}
3599
[email protected]82114f52012-03-20 22:53:413600WebKit::WebPageVisibilityState RenderViewImpl::GetVisibilityState() const {
[email protected]a2ef54c2011-10-10 16:20:313601 return visibilityState();
3602}
3603
[email protected]310ebd6302011-10-10 19:06:283604void RenderViewImpl::RunModalAlertDialog(WebKit::WebFrame* frame,
3605 const WebKit::WebString& message) {
[email protected]a2ef54c2011-10-10 16:20:313606 return runModalAlertDialog(frame, message);
3607}
3608
[email protected]310ebd6302011-10-10 19:06:283609void RenderViewImpl::LoadURLExternally(
[email protected]a2ef54c2011-10-10 16:20:313610 WebKit::WebFrame* frame,
3611 const WebKit::WebURLRequest& request,
3612 WebKit::WebNavigationPolicy policy) {
3613 loadURLExternally(frame, request, policy);
3614}
3615
3616// webkit_glue::WebPluginPageDelegate ------------------------------------------
[email protected]79dbc662009-09-04 05:42:513617
[email protected]310ebd6302011-10-10 19:06:283618webkit::npapi::WebPluginDelegate* RenderViewImpl::CreatePluginDelegate(
[email protected]4e0616e2010-05-28 14:55:533619 const FilePath& file_path,
3620 const std::string& mime_type) {
[email protected]94752ee2012-02-10 10:38:203621 if (!PluginChannelHost::IsListening()) {
3622 LOG(ERROR) << "PluginChannelHost isn't listening";
[email protected]f103ab72009-09-02 17:10:593623 return NULL;
[email protected]94752ee2012-02-10 10:38:203624 }
[email protected]f103ab72009-09-02 17:10:593625
[email protected]00c39612010-03-06 02:53:283626 bool in_process_plugin = RenderProcess::current()->UseInProcessPlugins();
[email protected]d032f492009-09-29 00:33:463627 if (in_process_plugin) {
[email protected]7398dcc2011-09-06 21:40:323628#if defined(OS_WIN) && !defined(USE_AURA)
[email protected]e8f7a182011-03-10 00:50:223629 return webkit::npapi::WebPluginDelegateImpl::Create(
3630 file_path, mime_type, gfx::NativeViewFromId(host_window_));
[email protected]6876dff2010-01-15 19:38:093631#else
[email protected]7398dcc2011-09-06 21:40:323632 // In-proc plugins aren't supported on non-Windows.
[email protected]e8f7a182011-03-10 00:50:223633 NOTIMPLEMENTED();
3634 return NULL;
[email protected]7b6616f2010-01-14 18:07:553635#endif
[email protected]f103ab72009-09-02 17:10:593636 }
3637
[email protected]4e0616e2010-05-28 14:55:533638 return new WebPluginDelegateProxy(mime_type, AsWeakPtr());
[email protected]f103ab72009-09-02 17:10:593639}
3640
[email protected]310ebd6302011-10-10 19:06:283641void RenderViewImpl::CreatedPluginWindow(gfx::PluginWindowHandle window) {
[email protected]6981f7f2010-03-09 00:53:033642#if defined(USE_X11)
[email protected]380244092011-10-07 17:26:273643 Send(new ViewHostMsg_CreatePluginContainer(routing_id(), window));
[email protected]f103ab72009-09-02 17:10:593644#endif
3645}
3646
[email protected]310ebd6302011-10-10 19:06:283647void RenderViewImpl::WillDestroyPluginWindow(gfx::PluginWindowHandle window) {
[email protected]6981f7f2010-03-09 00:53:033648#if defined(USE_X11)
[email protected]380244092011-10-07 17:26:273649 Send(new ViewHostMsg_DestroyPluginContainer(routing_id(), window));
[email protected]f103ab72009-09-02 17:10:593650#endif
3651 CleanupWindowInPluginMoves(window);
3652}
3653
[email protected]310ebd6302011-10-10 19:06:283654void RenderViewImpl::DidMovePlugin(
3655 const webkit::npapi::WebPluginGeometry& move) {
[email protected]f103ab72009-09-02 17:10:593656 SchedulePluginMove(move);
3657}
3658
[email protected]310ebd6302011-10-10 19:06:283659void RenderViewImpl::DidStartLoadingForPlugin() {
[email protected]f103ab72009-09-02 17:10:593660 // TODO(darin): Make is_loading_ be a counter!
[email protected]48c9cf2d2009-09-16 16:47:523661 didStartLoading();
[email protected]f103ab72009-09-02 17:10:593662}
3663
[email protected]310ebd6302011-10-10 19:06:283664void RenderViewImpl::DidStopLoadingForPlugin() {
[email protected]f103ab72009-09-02 17:10:593665 // TODO(darin): Make is_loading_ be a counter!
[email protected]48c9cf2d2009-09-16 16:47:523666 didStopLoading();
[email protected]f103ab72009-09-02 17:10:593667}
3668
[email protected]310ebd6302011-10-10 19:06:283669WebCookieJar* RenderViewImpl::GetCookieJar() {
[email protected]b921cfd22010-02-25 16:57:513670 return &cookie_jar_;
3671}
3672
[email protected]a9288f52011-11-17 05:18:163673void RenderViewImpl::DidPlay(webkit_media::WebMediaPlayerImpl* player) {
[email protected]baff4512011-10-19 18:21:073674 Send(new ViewHostMsg_MediaNotification(routing_id_,
3675 reinterpret_cast<int64>(player),
3676 player->hasVideo(),
3677 player->hasAudio(),
3678 true));
3679}
3680
[email protected]a9288f52011-11-17 05:18:163681void RenderViewImpl::DidPause(webkit_media::WebMediaPlayerImpl* player) {
[email protected]baff4512011-10-19 18:21:073682 Send(new ViewHostMsg_MediaNotification(routing_id_,
3683 reinterpret_cast<int64>(player),
3684 player->hasVideo(),
3685 player->hasAudio(),
3686 false));
3687}
3688
[email protected]a9288f52011-11-17 05:18:163689void RenderViewImpl::PlayerGone(webkit_media::WebMediaPlayerImpl* player) {
[email protected]baff4512011-10-19 18:21:073690 DidPause(player);
3691}
3692
[email protected]310ebd6302011-10-10 19:06:283693void RenderViewImpl::SyncNavigationState() {
initial.commit09911bf2008-07-26 23:55:293694 if (!webview())
3695 return;
3696
[email protected]26aa0482009-09-30 16:55:273697 const WebHistoryItem& item = webview()->mainFrame()->currentHistoryItem();
[email protected]6459800a2012-03-27 23:57:053698 SendUpdateState(item);
initial.commit09911bf2008-07-26 23:55:293699}
3700
[email protected]310ebd6302011-10-10 19:06:283701void RenderViewImpl::SyncSelectionIfRequired() {
[email protected]b781ff282011-08-20 06:19:363702 WebFrame* frame = webview()->focusedFrame();
[email protected]e99ef6f2011-10-16 01:13:003703 if (!frame)
3704 return;
[email protected]b781ff282011-08-20 06:19:363705
[email protected]e99ef6f2011-10-16 01:13:003706 string16 text;
3707 size_t offset;
[email protected]3c8c74c2012-03-15 07:34:523708 ui::Range range;
[email protected]e99ef6f2011-10-16 01:13:003709
[email protected]3c8c74c2012-03-15 07:34:523710 if (pepper_delegate_.IsPluginFocused()) {
3711 pepper_delegate_.GetSurroundingText(&text, &range);
[email protected]82114f52012-03-20 22:53:413712 offset = 0; // Pepper API does not support offset reporting.
[email protected]3c8c74c2012-03-15 07:34:523713 // TODO(kinaba): cut as needed.
[email protected]e99ef6f2011-10-16 01:13:003714 } else {
[email protected]3c8c74c2012-03-15 07:34:523715 size_t location, length;
3716 if (!webview()->caretOrSelectionRange(&location, &length))
3717 return;
3718
3719 range = ui::Range(location, location + length);
3720
3721 if (webview()->textInputType() != WebKit::WebTextInputTypeNone) {
3722 // If current focused element is editable, we will send 100 more chars
3723 // before and after selection. It is for input method surrounding text
3724 // feature.
3725 if (location > kExtraCharsBeforeAndAfterSelection)
3726 offset = location - kExtraCharsBeforeAndAfterSelection;
3727 else
3728 offset = 0;
3729 length = location + length - offset + kExtraCharsBeforeAndAfterSelection;
3730 WebRange webrange = WebRange::fromDocumentRange(frame, offset, length);
3731 if (!webrange.isNull())
3732 text = WebRange::fromDocumentRange(frame, offset, length).toPlainText();
3733 } else {
3734 offset = location;
3735 text = frame->selectionAsText();
3736 // http://crbug.com/101435
3737 // In some case, frame->selectionAsText() returned text's length is not
3738 // equal to the length returned from webview()->caretOrSelectionRange().
3739 // So we have to set the range according to text.length().
3740 range.set_end(range.start() + text.length());
3741 }
[email protected]b781ff282011-08-20 06:19:363742 }
3743
[email protected]b781ff282011-08-20 06:19:363744 // Sometimes we get repeated didChangeSelection calls from webkit when
3745 // the selection hasn't actually changed. We don't want to report these
3746 // because it will cause us to continually claim the X clipboard.
[email protected]e99ef6f2011-10-16 01:13:003747 if (selection_text_offset_ != offset ||
3748 selection_range_ != range ||
3749 selection_text_ != text) {
3750 selection_text_ = text;
3751 selection_text_offset_ = offset;
3752 selection_range_ = range;
3753 Send(new ViewHostMsg_SelectionChanged(routing_id_, text, offset, range));
3754 }
[email protected]b781ff282011-08-20 06:19:363755}
3756
[email protected]310ebd6302011-10-10 19:06:283757GURL RenderViewImpl::GetAlternateErrorPageURL(const GURL& failed_url,
3758 ErrorPageType error_type) {
[email protected]7ccddb8c2009-08-04 17:36:553759 if (failed_url.SchemeIsSecure()) {
initial.commit09911bf2008-07-26 23:55:293760 // If the URL that failed was secure, then the embedding web page was not
3761 // expecting a network attacker to be able to manipulate its contents. As
3762 // we fetch alternate error pages over HTTP, we would be allowing a network
3763 // attacker to manipulate the contents of the response if we tried to use
3764 // the link doctor here.
[email protected]810a52ef2010-01-08 01:22:153765 return GURL();
initial.commit09911bf2008-07-26 23:55:293766 }
3767
3768 // Grab the base URL from the browser process.
3769 if (!alternate_error_page_url_.is_valid())
[email protected]810a52ef2010-01-08 01:22:153770 return GURL();
initial.commit09911bf2008-07-26 23:55:293771
3772 // Strip query params from the failed URL.
3773 GURL::Replacements remove_params;
3774 remove_params.ClearUsername();
3775 remove_params.ClearPassword();
3776 remove_params.ClearQuery();
3777 remove_params.ClearRef();
[email protected]7ccddb8c2009-08-04 17:36:553778 const GURL url_to_send = failed_url.ReplaceComponents(remove_params);
[email protected]6fd28f642010-03-15 17:15:503779 std::string spec_to_send = url_to_send.spec();
3780 // Notify link doctor of the url truncation by sending of "?" at the end.
3781 if (failed_url.has_query())
[email protected]82114f52012-03-20 22:53:413782 spec_to_send.append("?");
initial.commit09911bf2008-07-26 23:55:293783
3784 // Construct the query params to send to link doctor.
3785 std::string params(alternate_error_page_url_.query());
3786 params.append("&url=");
[email protected]4a19be92011-09-22 14:25:023787 params.append(net::EscapeQueryParamValue(spec_to_send, true));
initial.commit09911bf2008-07-26 23:55:293788 params.append("&sourceid=chrome");
3789 params.append("&error=");
3790 switch (error_type) {
3791 case DNS_ERROR:
3792 params.append("dnserror");
3793 break;
3794
3795 case HTTP_404:
3796 params.append("http404");
3797 break;
3798
[email protected]5df266ac2008-10-15 19:50:133799 case CONNECTION_ERROR:
[email protected]e1f934b2009-01-26 20:41:333800 params.append("connectionfailure");
[email protected]5df266ac2008-10-15 19:50:133801 break;
3802
initial.commit09911bf2008-07-26 23:55:293803 default:
3804 NOTREACHED() << "unknown ErrorPageType";
3805 }
3806
3807 // OK, build the final url to return.
3808 GURL::Replacements link_doctor_params;
3809 link_doctor_params.SetQueryStr(params);
3810 GURL url = alternate_error_page_url_.ReplaceComponents(link_doctor_params);
3811 return url;
3812}
3813
[email protected]310ebd6302011-10-10 19:06:283814GURL RenderViewImpl::GetOpenerUrl() const {
[email protected]57b9396c2011-10-07 19:11:593815 if (opener_id_ == MSG_ROUTING_NONE || opener_suppressed_)
3816 return GURL();
3817 else
3818 return creator_url_;
3819}
3820
[email protected]69ddf852012-02-21 23:21:313821GURL RenderViewImpl::GetLoadingUrl(WebKit::WebFrame* frame) const {
3822 WebDataSource* ds = frame->dataSource();
3823 if (ds->hasUnreachableURL())
3824 return ds->unreachableURL();
3825
3826 const WebURLRequest& request = ds->request();
3827 return request.url();
3828}
3829
[email protected]310ebd6302011-10-10 19:06:283830WebUIBindings* RenderViewImpl::GetWebUIBindings() {
[email protected]c50008512011-02-03 01:17:273831 if (!web_ui_bindings_.get()) {
[email protected]a2ef54c2011-10-10 16:20:313832 web_ui_bindings_.reset(new WebUIBindings(
3833 static_cast<content::RenderView*>(this), routing_id_));
[email protected]c091c2c2010-09-17 19:05:463834 }
[email protected]c50008512011-02-03 01:17:273835 return web_ui_bindings_.get();
[email protected]c091c2c2010-09-17 19:05:463836}
3837
[email protected]310ebd6302011-10-10 19:06:283838WebKit::WebPlugin* RenderViewImpl::GetWebPluginFromPluginDocument() {
[email protected]0fdbf8c2010-07-08 20:33:013839 return webview()->mainFrame()->document().to<WebPluginDocument>().plugin();
[email protected]24a7f3c2010-03-25 08:26:493840}
3841
[email protected]310ebd6302011-10-10 19:06:283842void RenderViewImpl::OnFind(int request_id, const string16& search_text,
3843 const WebFindOptions& options) {
[email protected]26aa0482009-09-30 16:55:273844 WebFrame* main_frame = webview()->mainFrame();
[email protected]24a7f3c2010-03-25 08:26:493845
[email protected]872542532011-06-23 00:43:163846 // Check if the plugin still exists in the document.
3847 if (main_frame->document().isPluginDocument() &&
3848 GetWebPluginFromPluginDocument()) {
[email protected]24a7f3c2010-03-25 08:26:493849 if (options.findNext) {
3850 // Just navigate back/forward.
[email protected]0fdbf8c2010-07-08 20:33:013851 GetWebPluginFromPluginDocument()->selectFindResult(options.forward);
[email protected]24a7f3c2010-03-25 08:26:493852 } else {
[email protected]afdbd142010-07-10 08:01:233853 if (GetWebPluginFromPluginDocument()->startFind(
3854 search_text, options.matchCase, request_id)) {
[email protected]24a7f3c2010-03-25 08:26:493855 } else {
[email protected]e7c58a32010-08-13 19:47:113856 // Send "no results".
3857 Send(new ViewHostMsg_Find_Reply(routing_id_,
3858 request_id,
3859 0,
3860 gfx::Rect(),
3861 0,
3862 true));
[email protected]24a7f3c2010-03-25 08:26:493863 }
3864 }
3865 return;
3866 }
3867
[email protected]b4bb2502009-10-01 22:35:273868 WebFrame* frame_after_main = main_frame->traverseNext(true);
[email protected]26aa0482009-09-30 16:55:273869 WebFrame* focused_frame = webview()->focusedFrame();
initial.commit09911bf2008-07-26 23:55:293870 WebFrame* search_frame = focused_frame; // start searching focused frame.
3871
3872 bool multi_frame = (frame_after_main != main_frame);
3873
3874 // If we have multiple frames, we don't want to wrap the search within the
3875 // frame, so we check here if we only have main_frame in the chain.
3876 bool wrap_within_frame = !multi_frame;
3877
[email protected]b3f2b912009-04-09 16:18:523878 WebRect selection_rect;
initial.commit09911bf2008-07-26 23:55:293879 bool result = false;
3880
[email protected]7830da3e2009-11-06 16:27:263881 // If something is selected when we start searching it means we cannot just
3882 // increment the current match ordinal; we need to re-generate it.
3883 WebRange current_selection = focused_frame->selectionRange();
3884
initial.commit09911bf2008-07-26 23:55:293885 do {
[email protected]dd7daa82009-08-10 05:46:453886 result = search_frame->find(
[email protected]7ea066a2009-04-06 20:21:593887 request_id, search_text, options, wrap_within_frame, &selection_rect);
initial.commit09911bf2008-07-26 23:55:293888
3889 if (!result) {
3890 // don't leave text selected as you move to the next frame.
[email protected]a100d76bb2009-08-14 17:50:223891 search_frame->executeCommand(WebString::fromUTF8("Unselect"));
initial.commit09911bf2008-07-26 23:55:293892
3893 // Find the next frame, but skip the invisible ones.
3894 do {
3895 // What is the next frame to search? (we might be going backwards). Note
3896 // that we specify wrap=true so that search_frame never becomes NULL.
[email protected]7ea066a2009-04-06 20:21:593897 search_frame = options.forward ?
[email protected]b4bb2502009-10-01 22:35:273898 search_frame->traverseNext(true) :
3899 search_frame->traversePrevious(true);
[email protected]dd7daa82009-08-10 05:46:453900 } while (!search_frame->hasVisibleContent() &&
3901 search_frame != focused_frame);
initial.commit09911bf2008-07-26 23:55:293902
[email protected]884db412008-11-24 23:46:503903 // Make sure selection doesn't affect the search operation in new frame.
[email protected]a100d76bb2009-08-14 17:50:223904 search_frame->executeCommand(WebString::fromUTF8("Unselect"));
initial.commit09911bf2008-07-26 23:55:293905
3906 // If we have multiple frames and we have wrapped back around to the
3907 // focused frame, we need to search it once more allowing wrap within
3908 // the frame, otherwise it will report 'no match' if the focused frame has
3909 // reported matches, but no frames after the focused_frame contain a
3910 // match for the search word(s).
3911 if (multi_frame && search_frame == focused_frame) {
[email protected]dd7daa82009-08-10 05:46:453912 result = search_frame->find(
[email protected]7ea066a2009-04-06 20:21:593913 request_id, search_text, options, true, // Force wrapping.
3914 &selection_rect);
initial.commit09911bf2008-07-26 23:55:293915 }
3916 }
3917
[email protected]26aa0482009-09-30 16:55:273918 webview()->setFocusedFrame(search_frame);
initial.commit09911bf2008-07-26 23:55:293919 } while (!result && search_frame != focused_frame);
3920
[email protected]7830da3e2009-11-06 16:27:263921 if (options.findNext && current_selection.isNull()) {
[email protected]4f3dc372009-02-24 00:10:293922 // Force the main_frame to report the actual count.
[email protected]dd7daa82009-08-10 05:46:453923 main_frame->increaseMatchCount(0, request_id);
[email protected]4f3dc372009-02-24 00:10:293924 } else {
3925 // If nothing is found, set result to "0 of 0", otherwise, set it to
3926 // "-1 of 1" to indicate that we found at least one item, but we don't know
3927 // yet what is active.
3928 int ordinal = result ? -1 : 0; // -1 here means, we might know more later.
3929 int match_count = result ? 1 : 0; // 1 here means possibly more coming.
initial.commit09911bf2008-07-26 23:55:293930
[email protected]4f3dc372009-02-24 00:10:293931 // If we find no matches then this will be our last status update.
3932 // Otherwise the scoping effort will send more results.
3933 bool final_status_update = !result;
initial.commit09911bf2008-07-26 23:55:293934
[email protected]4f3dc372009-02-24 00:10:293935 // Send the search result over to the browser process.
[email protected]4f999132009-03-31 18:08:403936 Send(new ViewHostMsg_Find_Reply(routing_id_,
[email protected]7ea066a2009-04-06 20:21:593937 request_id,
[email protected]4f3dc372009-02-24 00:10:293938 match_count,
3939 selection_rect,
3940 ordinal,
3941 final_status_update));
initial.commit09911bf2008-07-26 23:55:293942
initial.commit09911bf2008-07-26 23:55:293943 // Scoping effort begins, starting with the mainframe.
3944 search_frame = main_frame;
3945
[email protected]dd7daa82009-08-10 05:46:453946 main_frame->resetMatchCount();
initial.commit09911bf2008-07-26 23:55:293947
3948 do {
3949 // Cancel all old scoping requests before starting a new one.
[email protected]dd7daa82009-08-10 05:46:453950 search_frame->cancelPendingScopingEffort();
initial.commit09911bf2008-07-26 23:55:293951
3952 // We don't start another scoping effort unless at least one match has
3953 // been found.
3954 if (result) {
3955 // Start new scoping request. If the scoping function determines that it
3956 // needs to scope, it will defer until later.
[email protected]dd7daa82009-08-10 05:46:453957 search_frame->scopeStringMatches(request_id,
[email protected]7ea066a2009-04-06 20:21:593958 search_text,
3959 options,
initial.commit09911bf2008-07-26 23:55:293960 true); // reset the tickmarks
3961 }
3962
3963 // Iterate to the next frame. The frame will not necessarily scope, for
3964 // example if it is not visible.
[email protected]b4bb2502009-10-01 22:35:273965 search_frame = search_frame->traverseNext(true);
initial.commit09911bf2008-07-26 23:55:293966 } while (search_frame != main_frame);
3967 }
3968}
3969
[email protected]815dd9872011-11-23 18:40:303970void RenderViewImpl::OnStopFinding(content::StopFindAction action) {
[email protected]24a7f3c2010-03-25 08:26:493971 WebView* view = webview();
3972 if (!view)
3973 return;
3974
3975 WebDocument doc = view->mainFrame()->document();
[email protected]872542532011-06-23 00:43:163976 if (doc.isPluginDocument() && GetWebPluginFromPluginDocument()) {
[email protected]0fdbf8c2010-07-08 20:33:013977 GetWebPluginFromPluginDocument()->stopFind();
[email protected]24a7f3c2010-03-25 08:26:493978 return;
3979 }
3980
[email protected]815dd9872011-11-23 18:40:303981 bool clear_selection = action == content::STOP_FIND_ACTION_CLEAR_SELECTION;
[email protected]24a7f3c2010-03-25 08:26:493982 if (clear_selection)
3983 view->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect"));
3984
3985 WebFrame* frame = view->mainFrame();
3986 while (frame) {
3987 frame->stopFinding(clear_selection);
3988 frame = frame->traverseNext(false);
3989 }
3990
[email protected]815dd9872011-11-23 18:40:303991 if (action == content::STOP_FIND_ACTION_ACTIVATE_SELECTION) {
[email protected]24a7f3c2010-03-25 08:26:493992 WebFrame* focused_frame = view->focusedFrame();
3993 if (focused_frame) {
3994 WebDocument doc = focused_frame->document();
3995 if (!doc.isNull()) {
3996 WebNode node = doc.focusedNode();
3997 if (!node.isNull())
3998 node.simulateClick();
3999 }
4000 }
4001 }
4002}
4003
[email protected]310ebd6302011-10-10 19:06:284004void RenderViewImpl::OnFindReplyAck() {
[email protected]24a7f3c2010-03-25 08:26:494005 // Check if there is any queued up request waiting to be sent.
4006 if (queued_find_reply_message_.get()) {
4007 // Send the search result over to the browser process.
[email protected]d22d8732010-05-04 19:24:424008 Send(queued_find_reply_message_.release());
[email protected]24a7f3c2010-03-25 08:26:494009 }
4010}
4011
[email protected]54087fe2011-10-28 22:02:484012void RenderViewImpl::OnZoom(content::PageZoom zoom) {
[email protected]40bd6582009-12-04 23:49:514013 if (!webview()) // Not sure if this can happen, but no harm in being safe.
4014 return;
4015
[email protected]258d31122010-05-09 10:59:414016 webview()->hidePopups();
[email protected]854ab5462011-11-22 20:48:104017
[email protected]b75b8292010-10-01 07:28:254018 double old_zoom_level = webview()->zoomLevel();
4019 double zoom_level;
[email protected]54087fe2011-10-28 22:02:484020 if (zoom == content::PAGE_ZOOM_RESET) {
[email protected]b75b8292010-10-01 07:28:254021 zoom_level = 0;
4022 } else if (static_cast<int>(old_zoom_level) == old_zoom_level) {
4023 // Previous zoom level is a whole number, so just increment/decrement.
[email protected]54087fe2011-10-28 22:02:484024 zoom_level = old_zoom_level + zoom;
[email protected]b75b8292010-10-01 07:28:254025 } else {
4026 // Either the user hit the zoom factor limit and thus the zoom level is now
4027 // not a whole number, or a plugin changed it to a custom value. We want
4028 // to go to the next whole number so that the user can always get back to
4029 // 100% with the keyboard/menu.
[email protected]54087fe2011-10-28 22:02:484030 if ((old_zoom_level > 1 && zoom > 0) ||
4031 (old_zoom_level < 1 && zoom < 0)) {
4032 zoom_level = static_cast<int>(old_zoom_level + zoom);
[email protected]b75b8292010-10-01 07:28:254033 } else {
4034 // We're going towards 100%, so first go to the next whole number.
4035 zoom_level = static_cast<int>(old_zoom_level);
4036 }
4037 }
[email protected]b75b8292010-10-01 07:28:254038 webview()->setZoomLevel(false, zoom_level);
[email protected]47578fa02011-11-02 19:34:414039 zoomLevelChanged();
4040}
4041
4042void RenderViewImpl::OnZoomFactor(content::PageZoom zoom,
4043 int zoom_center_x, int zoom_center_y) {
4044 ZoomFactorHelper(zoom, zoom_center_x, zoom_center_y,
4045 kScalingIncrementForGesture);
4046}
4047
4048void RenderViewImpl::ZoomFactorHelper(content::PageZoom zoom,
4049 int zoom_center_x,
4050 int zoom_center_y,
4051 float scaling_increment) {
4052 if (!webview()) // Not sure if this can happen, but no harm in being safe.
4053 return;
4054
[email protected]c514d6372011-08-16 22:54:444055 double old_page_scale_factor = webview()->pageScaleFactor();
4056 double page_scale_factor;
[email protected]54087fe2011-10-28 22:02:484057 if (zoom == content::PAGE_ZOOM_RESET) {
[email protected]c514d6372011-08-16 22:54:444058 page_scale_factor = 1.0;
4059 } else {
4060 page_scale_factor = old_page_scale_factor +
[email protected]47578fa02011-11-02 19:34:414061 (zoom > 0 ? scaling_increment : -scaling_increment);
[email protected]c514d6372011-08-16 22:54:444062 }
[email protected]47578fa02011-11-02 19:34:414063 if (page_scale_factor > 0) {
[email protected]85191362011-11-08 18:53:094064 webview()->setPageScaleFactor(page_scale_factor,
4065 WebPoint(zoom_center_x, zoom_center_y));
[email protected]47578fa02011-11-02 19:34:414066 }
[email protected]40bd6582009-12-04 23:49:514067}
4068
[email protected]310ebd6302011-10-10 19:06:284069void RenderViewImpl::OnSetZoomLevel(double zoom_level) {
[email protected]d0b8d092010-10-25 04:05:174070 webview()->hidePopups();
4071 webview()->setZoomLevel(false, zoom_level);
4072 zoomLevelChanged();
4073}
4074
[email protected]310ebd6302011-10-10 19:06:284075void RenderViewImpl::OnSetZoomLevelForLoadingURL(const GURL& url,
4076 double zoom_level) {
[email protected]9d797f32010-04-23 07:17:544077 host_zoom_levels_[url] = zoom_level;
initial.commit09911bf2008-07-26 23:55:294078}
4079
[email protected]310ebd6302011-10-10 19:06:284080void RenderViewImpl::OnSetPageEncoding(const std::string& encoding_name) {
[email protected]26aa0482009-09-30 16:55:274081 webview()->setPageEncoding(WebString::fromUTF8(encoding_name));
initial.commit09911bf2008-07-26 23:55:294082}
4083
[email protected]310ebd6302011-10-10 19:06:284084void RenderViewImpl::OnResetPageEncodingToDefault() {
[email protected]26aa0482009-09-30 16:55:274085 WebString no_encoding;
4086 webview()->setPageEncoding(no_encoding);
[email protected]a697f4c2009-09-14 22:30:184087}
4088
[email protected]310ebd6302011-10-10 19:06:284089WebFrame* RenderViewImpl::GetChildFrame(const string16& xpath) const {
[email protected]dd7daa82009-08-10 05:46:454090 if (xpath.empty())
[email protected]26aa0482009-09-30 16:55:274091 return webview()->mainFrame();
[email protected]dd7daa82009-08-10 05:46:454092
4093 // xpath string can represent a frame deep down the tree (across multiple
4094 // frame DOMs).
4095 // Example, /html/body/table/tbody/tr/td/iframe\n/frameset/frame[0]
4096 // should break into 2 xpaths
4097 // /html/body/table/tbody/tr/td/iframe & /frameset/frame[0]
[email protected]318bf5802011-08-08 17:12:414098 std::vector<string16> xpaths;
4099 base::SplitString(xpath, '\n', &xpaths);
[email protected]dd7daa82009-08-10 05:46:454100
[email protected]26aa0482009-09-30 16:55:274101 WebFrame* frame = webview()->mainFrame();
[email protected]318bf5802011-08-08 17:12:414102 for (std::vector<string16>::const_iterator i = xpaths.begin();
4103 frame && i != xpaths.end(); ++i) {
4104 frame = frame->findChildByExpression(*i);
initial.commit09911bf2008-07-26 23:55:294105 }
4106
[email protected]dd7daa82009-08-10 05:46:454107 return frame;
initial.commit09911bf2008-07-26 23:55:294108}
4109
[email protected]310ebd6302011-10-10 19:06:284110void RenderViewImpl::OnScriptEvalRequest(const string16& frame_xpath,
4111 const string16& jscript,
4112 int id,
4113 bool notify_result) {
[email protected]882b7b22010-10-05 03:34:534114 EvaluateScript(frame_xpath, jscript, id, notify_result);
initial.commit09911bf2008-07-26 23:55:294115}
4116
[email protected]310ebd6302011-10-10 19:06:284117void RenderViewImpl::OnCSSInsertRequest(const string16& frame_xpath,
4118 const std::string& css) {
[email protected]b6cb3a842011-06-24 18:28:414119 WebFrame* frame = GetChildFrame(frame_xpath);
4120 if (!frame)
[email protected]216813952011-05-19 22:21:264121 return;
[email protected]ae461542009-06-19 19:03:414122
[email protected]01cf589c2011-07-28 18:04:034123 frame->document().insertUserStyleSheet(
4124 WebString::fromUTF8(css),
4125 WebDocument::UserStyleAuthorLevel);
[email protected]1810e132009-03-24 23:35:484126}
4127
[email protected]310ebd6302011-10-10 19:06:284128void RenderViewImpl::OnAllowBindings(int enabled_bindings_flags) {
[email protected]81e63782009-02-27 19:35:094129 enabled_bindings_ |= enabled_bindings_flags;
[email protected]744c2a22012-03-15 18:42:044130
4131 // Keep track of the total bindings accumulated in this process.
4132 RenderProcess::current()->AddBindings(enabled_bindings_flags);
initial.commit09911bf2008-07-26 23:55:294133}
4134
[email protected]310ebd6302011-10-10 19:06:284135void RenderViewImpl::OnSetWebUIProperty(const std::string& name,
4136 const std::string& value) {
[email protected]808bda52012-03-09 22:43:324137 if (enabled_bindings_ & content::BINDINGS_POLICY_WEB_UI)
4138 GetWebUIBindings()->SetProperty(name, value);
4139 else
4140 NOTREACHED() << "WebUI bindings not enabled.";
initial.commit09911bf2008-07-26 23:55:294141}
4142
[email protected]310ebd6302011-10-10 19:06:284143void RenderViewImpl::OnDragTargetDragEnter(const WebDropData& drop_data,
4144 const gfx::Point& client_point,
4145 const gfx::Point& screen_point,
4146 WebDragOperationsMask ops) {
[email protected]59f4f2fa2011-03-23 01:00:554147 WebDragOperation operation = webview()->dragTargetDragEnter(
4148 drop_data.ToDragData(),
[email protected]59f4f2fa2011-03-23 01:00:554149 client_point,
4150 screen_point,
4151 ops);
4152
4153 Send(new DragHostMsg_UpdateDragCursor(routing_id_, operation));
4154}
4155
[email protected]310ebd6302011-10-10 19:06:284156void RenderViewImpl::OnDragTargetDragOver(const gfx::Point& client_point,
4157 const gfx::Point& screen_point,
4158 WebDragOperationsMask ops) {
[email protected]59f4f2fa2011-03-23 01:00:554159 WebDragOperation operation = webview()->dragTargetDragOver(
4160 client_point,
4161 screen_point,
4162 ops);
4163
4164 Send(new DragHostMsg_UpdateDragCursor(routing_id_, operation));
4165}
4166
[email protected]310ebd6302011-10-10 19:06:284167void RenderViewImpl::OnDragTargetDragLeave() {
[email protected]59f4f2fa2011-03-23 01:00:554168 webview()->dragTargetDragLeave();
4169}
4170
[email protected]310ebd6302011-10-10 19:06:284171void RenderViewImpl::OnDragTargetDrop(const gfx::Point& client_point,
4172 const gfx::Point& screen_point) {
[email protected]59f4f2fa2011-03-23 01:00:554173 webview()->dragTargetDrop(client_point, screen_point);
[email protected]fcad49452011-06-28 17:11:574174
4175 Send(new DragHostMsg_TargetDrop_ACK(routing_id_));
[email protected]59f4f2fa2011-03-23 01:00:554176}
4177
[email protected]310ebd6302011-10-10 19:06:284178void RenderViewImpl::OnDragSourceEndedOrMoved(const gfx::Point& client_point,
4179 const gfx::Point& screen_point,
4180 bool ended,
4181 WebDragOperation op) {
[email protected]5f9ae6c2009-07-08 02:38:034182 if (ended) {
[email protected]26aa0482009-09-30 16:55:274183 webview()->dragSourceEndedAt(client_point, screen_point, op);
[email protected]daec5d62010-06-04 09:14:204184 } else {
4185 webview()->dragSourceMovedTo(client_point, screen_point, op);
[email protected]5f9ae6c2009-07-08 02:38:034186 }
initial.commit09911bf2008-07-26 23:55:294187}
4188
[email protected]310ebd6302011-10-10 19:06:284189void RenderViewImpl::OnDragSourceSystemDragEnded() {
[email protected]26aa0482009-09-30 16:55:274190 webview()->dragSourceSystemDragEnded();
initial.commit09911bf2008-07-26 23:55:294191}
4192
[email protected]310ebd6302011-10-10 19:06:284193void RenderViewImpl::OnUpdateWebPreferences(const WebPreferences& prefs) {
[email protected]2fab253a2009-08-17 23:00:594194 webkit_preferences_ = prefs;
4195 webkit_preferences_.Apply(webview());
initial.commit09911bf2008-07-26 23:55:294196}
4197
[email protected]310ebd6302011-10-10 19:06:284198void RenderViewImpl::OnSetAltErrorPageURL(const GURL& url) {
initial.commit09911bf2008-07-26 23:55:294199 alternate_error_page_url_ = url;
4200}
4201
[email protected]310ebd6302011-10-10 19:06:284202void RenderViewImpl::OnCustomContextMenuAction(
[email protected]35be7ec2012-02-12 20:42:514203 const content::CustomContextMenuContext& custom_context,
[email protected]b29aa74b2011-01-31 21:41:084204 unsigned action) {
4205 if (custom_context.is_pepper_menu)
4206 pepper_delegate_.OnCustomContextMenuAction(custom_context, action);
4207 else
4208 webview()->performCustomContextMenuAction(action);
[email protected]440a0e52011-09-13 17:38:584209 FOR_EACH_OBSERVER(RenderViewObserver, observers_,
4210 ContextMenuAction(action));
[email protected]a0c7153e2009-12-09 14:36:334211}
4212
[email protected]310ebd6302011-10-10 19:06:284213void RenderViewImpl::OnEnumerateDirectoryResponse(
[email protected]600ea402011-04-12 00:01:514214 int id,
4215 const std::vector<FilePath>& paths) {
4216 if (!enumeration_completions_[id])
4217 return;
4218
4219 WebVector<WebString> ws_file_names(paths.size());
4220 for (size_t i = 0; i < paths.size(); ++i)
4221 ws_file_names[i] = webkit_glue::FilePathToWebString(paths[i]);
4222
4223 enumeration_completions_[id]->didChooseFile(ws_file_names);
4224 enumeration_completions_.erase(id);
4225}
4226
[email protected]fb11b6a42012-03-14 07:25:124227void RenderViewImpl::OnFileChooserResponse(
4228 const std::vector<content::SelectedFileInfo>& files) {
[email protected]8029f5672009-03-20 22:33:364229 // This could happen if we navigated to a different page before the user
4230 // closed the chooser.
[email protected]cdaf8d02010-03-30 19:52:474231 if (file_chooser_completions_.empty())
[email protected]8029f5672009-03-20 22:33:364232 return;
4233
[email protected]b5188522012-03-15 00:18:044234 // Convert Chrome's SelectedFileInfo list to WebKit's.
4235 WebVector<WebFileChooserCompletion::SelectedFileInfo> selected_files(
4236 files.size());
4237 for (size_t i = 0; i < files.size(); ++i) {
4238 WebFileChooserCompletion::SelectedFileInfo selected_file;
4239 selected_file.path = webkit_glue::FilePathToWebString(files[i].path);
4240 selected_file.displayName = webkit_glue::FilePathStringToWebString(
4241 files[i].display_name);
4242 selected_files[i] = selected_file;
4243 }
[email protected]a1128322009-10-06 18:38:464244
[email protected]cdaf8d02010-03-30 19:52:474245 if (file_chooser_completions_.front()->completion)
[email protected]b5188522012-03-15 00:18:044246 file_chooser_completions_.front()->completion->didChooseFile(
4247 selected_files);
[email protected]cdaf8d02010-03-30 19:52:474248 file_chooser_completions_.pop_front();
4249
4250 // If there are more pending file chooser requests, schedule one now.
4251 if (!file_chooser_completions_.empty()) {
4252 Send(new ViewHostMsg_RunFileChooser(routing_id_,
4253 file_chooser_completions_.front()->params));
4254 }
initial.commit09911bf2008-07-26 23:55:294255}
4256
[email protected]244ac1892011-12-02 17:04:474257void RenderViewImpl::OnEnableAutoResize(const gfx::Size& min_size,
4258 const gfx::Size& max_size) {
4259 DCHECK(disable_scrollbars_size_limit_.IsEmpty());
4260 if (!webview())
4261 return;
[email protected]61e2b3cc2012-03-02 16:13:344262 webview()->enableAutoResizeMode(min_size, max_size);
4263}
4264
4265void RenderViewImpl::OnDisableAutoResize(const gfx::Size& new_size) {
4266 DCHECK(disable_scrollbars_size_limit_.IsEmpty());
4267 if (!webview())
4268 return;
4269 webview()->disableAutoResizeMode();
4270
4271 Resize(new_size, resizer_rect_, is_fullscreen_, NO_RESIZE_ACK);
[email protected]244ac1892011-12-02 17:04:474272}
4273
[email protected]2bf834f2011-11-17 20:02:214274void RenderViewImpl::OnEnablePreferredSizeChangedMode() {
[email protected]9fb325e2010-05-06 18:23:244275 if (send_preferred_size_changes_)
4276 return;
[email protected]9fb325e2010-05-06 18:23:244277 send_preferred_size_changes_ = true;
[email protected]770dd8b2010-05-24 18:11:394278
[email protected]d812fd12011-05-27 23:05:074279 // Start off with an initial preferred size notification (in case
4280 // |didUpdateLayout| was already called).
[email protected]169d4282011-11-30 19:33:594281 didUpdateLayout();
[email protected]0666aef2009-05-13 19:48:084282}
4283
[email protected]310ebd6302011-10-10 19:06:284284void RenderViewImpl::OnDisableScrollbarsForSmallWindows(
[email protected]cda45c02010-02-25 19:28:104285 const gfx::Size& disable_scrollbar_size_limit) {
4286 disable_scrollbars_size_limit_ = disable_scrollbar_size_limit;
4287}
4288
[email protected]310ebd6302011-10-10 19:06:284289void RenderViewImpl::OnSetRendererPrefs(
[email protected]daf82f82011-10-31 22:35:314290 const content::RendererPreferences& renderer_prefs) {
[email protected]d051d9a2011-12-10 02:02:504291 double old_zoom_level = renderer_preferences_.default_zoom_level;
[email protected]80d96fa2009-06-10 22:34:514292 renderer_preferences_ = renderer_prefs;
[email protected]6e282c92009-07-24 01:19:374293 UpdateFontRenderingFromRendererPrefs();
[email protected]0dd6f9b52010-10-14 16:39:134294#if defined(TOOLKIT_USES_GTK)
[email protected]1c83eb42009-09-11 21:08:414295 WebColorName name = WebKit::WebColorWebkitFocusRingColor;
4296 WebKit::setNamedColors(&name, &renderer_prefs.focus_ring_color, 1);
[email protected]39cd64ed2010-02-05 02:18:464297 WebKit::setCaretBlinkInterval(renderer_prefs.caret_blink_interval);
[email protected]42e5c862011-04-07 22:13:514298 gfx::NativeTheme::instance()->SetScrollbarColors(
[email protected]8d1b864d12010-10-10 00:04:344299 renderer_prefs.thumb_inactive_color,
4300 renderer_prefs.thumb_active_color,
4301 renderer_prefs.track_color);
[email protected]d299d972012-03-23 02:26:554302#endif
[email protected]93623c5d2009-12-10 21:40:324303
[email protected]d299d972012-03-23 02:26:554304#if defined(USE_ASH) || defined(TOOLKIT_USES_GTK)
[email protected]644d77e2010-01-27 01:03:104305 if (webview()) {
[email protected]d299d972012-03-23 02:26:554306#if defined(TOOLKIT_USES_GTK)
[email protected]93623c5d2009-12-10 21:40:324307 webview()->setScrollbarColors(
4308 renderer_prefs.thumb_inactive_color,
4309 renderer_prefs.thumb_active_color,
4310 renderer_prefs.track_color);
[email protected]d299d972012-03-23 02:26:554311#endif
[email protected]644d77e2010-01-27 01:03:104312 webview()->setSelectionColors(
4313 renderer_prefs.active_selection_bg_color,
4314 renderer_prefs.active_selection_fg_color,
4315 renderer_prefs.inactive_selection_bg_color,
4316 renderer_prefs.inactive_selection_fg_color);
[email protected]f98d7e3c2010-09-13 22:30:464317 webview()->themeChanged();
[email protected]644d77e2010-01-27 01:03:104318 }
[email protected]7a74e102009-09-03 00:16:564319#endif
[email protected]d299d972012-03-23 02:26:554320
[email protected]d051d9a2011-12-10 02:02:504321 // If the zoom level for this page matches the old zoom default, and this
4322 // is not a plugin, update the zoom level to match the new default.
4323 if (webview() && !webview()->mainFrame()->document().isPluginDocument() &&
4324 content::ZoomValuesEqual(webview()->zoomLevel(), old_zoom_level)) {
4325 webview()->setZoomLevel(false, renderer_preferences_.default_zoom_level);
4326 zoomLevelChanged();
4327 }
[email protected]80d96fa2009-06-10 22:34:514328}
4329
[email protected]310ebd6302011-10-10 19:06:284330void RenderViewImpl::OnMediaPlayerActionAt(const gfx::Point& location,
4331 const WebMediaPlayerAction& action) {
[email protected]952cb702009-10-07 05:50:284332 if (webview())
4333 webview()->performMediaPlayerAction(action, location);
[email protected]581b87eb2009-07-23 23:06:564334}
4335
[email protected]81375e872012-01-11 21:40:364336void RenderViewImpl::OnPluginActionAt(const gfx::Point& location,
4337 const WebPluginAction& action) {
4338 if (webview())
4339 webview()->performPluginAction(action, location);
4340}
4341
[email protected]310ebd6302011-10-10 19:06:284342void RenderViewImpl::OnGetAllSavableResourceLinksForCurrentPage(
[email protected]18d5be92011-07-25 18:00:194343 const GURL& page_url) {
4344 // Prepare list to storage all savable resource links.
4345 std::vector<GURL> resources_list;
4346 std::vector<GURL> referrers_list;
4347 std::vector<GURL> frames_list;
4348 webkit_glue::SavableResourcesResult result(&resources_list,
4349 &referrers_list,
4350 &frames_list);
4351
[email protected]445e1042011-12-03 21:03:154352 // FIXME(rdsmith): When GetAllSavableResourceLinksForCurrentPage starts to
4353 // return referrers, it should also return the referrer policies.
[email protected]18d5be92011-07-25 18:00:194354 if (!webkit_glue::GetAllSavableResourceLinksForCurrentPage(
4355 webview(),
4356 page_url,
4357 &result,
[email protected]0a35efc2012-03-13 17:28:134358 content::GetSavableSchemes())) {
[email protected]18d5be92011-07-25 18:00:194359 // If something is wrong when collecting all savable resource links,
4360 // send empty list to embedder(browser) to tell it failed.
4361 referrers_list.clear();
4362 resources_list.clear();
4363 frames_list.clear();
4364 }
4365
4366 // Send result of all savable resource links to embedder.
4367 Send(new ViewHostMsg_SendCurrentPageAllSavableResourceLinks(routing_id(),
4368 resources_list,
4369 referrers_list,
4370 frames_list));
4371}
4372
[email protected]310ebd6302011-10-10 19:06:284373void RenderViewImpl::OnGetSerializedHtmlDataForCurrentPageWithLocalLinks(
[email protected]18d5be92011-07-25 18:00:194374 const std::vector<GURL>& links,
4375 const std::vector<FilePath>& local_paths,
4376 const FilePath& local_directory_name) {
4377
4378 // Convert std::vector of GURLs to WebVector<WebURL>
4379 WebVector<WebURL> weburl_links(links);
4380
4381 // Convert std::vector of std::strings to WebVector<WebString>
4382 WebVector<WebString> webstring_paths(local_paths.size());
4383 for (size_t i = 0; i < local_paths.size(); i++)
4384 webstring_paths[i] = webkit_glue::FilePathToWebString(local_paths[i]);
4385
4386 WebPageSerializer::serialize(webview()->mainFrame(), true, this, weburl_links,
4387 webstring_paths,
4388 webkit_glue::FilePathToWebString(
4389 local_directory_name));
4390}
4391
[email protected]310ebd6302011-10-10 19:06:284392void RenderViewImpl::OnShouldClose() {
[email protected]7a17bac02012-03-07 21:58:124393 base::TimeTicks before_unload_start_time = base::TimeTicks::Now();
[email protected]26aa0482009-09-30 16:55:274394 bool should_close = webview()->dispatchBeforeUnloadEvent();
[email protected]7a17bac02012-03-07 21:58:124395 base::TimeTicks before_unload_end_time = base::TimeTicks::Now();
4396 Send(new ViewHostMsg_ShouldClose_ACK(routing_id_, should_close,
4397 before_unload_start_time,
4398 before_unload_end_time));
initial.commit09911bf2008-07-26 23:55:294399}
4400
[email protected]310ebd6302011-10-10 19:06:284401void RenderViewImpl::OnSwapOut(const ViewMsg_SwapOut_Params& params) {
[email protected]69ddf852012-02-21 23:21:314402 // Ensure that no other in-progress navigation continues.
4403 OnStop();
4404
[email protected]73eb2602012-02-09 19:50:554405 // Only run unload if we're not swapped out yet, but send the ack either way.
4406 if (!is_swapped_out_) {
4407 // Swap this RenderView out so the tab can navigate to a page rendered by a
4408 // different process. This involves running the unload handler and clearing
4409 // the page. Once WasSwappedOut is called, we also allow this process to
4410 // exit if there are no other active RenderViews in it.
[email protected]992db4c2011-05-12 15:37:154411
[email protected]73eb2602012-02-09 19:50:554412 // Send an UpdateState message before we get swapped out.
4413 SyncNavigationState();
[email protected]992db4c2011-05-12 15:37:154414
[email protected]73eb2602012-02-09 19:50:554415 // Synchronously run the unload handler before sending the ACK.
4416 webview()->dispatchUnloadEvent();
[email protected]992db4c2011-05-12 15:37:154417
[email protected]73eb2602012-02-09 19:50:554418 // Swap out and stop sending any IPC messages that are not ACKs.
4419 SetSwappedOut(true);
[email protected]992db4c2011-05-12 15:37:154420
[email protected]73eb2602012-02-09 19:50:554421 // Replace the page with a blank dummy URL. The unload handler will not be
4422 // run a second time, thanks to a check in FrameLoader::stopLoading.
[email protected]69ddf852012-02-21 23:21:314423 // We use loadRequest instead of loadHTMLString because the former commits
4424 // synchronously. Otherwise a new navigation can interrupt the navigation
[email protected]58436a12012-03-21 17:10:264425 // to chrome::kSwappedOutURL. If that happens to be to the page we had been
[email protected]69ddf852012-02-21 23:21:314426 // showing, then WebKit will never send a commit and we'll be left spinning.
[email protected]73eb2602012-02-09 19:50:554427 // TODO(creis): Need to add a better way to do this that avoids running the
4428 // beforeunload handler. For now, we just run it a second time silently.
[email protected]58436a12012-03-21 17:10:264429 GURL swappedOutURL(chrome::kSwappedOutURL);
4430 WebURLRequest request(swappedOutURL);
[email protected]69ddf852012-02-21 23:21:314431 webview()->mainFrame()->loadRequest(request);
[email protected]73eb2602012-02-09 19:50:554432 }
[email protected]992db4c2011-05-12 15:37:154433
4434 // Just echo back the params in the ACK.
4435 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params));
4436}
4437
[email protected]310ebd6302011-10-10 19:06:284438void RenderViewImpl::OnClosePage() {
[email protected]77fc9b92011-10-15 16:20:374439 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage());
initial.commit09911bf2008-07-26 23:55:294440 // TODO(creis): We'd rather use webview()->Close() here, but that currently
4441 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs
4442 // in the onunload handler from appearing. For now, we're bypassing that and
4443 // calling the FrameLoader's CloseURL method directly. This should be
4444 // revisited to avoid having two ways to close a page. Having a single way
4445 // to close that can run onunload is also useful for fixing
4446 // http://b/issue?id=753080.
[email protected]26aa0482009-09-30 16:55:274447 webview()->dispatchUnloadEvent();
initial.commit09911bf2008-07-26 23:55:294448
[email protected]992db4c2011-05-12 15:37:154449 Send(new ViewHostMsg_ClosePage_ACK(routing_id_));
initial.commit09911bf2008-07-26 23:55:294450}
4451
[email protected]310ebd6302011-10-10 19:06:284452void RenderViewImpl::OnThemeChanged() {
[email protected]e8d6b9f2011-10-10 22:21:024453#if defined(USE_AURA)
4454 // Aura doesn't care if we switch themes.
4455#elif defined(OS_WIN)
[email protected]c6d942212011-03-30 19:02:164456 gfx::NativeThemeWin::instance()->CloseHandles();
[email protected]f98d7e3c2010-09-13 22:30:464457 if (webview())
4458 webview()->themeChanged();
[email protected]6c8afae52009-01-22 02:24:574459#else // defined(OS_WIN)
4460 // TODO(port): we don't support theming on non-Windows platforms yet
4461 NOTIMPLEMENTED();
4462#endif
initial.commit09911bf2008-07-26 23:55:294463}
4464
[email protected]310ebd6302011-10-10 19:06:284465void RenderViewImpl::OnDisassociateFromPopupCount() {
[email protected]0aa55312008-10-17 21:53:084466 if (decrement_shared_popup_at_destruction_)
4467 shared_popup_counter_->data--;
4468 shared_popup_counter_ = new SharedRenderViewCounter(0);
4469 decrement_shared_popup_at_destruction_ = false;
4470}
4471
[email protected]310ebd6302011-10-10 19:06:284472bool RenderViewImpl::MaybeLoadAlternateErrorPage(WebFrame* frame,
4473 const WebURLError& error,
4474 bool replace) {
[email protected]15d79e12009-08-02 19:23:454475 // We only show alternate error pages in the main frame. They are
4476 // intended to assist the user when navigating, so there is not much
4477 // value in showing them for failed subframes. Ideally, we would be
4478 // able to use the TYPED transition type for this, but that flag is
4479 // not preserved across page reloads.
[email protected]dd7daa82009-08-10 05:46:454480 if (frame->parent())
[email protected]15d79e12009-08-02 19:23:454481 return false;
4482
4483 // Use the alternate error page service if this is a DNS failure or
[email protected]c53976d52009-08-07 18:58:374484 // connection failure.
[email protected]15d79e12009-08-02 19:23:454485 int ec = error.reason;
4486 if (ec != net::ERR_NAME_NOT_RESOLVED &&
4487 ec != net::ERR_CONNECTION_FAILED &&
4488 ec != net::ERR_CONNECTION_REFUSED &&
4489 ec != net::ERR_ADDRESS_UNREACHABLE &&
[email protected]82114f52012-03-20 22:53:414490 ec != net::ERR_CONNECTION_TIMED_OUT) {
[email protected]15d79e12009-08-02 19:23:454491 return false;
[email protected]82114f52012-03-20 22:53:414492 }
[email protected]15d79e12009-08-02 19:23:454493
4494 const GURL& error_page_url = GetAlternateErrorPageURL(error.unreachableURL,
[email protected]7ccddb8c2009-08-04 17:36:554495 ec == net::ERR_NAME_NOT_RESOLVED ? DNS_ERROR : CONNECTION_ERROR);
[email protected]15d79e12009-08-02 19:23:454496 if (!error_page_url.is_valid())
4497 return false;
4498
4499 // Load an empty page first so there is an immediate response to the error,
4500 // and then kick off a request for the alternate error page.
[email protected]dd7daa82009-08-10 05:46:454501 frame->loadHTMLString(std::string(),
[email protected]144143c2010-10-28 08:17:364502 GURL(chrome::kUnreachableWebDataURL),
[email protected]15d79e12009-08-02 19:23:454503 error.unreachableURL,
4504 replace);
4505
4506 // Now, create a fetcher for the error page and associate it with the data
4507 // source we just created via the LoadHTMLString call. That way if another
4508 // navigation occurs, the fetcher will get destroyed.
[email protected]007733c2011-11-17 00:34:074509 DocumentState* document_state =
4510 DocumentState::FromDataSource(frame->provisionalDataSource());
4511 document_state->set_alt_error_page_fetcher(
[email protected]15d79e12009-08-02 19:23:454512 new AltErrorPageResourceFetcher(
4513 error_page_url, frame, error,
[email protected]6e806822011-11-19 01:51:084514 base::Bind(&RenderViewImpl::AltErrorPageFinished,
4515 base::Unretained(this))));
[email protected]15d79e12009-08-02 19:23:454516 return true;
4517}
4518
[email protected]310ebd6302011-10-10 19:06:284519void RenderViewImpl::AltErrorPageFinished(WebFrame* frame,
4520 const WebURLError& original_error,
4521 const std::string& html) {
[email protected]15d79e12009-08-02 19:23:454522 // Here, we replace the blank page we loaded previously.
[email protected]06333afe2011-02-24 14:55:094523 // If we failed to download the alternate error page, LoadNavigationErrorPage
[email protected]7ccddb8c2009-08-04 17:36:554524 // will simply display a default error page.
[email protected]06333afe2011-02-24 14:55:094525 LoadNavigationErrorPage(frame, WebURLRequest(), original_error, html, true);
[email protected]15d79e12009-08-02 19:23:454526}
4527
[email protected]310ebd6302011-10-10 19:06:284528void RenderViewImpl::OnMoveOrResizeStarted() {
[email protected]30f75e62009-02-25 22:01:004529 if (webview())
[email protected]a72a1fa2010-05-03 22:18:474530 webview()->hidePopups();
[email protected]30f75e62009-02-25 22:01:004531}
4532
[email protected]310ebd6302011-10-10 19:06:284533void RenderViewImpl::OnResize(const gfx::Size& new_size,
[email protected]ee41e7d22011-10-14 19:34:094534 const gfx::Rect& resizer_rect,
4535 bool is_fullscreen) {
[email protected]cda45c02010-02-25 19:28:104536 if (webview()) {
[email protected]7ddea9802012-02-22 23:08:054537 // This setting has no effect if fixed layout is not enabled.
[email protected]43d9d782012-03-01 15:40:094538 if (webkit_preferences_.default_device_scale_factor)
[email protected]7ddea9802012-02-22 23:08:054539 webview()->settings()->setLayoutFallbackWidth(
[email protected]43d9d782012-03-01 15:40:094540 new_size.width() / webkit_preferences_.default_device_scale_factor);
[email protected]a72a1fa2010-05-03 22:18:474541 webview()->hidePopups();
[email protected]cda45c02010-02-25 19:28:104542 if (send_preferred_size_changes_) {
[email protected]7339cd22010-10-27 00:11:204543 webview()->mainFrame()->setCanHaveScrollbars(
[email protected]a2ef54c2011-10-10 16:20:314544 ShouldDisplayScrollbars(new_size.width(), new_size.height()));
[email protected]cda45c02010-02-25 19:28:104545 }
[email protected]dd6afca2011-08-13 03:44:314546 UpdateScrollState(webview()->mainFrame());
[email protected]cda45c02010-02-25 19:28:104547 }
4548
[email protected]ee41e7d22011-10-14 19:34:094549 RenderWidget::OnResize(new_size, resizer_rect, is_fullscreen);
[email protected]30f75e62009-02-25 22:01:004550}
[email protected]0aa477bd2009-03-23 22:21:434551
[email protected]29ed96a2012-02-04 18:12:164552void RenderViewImpl::WillInitiatePaint() {
4553 // Notify the pepper plugins that we're about to paint.
4554 pepper_delegate_.ViewWillInitiatePaint();
4555}
4556
[email protected]310ebd6302011-10-10 19:06:284557void RenderViewImpl::DidInitiatePaint() {
[email protected]29ed96a2012-02-04 18:12:164558 // Notify the pepper plugins that we've painted, and are waiting to flush.
[email protected]53900d52010-06-16 04:25:014559 pepper_delegate_.ViewInitiatedPaint();
[email protected]00c39612010-03-06 02:53:284560}
4561
[email protected]310ebd6302011-10-10 19:06:284562void RenderViewImpl::DidFlushPaint() {
[email protected]00c39612010-03-06 02:53:284563 // Notify any pepper plugins that we painted. This will call into the plugin,
4564 // and we it may ask to close itself as a result. This will, in turn, modify
4565 // our set, possibly invalidating the iterator. So we iterate on a copy that
4566 // won't change out from under us.
[email protected]53900d52010-06-16 04:25:014567 pepper_delegate_.ViewFlushedPaint();
4568
[email protected]5b1dec8c2012-02-07 04:35:384569 // If the RenderWidget is closing down then early-exit, otherwise we'll crash.
4570 // See crbug.com/112921.
4571 if (!webview())
4572 return;
4573
[email protected]00c39612010-03-06 02:53:284574 WebFrame* main_frame = webview()->mainFrame();
4575
4576 // If we have a provisional frame we are between the start and commit stages
4577 // of loading and we don't want to save stats.
4578 if (!main_frame->provisionalDataSource()) {
4579 WebDataSource* ds = main_frame->dataSource();
[email protected]007733c2011-11-17 00:34:074580 DocumentState* document_state = DocumentState::FromDataSource(ds);
[email protected]00c39612010-03-06 02:53:284581
[email protected]05c8e502010-08-15 15:13:524582 // TODO(jar): The following code should all be inside a method, probably in
4583 // NavigatorState.
[email protected]00c39612010-03-06 02:53:284584 Time now = Time::Now();
[email protected]007733c2011-11-17 00:34:074585 if (document_state->first_paint_time().is_null()) {
4586 document_state->set_first_paint_time(now);
[email protected]00c39612010-03-06 02:53:284587 }
[email protected]007733c2011-11-17 00:34:074588 if (document_state->first_paint_after_load_time().is_null() &&
4589 !document_state->finish_load_time().is_null()) {
4590 document_state->set_first_paint_after_load_time(now);
[email protected]00c39612010-03-06 02:53:284591 }
4592 }
4593}
4594
[email protected]310ebd6302011-10-10 19:06:284595void RenderViewImpl::OnViewContextSwapBuffersPosted() {
[email protected]37a6f302011-07-11 23:43:084596 RenderWidget::OnSwapBuffersPosted();
4597}
4598
[email protected]310ebd6302011-10-10 19:06:284599void RenderViewImpl::OnViewContextSwapBuffersComplete() {
[email protected]65225772011-05-12 21:10:244600 RenderWidget::OnSwapBuffersComplete();
4601}
4602
[email protected]310ebd6302011-10-10 19:06:284603void RenderViewImpl::OnViewContextSwapBuffersAborted() {
[email protected]65225772011-05-12 21:10:244604 RenderWidget::OnSwapBuffersAborted();
4605}
4606
[email protected]310ebd6302011-10-10 19:06:284607webkit::ppapi::PluginInstance* RenderViewImpl::GetBitmapForOptimizedPluginPaint(
[email protected]ca4847f2010-09-24 05:39:154608 const gfx::Rect& paint_bounds,
4609 TransportDIB** dib,
4610 gfx::Rect* location,
4611 gfx::Rect* clip) {
4612 return pepper_delegate_.GetBitmapForOptimizedPluginPaint(
4613 paint_bounds, dib, location, clip);
4614}
4615
[email protected]310ebd6302011-10-10 19:06:284616gfx::Point RenderViewImpl::GetScrollOffset() {
[email protected]d812fd12011-05-27 23:05:074617 WebSize scroll_offset = webview()->mainFrame()->scrollOffset();
[email protected]bcaf2272011-02-15 15:29:434618 return gfx::Point(scroll_offset.width, scroll_offset.height);
[email protected]d54169e92011-01-21 09:19:524619}
4620
[email protected]310ebd6302011-10-10 19:06:284621void RenderViewImpl::OnClearFocusedNode() {
[email protected]05d478752009-04-08 23:38:164622 if (webview())
[email protected]26aa0482009-09-30 16:55:274623 webview()->clearFocusedNode();
[email protected]05d478752009-04-08 23:38:164624}
4625
[email protected]310ebd6302011-10-10 19:06:284626void RenderViewImpl::OnSetBackground(const SkBitmap& background) {
[email protected]699ab0d2009-04-23 23:19:144627 if (webview())
[email protected]b4bb2502009-10-01 22:35:274628 webview()->setIsTransparent(!background.empty());
[email protected]699ab0d2009-04-23 23:19:144629
4630 SetBackground(background);
4631}
4632
[email protected]310ebd6302011-10-10 19:06:284633void RenderViewImpl::OnSetActive(bool active) {
[email protected]8c66c5a2009-07-22 17:26:344634 if (webview())
[email protected]b4bb2502009-10-01 22:35:274635 webview()->setIsActive(active);
[email protected]d8fd6fa2010-02-01 15:54:264636
4637#if defined(OS_MACOSX)
4638 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
4639 for (plugin_it = plugin_delegates_.begin();
4640 plugin_it != plugin_delegates_.end(); ++plugin_it) {
4641 (*plugin_it)->SetWindowFocus(active);
4642 }
4643#endif
[email protected]8c66c5a2009-07-22 17:26:344644}
4645
[email protected]7a17bac02012-03-07 21:58:124646void RenderViewImpl::OnSetNavigationStartTime(
4647 const base::TimeTicks& browser_navigation_start) {
4648 if (!webview())
4649 return;
4650
4651 // Only the initial navigation can be a cross-renderer navigation. If we've
4652 // already navigated away from that page, we can ignore this message.
4653 if (page_id_ != -1)
4654 return;
4655
4656 // browser_navigation_start is likely before this process existed, so we can't
4657 // use InterProcessTimeTicksConverter. Instead, the best we can do is just
4658 // ensure we don't report a bogus value in the future.
4659 base::TimeTicks navigation_start = std::min(base::TimeTicks::Now(),
4660 browser_navigation_start);
4661 webview()->mainFrame()->provisionalDataSource()->setNavigationStartTime(
4662 (navigation_start - base::TimeTicks()).InSecondsF());
4663}
4664
[email protected]6ce7abc52010-02-02 18:40:144665#if defined(OS_MACOSX)
[email protected]310ebd6302011-10-10 19:06:284666void RenderViewImpl::OnSetWindowVisibility(bool visible) {
[email protected]6ce7abc52010-02-02 18:40:144667 // Inform plugins that their container has changed visibility.
4668 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
4669 for (plugin_it = plugin_delegates_.begin();
4670 plugin_it != plugin_delegates_.end(); ++plugin_it) {
4671 (*plugin_it)->SetContainerVisibility(visible);
4672 }
4673}
[email protected]1e6e3c992010-02-08 15:52:134674
[email protected]310ebd6302011-10-10 19:06:284675void RenderViewImpl::OnWindowFrameChanged(const gfx::Rect& window_frame,
4676 const gfx::Rect& view_frame) {
[email protected]1e6e3c992010-02-08 15:52:134677 // Inform plugins that their window's frame has changed.
4678 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
4679 for (plugin_it = plugin_delegates_.begin();
4680 plugin_it != plugin_delegates_.end(); ++plugin_it) {
4681 (*plugin_it)->WindowFrameChanged(window_frame, view_frame);
4682 }
4683}
[email protected]935d63d2010-10-15 23:31:554684
[email protected]310ebd6302011-10-10 19:06:284685void RenderViewImpl::OnPluginImeCompositionCompleted(const string16& text,
4686 int plugin_id) {
[email protected]b7f75862011-01-21 21:15:134687 // WebPluginDelegateProxy is responsible for figuring out if this event
[email protected]935d63d2010-10-15 23:31:554688 // applies to it or not, so inform all the delegates.
4689 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
4690 for (plugin_it = plugin_delegates_.begin();
4691 plugin_it != plugin_delegates_.end(); ++plugin_it) {
[email protected]b7f75862011-01-21 21:15:134692 (*plugin_it)->ImeCompositionCompleted(text, plugin_id);
[email protected]935d63d2010-10-15 23:31:554693 }
4694}
[email protected]6ce7abc52010-02-02 18:40:144695#endif // OS_MACOSX
4696
[email protected]310ebd6302011-10-10 19:06:284697void RenderViewImpl::OnSetEditCommandsForNextKeyEvent(
[email protected]446705872009-09-10 07:22:484698 const EditCommands& edit_commands) {
4699 edit_commands_ = edit_commands;
4700}
4701
[email protected]310ebd6302011-10-10 19:06:284702void RenderViewImpl::Close() {
[email protected]60c42a8c72009-10-09 04:08:594703 // We need to grab a pointer to the doomed WebView before we destroy it.
4704 WebView* doomed = webview();
4705 RenderWidget::Close();
[email protected]625332e02010-12-14 07:48:494706 g_view_map.Get().erase(doomed);
[email protected]60c42a8c72009-10-09 04:08:594707}
4708
[email protected]310ebd6302011-10-10 19:06:284709void RenderViewImpl::DidHandleKeyEvent() {
[email protected]446705872009-09-10 07:22:484710 edit_commands_.clear();
4711}
4712
[email protected]310ebd6302011-10-10 19:06:284713bool RenderViewImpl::WillHandleMouseEvent(const WebKit::WebMouseEvent& event) {
[email protected]217690d2012-01-27 07:33:114714 pepper_delegate_.WillHandleMouseEvent();
4715
4716 // If the mouse is locked, only the current owner of the mouse lock can
4717 // process mouse events.
4718 return mouse_lock_dispatcher_->WillHandleMouseEvent(event);
[email protected]67bfb83f2011-09-22 03:36:374719}
4720
[email protected]310ebd6302011-10-10 19:06:284721void RenderViewImpl::DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {
[email protected]676126f72011-01-15 00:03:514722 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidHandleMouseEvent(event));
[email protected]6a8ddba52010-09-05 04:38:064723}
4724
[email protected]310ebd6302011-10-10 19:06:284725void RenderViewImpl::DidHandleTouchEvent(const WebTouchEvent& event) {
[email protected]2d0f2e92011-10-03 09:02:244726 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidHandleTouchEvent(event));
4727}
4728
[email protected]310ebd6302011-10-10 19:06:284729void RenderViewImpl::OnWasHidden() {
[email protected]941e4552010-02-01 21:23:434730 RenderWidget::OnWasHidden();
4731
[email protected]a6939ca42011-02-18 17:58:074732 if (webview()) {
4733 webview()->settings()->setMinimumTimerInterval(
4734 webkit_glue::kBackgroundTabTimerInterval);
[email protected]f59203a2011-06-07 10:01:444735 webview()->setVisibilityState(visibilityState(), false);
[email protected]a6939ca42011-02-18 17:58:074736 }
4737
[email protected]204f1df2012-01-04 20:21:134738 // Inform PPAPI plugins that their page is no longer visible.
4739 pepper_delegate_.PageVisibilityChanged(false);
4740
[email protected]a6939ca42011-02-18 17:58:074741#if defined(OS_MACOSX)
[email protected]204f1df2012-01-04 20:21:134742 // Inform NPAPI plugins that their container is no longer visible.
[email protected]941e4552010-02-01 21:23:434743 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
4744 for (plugin_it = plugin_delegates_.begin();
4745 plugin_it != plugin_delegates_.end(); ++plugin_it) {
4746 (*plugin_it)->SetContainerVisibility(false);
4747 }
[email protected]a6939ca42011-02-18 17:58:074748#endif // OS_MACOSX
[email protected]941e4552010-02-01 21:23:434749}
4750
[email protected]310ebd6302011-10-10 19:06:284751void RenderViewImpl::OnWasRestored(bool needs_repainting) {
[email protected]941e4552010-02-01 21:23:434752 RenderWidget::OnWasRestored(needs_repainting);
4753
[email protected]a6939ca42011-02-18 17:58:074754 if (webview()) {
4755 webview()->settings()->setMinimumTimerInterval(
4756 webkit_glue::kForegroundTabTimerInterval);
[email protected]f59203a2011-06-07 10:01:444757 webview()->setVisibilityState(visibilityState(), false);
[email protected]a6939ca42011-02-18 17:58:074758 }
4759
[email protected]204f1df2012-01-04 20:21:134760 // Inform PPAPI plugins that their page is visible.
4761 pepper_delegate_.PageVisibilityChanged(true);
4762
[email protected]a6939ca42011-02-18 17:58:074763#if defined(OS_MACOSX)
[email protected]204f1df2012-01-04 20:21:134764 // Inform NPAPI plugins that their container is now visible.
[email protected]941e4552010-02-01 21:23:434765 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
4766 for (plugin_it = plugin_delegates_.begin();
4767 plugin_it != plugin_delegates_.end(); ++plugin_it) {
4768 (*plugin_it)->SetContainerVisibility(true);
4769 }
[email protected]784ea1ab2010-09-18 00:02:344770#endif // OS_MACOSX
[email protected]a6939ca42011-02-18 17:58:074771}
[email protected]1e6e3c992010-02-08 15:52:134772
[email protected]310ebd6302011-10-10 19:06:284773bool RenderViewImpl::SupportsAsynchronousSwapBuffers() {
[email protected]555e75d2011-10-08 01:23:384774 if (WebWidgetHandlesCompositorScheduling())
4775 return false;
4776
[email protected]05a980d7a2012-02-07 22:16:424777 if (queried_for_swapbuffers_complete_callback_)
4778 return context_has_swapbuffers_complete_callback_;
4779
4780 queried_for_swapbuffers_complete_callback_ = true;
4781
[email protected]65225772011-05-12 21:10:244782 WebKit::WebGraphicsContext3D* context = webview()->graphicsContext3D();
[email protected]05a980d7a2012-02-07 22:16:424783 if (context && context->makeContextCurrent()) {
4784 std::string extensions(context->getRequestableExtensionsCHROMIUM().utf8());
4785 context_has_swapbuffers_complete_callback_ =
4786 extensions.find("GL_CHROMIUM_swapbuffers_complete_callback")
4787 != std::string::npos;
4788 }
4789
4790 return context_has_swapbuffers_complete_callback_;
[email protected]65225772011-05-12 21:10:244791}
4792
[email protected]310ebd6302011-10-10 19:06:284793void RenderViewImpl::OnSetFocus(bool enable) {
[email protected]1e6e3c992010-02-08 15:52:134794 RenderWidget::OnSetFocus(enable);
4795
[email protected]7d3c02c2010-05-05 23:10:314796 if (webview() && webview()->isActive()) {
[email protected]589621b2010-09-23 22:01:074797 // Notify all NPAPI plugins.
[email protected]1e6e3c992010-02-08 15:52:134798 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
4799 for (plugin_it = plugin_delegates_.begin();
4800 plugin_it != plugin_delegates_.end(); ++plugin_it) {
[email protected]784ea1ab2010-09-18 00:02:344801#if defined(OS_MACOSX)
[email protected]7d3c02c2010-05-05 23:10:314802 // RenderWidget's call to setFocus can cause the underlying webview's
4803 // activation state to change just like a call to setIsActive.
4804 if (enable)
4805 (*plugin_it)->SetWindowFocus(true);
[email protected]784ea1ab2010-09-18 00:02:344806#endif
[email protected]7d3c02c2010-05-05 23:10:314807 (*plugin_it)->SetContentAreaFocus(enable);
[email protected]1e6e3c992010-02-08 15:52:134808 }
[email protected]589621b2010-09-23 22:01:074809
4810 // Notify all Pepper plugins.
4811 pepper_delegate_.OnSetFocus(enable);
[email protected]1e6e3c992010-02-08 15:52:134812 }
4813}
[email protected]941e4552010-02-01 21:23:434814
[email protected]310ebd6302011-10-10 19:06:284815void RenderViewImpl::PpapiPluginFocusChanged() {
[email protected]e99ef6f2011-10-16 01:13:004816 UpdateTextInputState();
[email protected]3f783362011-10-21 22:40:504817 UpdateSelectionBounds();
[email protected]56ea1a62011-05-30 07:05:574818}
4819
[email protected]73bf95812011-10-12 11:38:324820void RenderViewImpl::PpapiPluginTextInputTypeChanged() {
[email protected]e99ef6f2011-10-16 01:13:004821 UpdateTextInputState();
[email protected]73bf95812011-10-12 11:38:324822}
4823
[email protected]3f783362011-10-21 22:40:504824void RenderViewImpl::PpapiPluginCaretPositionChanged() {
4825 UpdateSelectionBounds();
4826}
4827
[email protected]b25b3ee2012-01-13 05:19:544828bool RenderViewImpl::GetPpapiPluginCaretBounds(gfx::Rect* rect) {
4829 if (!pepper_delegate_.IsPluginFocused())
4830 return false;
4831 *rect = pepper_delegate_.GetCaretBounds();
4832 return true;
4833}
4834
[email protected]73bf95812011-10-12 11:38:324835void RenderViewImpl::PpapiPluginCancelComposition() {
4836 Send(new ViewHostMsg_ImeCancelComposition(routing_id()));
4837 ui::Range range(ui::Range::InvalidRange());
4838 Send(new ViewHostMsg_ImeCompositionRangeChanged(routing_id(), range));
4839}
4840
[email protected]3c8c74c2012-03-15 07:34:524841void RenderViewImpl::PpapiPluginSelectionChanged() {
4842 SyncSelectionIfRequired();
4843}
4844
[email protected]310ebd6302011-10-10 19:06:284845void RenderViewImpl::OnImeSetComposition(
[email protected]56ea1a62011-05-30 07:05:574846 const string16& text,
4847 const std::vector<WebKit::WebCompositionUnderline>& underlines,
4848 int selection_start,
4849 int selection_end) {
[email protected]73bf95812011-10-12 11:38:324850 if (pepper_delegate_.IsPluginFocused()) {
4851 // When a PPAPI plugin has focus, we bypass WebKit.
4852 pepper_delegate_.OnImeSetComposition(text,
4853 underlines,
4854 selection_start,
4855 selection_end);
4856 } else {
[email protected]e6ae0f6c2011-10-04 10:39:234857#if defined(OS_WIN)
4858 // When a plug-in has focus, we create platform-specific IME data used by
4859 // our IME emulator and send it directly to the focused plug-in, i.e. we
4860 // bypass WebKit. (WebPluginDelegate dispatches this IME data only when its
4861 // instance ID is the same one as the specified ID.)
4862 if (focused_plugin_id_ >= 0) {
4863 std::vector<int> clauses;
4864 std::vector<int> target;
4865 for (size_t i = 0; i < underlines.size(); ++i) {
4866 clauses.push_back(underlines[i].startOffset);
4867 clauses.push_back(underlines[i].endOffset);
4868 if (underlines[i].thick) {
4869 target.clear();
4870 target.push_back(underlines[i].startOffset);
4871 target.push_back(underlines[i].endOffset);
4872 }
4873 }
4874 std::set<WebPluginDelegateProxy*>::iterator it;
4875 for (it = plugin_delegates_.begin();
4876 it != plugin_delegates_.end(); ++it) {
4877 (*it)->ImeCompositionUpdated(text, clauses, target, selection_end,
4878 focused_plugin_id_);
4879 }
4880 return;
4881 }
4882#endif
[email protected]56ea1a62011-05-30 07:05:574883 RenderWidget::OnImeSetComposition(text,
4884 underlines,
4885 selection_start,
4886 selection_end);
4887 }
4888}
4889
[email protected]4de6d1692011-10-12 08:45:444890void RenderViewImpl::OnImeConfirmComposition(
4891 const string16& text, const ui::Range& replacement_range) {
[email protected]56ea1a62011-05-30 07:05:574892 if (pepper_delegate_.IsPluginFocused()) {
[email protected]73bf95812011-10-12 11:38:324893 // When a PPAPI plugin has focus, we bypass WebKit.
4894 pepper_delegate_.OnImeConfirmComposition(text);
[email protected]56ea1a62011-05-30 07:05:574895 } else {
[email protected]e6ae0f6c2011-10-04 10:39:234896#if defined(OS_WIN)
4897 // Same as OnImeSetComposition(), we send the text from IMEs directly to
4898 // plug-ins. When we send IME text directly to plug-ins, we should not send
4899 // it to WebKit to prevent WebKit from controlling IMEs.
[email protected]4de6d1692011-10-12 08:45:444900 // TODO(thakis): Honor |replacement_range| for plugins?
[email protected]e6ae0f6c2011-10-04 10:39:234901 if (focused_plugin_id_ >= 0) {
4902 std::set<WebPluginDelegateProxy*>::iterator it;
4903 for (it = plugin_delegates_.begin();
4904 it != plugin_delegates_.end(); ++it) {
4905 (*it)->ImeCompositionCompleted(text, focused_plugin_id_);
4906 }
4907 return;
4908 }
4909#endif
[email protected]ebd28ac2011-10-13 18:49:054910 if (replacement_range.IsValid() && webview()) {
4911 // Select the text in |replacement_range|, it will then be replaced by
4912 // text added by the call to RenderWidget::OnImeConfirmComposition().
4913 if (WebFrame* frame = webview()->focusedFrame()) {
[email protected]4bacb822011-11-02 15:10:164914 WebRange webrange = WebRange::fromDocumentRange(
4915 frame, replacement_range.start(), replacement_range.length());
4916 if (!webrange.isNull())
4917 frame->setSelectionToRange(webrange);
[email protected]ebd28ac2011-10-13 18:49:054918 }
4919 }
[email protected]4de6d1692011-10-12 08:45:444920 RenderWidget::OnImeConfirmComposition(text, replacement_range);
[email protected]56ea1a62011-05-30 07:05:574921 }
4922}
4923
[email protected]310ebd6302011-10-10 19:06:284924ui::TextInputType RenderViewImpl::GetTextInputType() {
[email protected]73bf95812011-10-12 11:38:324925 return pepper_delegate_.IsPluginFocused() ?
4926 pepper_delegate_.GetTextInputType() : RenderWidget::GetTextInputType();
4927}
4928
[email protected]3f783362011-10-21 22:40:504929void RenderViewImpl::GetSelectionBounds(gfx::Rect* start, gfx::Rect* end) {
4930 if (pepper_delegate_.IsPluginFocused()) {
4931 // TODO(kinaba) http://crbug.com/101101
4932 // Current Pepper IME API does not handle selection bounds. So we simply
4933 // use the caret position as an empty range for now. It will be updated
4934 // after Pepper API equips features related to surrounding text retrieval.
4935 gfx::Rect caret = pepper_delegate_.GetCaretBounds();
4936 *start = caret;
4937 *end = caret;
4938 return;
4939 }
4940 RenderWidget::GetSelectionBounds(start, end);
[email protected]ad26ef42011-06-17 07:59:454941}
4942
[email protected]310ebd6302011-10-10 19:06:284943bool RenderViewImpl::CanComposeInline() {
[email protected]73bf95812011-10-12 11:38:324944 return pepper_delegate_.IsPluginFocused() ?
4945 pepper_delegate_.CanComposeInline() : true;
[email protected]56ea1a62011-05-30 07:05:574946}
4947
[email protected]e6ae0f6c2011-10-04 10:39:234948#if defined(OS_WIN)
[email protected]310ebd6302011-10-10 19:06:284949void RenderViewImpl::PluginFocusChanged(bool focused, int plugin_id) {
[email protected]e6ae0f6c2011-10-04 10:39:234950 if (focused)
4951 focused_plugin_id_ = plugin_id;
4952 else
4953 focused_plugin_id_ = -1;
4954}
4955#endif
4956
[email protected]43f28f832010-02-03 02:28:484957#if defined(OS_MACOSX)
[email protected]310ebd6302011-10-10 19:06:284958void RenderViewImpl::PluginFocusChanged(bool focused, int plugin_id) {
[email protected]82114f52012-03-20 22:53:414959 Send(new ViewHostMsg_PluginFocusChanged(routing_id(), focused, plugin_id));
[email protected]b7f75862011-01-21 21:15:134960}
4961
[email protected]310ebd6302011-10-10 19:06:284962void RenderViewImpl::StartPluginIme() {
[email protected]b7f75862011-01-21 21:15:134963 IPC::Message* msg = new ViewHostMsg_StartPluginIme(routing_id());
[email protected]935d63d2010-10-15 23:31:554964 // This message can be sent during event-handling, and needs to be delivered
4965 // within that context.
4966 msg->set_unblock(true);
4967 Send(msg);
4968}
4969
[email protected]310ebd6302011-10-10 19:06:284970gfx::PluginWindowHandle RenderViewImpl::AllocateFakePluginWindowHandle(
[email protected]77e74db2010-08-04 17:46:234971 bool opaque, bool root) {
[email protected]b2968292012-03-28 01:35:514972 gfx::PluginWindowHandle window = gfx::kNullPluginWindow;
[email protected]43f28f832010-02-03 02:28:484973 Send(new ViewHostMsg_AllocateFakePluginWindowHandle(
[email protected]77e74db2010-08-04 17:46:234974 routing_id(), opaque, root, &window));
[email protected]c36a9b62010-10-14 00:41:114975 if (window) {
4976 fake_plugin_window_handles_.insert(window);
4977 }
[email protected]43f28f832010-02-03 02:28:484978 return window;
4979}
4980
[email protected]310ebd6302011-10-10 19:06:284981void RenderViewImpl::DestroyFakePluginWindowHandle(
4982 gfx::PluginWindowHandle window) {
[email protected]c36a9b62010-10-14 00:41:114983 if (window && fake_plugin_window_handles_.find(window) !=
4984 fake_plugin_window_handles_.end()) {
[email protected]43f28f832010-02-03 02:28:484985 Send(new ViewHostMsg_DestroyFakePluginWindowHandle(routing_id(), window));
[email protected]c36a9b62010-10-14 00:41:114986 fake_plugin_window_handles_.erase(window);
4987 }
[email protected]43f28f832010-02-03 02:28:484988}
4989
[email protected]310ebd6302011-10-10 19:06:284990void RenderViewImpl::AcceleratedSurfaceSetIOSurface(
4991 gfx::PluginWindowHandle window,
4992 int32 width,
4993 int32 height,
4994 uint64 io_surface_identifier) {
[email protected]44ce0b12010-03-12 16:45:334995 Send(new ViewHostMsg_AcceleratedSurfaceSetIOSurface(
[email protected]43f28f832010-02-03 02:28:484996 routing_id(), window, width, height, io_surface_identifier));
4997}
4998
[email protected]310ebd6302011-10-10 19:06:284999void RenderViewImpl::AcceleratedSurfaceSetTransportDIB(
[email protected]44ce0b12010-03-12 16:45:335000 gfx::PluginWindowHandle window,
5001 int32 width,
5002 int32 height,
5003 TransportDIB::Handle transport_dib) {
5004 Send(new ViewHostMsg_AcceleratedSurfaceSetTransportDIB(
[email protected]1aef98132010-02-23 18:00:075005 routing_id(), window, width, height, transport_dib));
5006}
5007
[email protected]310ebd6302011-10-10 19:06:285008TransportDIB::Handle RenderViewImpl::AcceleratedSurfaceAllocTransportDIB(
[email protected]44ce0b12010-03-12 16:45:335009 size_t size) {
[email protected]1aef98132010-02-23 18:00:075010 TransportDIB::Handle dib_handle;
5011 // Assume this is a synchronous RPC.
[email protected]ada848b12010-04-08 22:35:385012 if (Send(new ViewHostMsg_AllocTransportDIB(size, true, &dib_handle)))
[email protected]1aef98132010-02-23 18:00:075013 return dib_handle;
5014 // Return an invalid handle if Send() fails.
5015 return TransportDIB::DefaultHandleValue();
5016}
5017
[email protected]310ebd6302011-10-10 19:06:285018void RenderViewImpl::AcceleratedSurfaceFreeTransportDIB(
5019 TransportDIB::Id dib_id) {
[email protected]1aef98132010-02-23 18:00:075020 Send(new ViewHostMsg_FreeTransportDIB(dib_id));
5021}
5022
[email protected]310ebd6302011-10-10 19:06:285023void RenderViewImpl::AcceleratedSurfaceBuffersSwapped(
[email protected]7de8fb72012-03-14 04:24:325024 gfx::PluginWindowHandle window, uint64 surface_handle) {
[email protected]f35d6672010-10-28 21:39:145025 Send(new ViewHostMsg_AcceleratedSurfaceBuffersSwapped(
[email protected]7de8fb72012-03-14 04:24:325026 routing_id(), window, surface_handle));
[email protected]43f28f832010-02-03 02:28:485027}
[email protected]82114f52012-03-20 22:53:415028#endif // defined(OS_MACOSX)
[email protected]58c321d2010-02-19 12:11:285029
[email protected]310ebd6302011-10-10 19:06:285030bool RenderViewImpl::ScheduleFileChooser(
[email protected]8caadeb2011-11-22 02:45:235031 const content::FileChooserParams& params,
[email protected]cdaf8d02010-03-30 19:52:475032 WebFileChooserCompletion* completion) {
5033 static const size_t kMaximumPendingFileChooseRequests = 4;
5034 if (file_chooser_completions_.size() > kMaximumPendingFileChooseRequests) {
5035 // This sanity check prevents too many file choose requests from getting
5036 // queued which could DoS the user. Getting these is most likely a
5037 // programming error (there are many ways to DoS the user so it's not
5038 // considered a "real" security check), either in JS requesting many file
5039 // choosers to pop up, or in a plugin.
5040 //
5041 // TODO(brettw) we might possibly want to require a user gesture to open
5042 // a file picker, which will address this issue in a better way.
5043 return false;
5044 }
5045
5046 file_chooser_completions_.push_back(linked_ptr<PendingFileChooser>(
5047 new PendingFileChooser(params, completion)));
5048 if (file_chooser_completions_.size() == 1) {
5049 // Actually show the browse dialog when this is the first request.
5050 Send(new ViewHostMsg_RunFileChooser(routing_id_, params));
5051 }
5052 return true;
5053}
5054
[email protected]310ebd6302011-10-10 19:06:285055WebKit::WebGeolocationClient* RenderViewImpl::geolocationClient() {
[email protected]676126f72011-01-15 00:03:515056 if (!geolocation_dispatcher_)
5057 geolocation_dispatcher_ = new GeolocationDispatcher(this);
5058 return geolocation_dispatcher_;
[email protected]7e0c4702010-12-31 14:06:255059}
[email protected]61c9f032010-03-31 23:04:195060
[email protected]310ebd6302011-10-10 19:06:285061WebKit::WebSpeechInputController* RenderViewImpl::speechInputController(
[email protected]638694c2010-08-04 22:24:115062 WebKit::WebSpeechInputListener* listener) {
[email protected]9eb100e2011-10-14 05:08:225063#if defined(ENABLE_INPUT_SPEECH)
[email protected]c52b2892012-03-07 11:01:025064 if (!input_tag_speech_dispatcher_)
5065 input_tag_speech_dispatcher_ =
5066 new InputTagSpeechDispatcher(this, listener);
[email protected]9eb100e2011-10-14 05:08:225067#endif
[email protected]c52b2892012-03-07 11:01:025068 return input_tag_speech_dispatcher_;
[email protected]638694c2010-08-04 22:24:115069}
5070
[email protected]310ebd6302011-10-10 19:06:285071WebKit::WebDeviceOrientationClient* RenderViewImpl::deviceOrientationClient() {
[email protected]676126f72011-01-15 00:03:515072 if (!device_orientation_dispatcher_)
5073 device_orientation_dispatcher_ = new DeviceOrientationDispatcher(this);
5074 return device_orientation_dispatcher_;
[email protected]57ead352010-08-11 14:42:535075}
5076
[email protected]310ebd6302011-10-10 19:06:285077void RenderViewImpl::zoomLimitsChanged(double minimum_level,
5078 double maximum_level) {
[email protected]b75b8292010-10-01 07:28:255079 // For now, don't remember plugin zoom values. We don't want to mix them with
5080 // normal web content (i.e. a fixed layout plugin would usually want them
5081 // different).
5082 bool remember = !webview()->mainFrame()->document().isPluginDocument();
5083
[email protected]b75b8292010-10-01 07:28:255084 int minimum_percent = static_cast<int>(
5085 WebView::zoomLevelToZoomFactor(minimum_level) * 100);
5086 int maximum_percent = static_cast<int>(
5087 WebView::zoomLevelToZoomFactor(maximum_level) * 100);
[email protected]b75b8292010-10-01 07:28:255088
5089 Send(new ViewHostMsg_UpdateZoomLimits(
5090 routing_id_, minimum_percent, maximum_percent, remember));
5091}
5092
[email protected]310ebd6302011-10-10 19:06:285093void RenderViewImpl::zoomLevelChanged() {
[email protected]b75b8292010-10-01 07:28:255094 bool remember = !webview()->mainFrame()->document().isPluginDocument();
[email protected]ba51d3b2011-08-24 19:53:085095 float zoom_level = webview()->zoomLevel();
[email protected]b75b8292010-10-01 07:28:255096 // Tell the browser which url got zoomed so it can update the menu and the
5097 // saved values if necessary
5098 Send(new ViewHostMsg_DidZoomURL(
[email protected]ba51d3b2011-08-24 19:53:085099 routing_id_, zoom_level, remember,
[email protected]b6cb3a842011-06-24 18:28:415100 GURL(webview()->mainFrame()->document().url())));
[email protected]b75b8292010-10-01 07:28:255101}
5102
[email protected]310ebd6302011-10-10 19:06:285103void RenderViewImpl::registerProtocolHandler(const WebString& scheme,
5104 const WebString& base_url,
5105 const WebString& url,
5106 const WebString& title) {
[email protected]a6d36cc2011-02-23 00:39:485107 GURL base(base_url);
5108 GURL absolute_url = base.Resolve(UTF16ToUTF8(url));
5109 if (base.GetOrigin() != absolute_url.GetOrigin()) {
5110 return;
5111 }
[email protected]f1a29a02011-10-06 23:08:445112 Send(new ViewHostMsg_RegisterProtocolHandler(routing_id_,
5113 UTF16ToUTF8(scheme),
5114 absolute_url,
5115 title));
[email protected]a6d36cc2011-02-23 00:39:485116}
5117
[email protected]310ebd6302011-10-10 19:06:285118WebKit::WebPageVisibilityState RenderViewImpl::visibilityState() const {
[email protected]f59203a2011-06-07 10:01:445119 WebKit::WebPageVisibilityState current_state = is_hidden() ?
5120 WebKit::WebPageVisibilityStateHidden :
5121 WebKit::WebPageVisibilityStateVisible;
5122 WebKit::WebPageVisibilityState override_state = current_state;
5123 if (content::GetContentClient()->renderer()->
5124 ShouldOverridePageVisibilityState(this,
5125 &override_state))
5126 return override_state;
5127 return current_state;
[email protected]94dec932011-05-26 20:04:215128}
5129
[email protected]273558fb2012-01-12 15:03:515130WebKit::WebUserMediaClient* RenderViewImpl::userMediaClient() {
5131 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
5132 if (!cmd_line->HasSwitch(switches::kEnableMediaStream))
5133 return NULL;
5134 EnsureMediaStreamImpl();
5135 return media_stream_impl_;
5136}
5137
[email protected]310ebd6302011-10-10 19:06:285138bool RenderViewImpl::IsNonLocalTopLevelNavigation(
[email protected]61c9f032010-03-31 23:04:195139 const GURL& url, WebKit::WebFrame* frame, WebKit::WebNavigationType type) {
[email protected]8079b362010-05-07 18:37:455140 // Must be a top level frame.
[email protected]61c9f032010-03-31 23:04:195141 if (frame->parent() != NULL)
5142 return false;
5143
[email protected]f0a3d0b2010-08-06 22:51:535144 // Navigations initiated within Webkit are not sent out to the external host
5145 // in the following cases.
[email protected]900eb2f12010-08-23 22:36:275146 // 1. The url scheme is not http/https
[email protected]d19ea342011-04-20 20:31:135147 // 2. The origin of the url and the opener is the same in which case the
[email protected]f0a3d0b2010-08-06 22:51:535148 // opener relationship is maintained.
[email protected]d19ea342011-04-20 20:31:135149 // 3. Reloads/form submits/back forward navigations
[email protected]abbfaec2011-05-23 23:57:335150 if (!url.SchemeIs(chrome::kHttpScheme) && !url.SchemeIs(chrome::kHttpsScheme))
[email protected]f0a3d0b2010-08-06 22:51:535151 return false;
5152
[email protected]2fc22d12010-12-02 23:08:165153 // Not interested in reloads/form submits/resubmits/back forward navigations.
[email protected]d0ed50d2010-06-22 01:01:325154 if (type != WebKit::WebNavigationTypeReload &&
[email protected]070c49c2010-07-13 22:22:015155 type != WebKit::WebNavigationTypeFormSubmitted &&
[email protected]2fc22d12010-12-02 23:08:165156 type != WebKit::WebNavigationTypeFormResubmitted &&
[email protected]070c49c2010-07-13 22:22:015157 type != WebKit::WebNavigationTypeBackForward) {
[email protected]d0ed50d2010-06-22 01:01:325158 // The opener relationship between the new window and the parent allows the
5159 // new window to script the parent and vice versa. This is not allowed if
5160 // the origins of the two domains are different. This can be treated as a
5161 // top level navigation and routed back to the host.
5162 WebKit::WebFrame* opener = frame->opener();
[email protected]900eb2f12010-08-23 22:36:275163 if (!opener) {
[email protected]86965362011-04-21 18:42:515164 return true;
[email protected]d19ea342011-04-20 20:31:135165 } else {
[email protected]b6cb3a842011-06-24 18:28:415166 if (url.GetOrigin() != GURL(opener->document().url()).GetOrigin())
[email protected]d0ed50d2010-06-22 01:01:325167 return true;
5168 }
5169 }
[email protected]61c9f032010-03-31 23:04:195170 return false;
5171}
[email protected]2b06a992010-08-21 05:48:225172
[email protected]310ebd6302011-10-10 19:06:285173void RenderViewImpl::OnAsyncFileOpened(
5174 base::PlatformFileError error_code,
5175 IPC::PlatformFileForTransit file_for_transit,
5176 int message_id) {
[email protected]27a9ef32010-09-10 04:06:245177 pepper_delegate_.OnAsyncFileOpened(
5178 error_code,
5179 IPC::PlatformFileForTransitToPlatformFile(file_for_transit),
5180 message_id);
5181}
[email protected]caf706f2010-10-26 17:54:085182
[email protected]310ebd6302011-10-10 19:06:285183void RenderViewImpl::OnPpapiBrokerChannelCreated(
[email protected]2b657fd2011-04-18 16:00:475184 int request_id,
5185 base::ProcessHandle broker_process_handle,
[email protected]d54305072011-06-22 20:58:435186 const IPC::ChannelHandle& handle) {
[email protected]2b657fd2011-04-18 16:00:475187 pepper_delegate_.OnPpapiBrokerChannelCreated(request_id,
5188 broker_process_handle,
5189 handle);
[email protected]eb415bf0e2011-04-14 02:45:425190}
5191
[email protected]caf706f2010-10-26 17:54:085192#if defined(OS_MACOSX)
[email protected]310ebd6302011-10-10 19:06:285193void RenderViewImpl::OnSelectPopupMenuItem(int selected_index) {
[email protected]68dc3ba2010-12-06 21:43:155194 if (external_popup_menu_ == NULL) {
5195 // Crash reports from the field indicate that we can be notified with a
5196 // NULL external popup menu (we probably get notified twice).
5197 // If you hit this please file a bug against jcivelli and include the page
5198 // and steps to repro.
5199 NOTREACHED();
5200 return;
5201 }
[email protected]caf706f2010-10-26 17:54:085202 external_popup_menu_->DidSelectItem(selected_index);
5203 external_popup_menu_.reset();
5204}
5205#endif
[email protected]bb461532010-11-26 21:50:235206
[email protected]310ebd6302011-10-10 19:06:285207void RenderViewImpl::OnContextMenuClosed(
[email protected]35be7ec2012-02-12 20:42:515208 const content::CustomContextMenuContext& custom_context) {
[email protected]b29aa74b2011-01-31 21:41:085209 if (custom_context.is_pepper_menu)
5210 pepper_delegate_.OnContextMenuClosed(custom_context);
5211 else
5212 context_menu_node_.reset();
[email protected]521b2482011-01-15 00:10:105213}
[email protected]5a7b15a2011-08-22 22:48:185214
[email protected]310ebd6302011-10-10 19:06:285215void RenderViewImpl::OnEnableViewSourceMode() {
[email protected]5a7b15a2011-08-22 22:48:185216 if (!webview())
5217 return;
5218 WebFrame* main_frame = webview()->mainFrame();
5219 if (!main_frame)
5220 return;
5221 main_frame->enableViewSourceMode(true);
5222}
[email protected]67bfb83f2011-09-22 03:36:375223
[email protected]310ebd6302011-10-10 19:06:285224bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const {
[email protected]ab21f2c2011-11-19 00:50:085225 return !!RenderThreadImpl::current()->compositor_thread();
[email protected]c3d45532011-10-07 19:20:405226}
[email protected]7f3c7af2011-10-20 22:52:515227
[email protected]64d0e192011-12-09 14:44:205228void RenderViewImpl::OnJavaBridgeInit() {
[email protected]7f3c7af2011-10-20 22:52:515229 DCHECK(!java_bridge_dispatcher_.get());
[email protected]464750f2011-10-24 23:16:185230#if defined(ENABLE_JAVA_BRIDGE)
[email protected]64d0e192011-12-09 14:44:205231 java_bridge_dispatcher_.reset(new JavaBridgeDispatcher(this));
[email protected]464750f2011-10-24 23:16:185232#endif
[email protected]7f3c7af2011-10-20 22:52:515233}