blob: 964e29241e65f57823f9a33b789adc50a680cdc4 [file] [log] [blame]
[email protected]1b4209f2011-01-07 00:25:401// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/renderer/render_view.h"
6
7#include <algorithm>
[email protected]b75b8292010-10-01 07:28:258#include <cmath>
initial.commit09911bf2008-07-26 23:55:299#include <string>
10#include <vector>
11
[email protected]2041cf342010-02-19 03:15:5912#include "base/callback.h"
initial.commit09911bf2008-07-26 23:55:2913#include "base/command_line.h"
[email protected]bb063b72009-03-27 23:18:5014#include "base/compiler_specific.h"
[email protected]625332e02010-12-14 07:48:4915#include "base/lazy_instance.h"
[email protected]835d7c82010-10-14 04:38:3816#include "base/metrics/histogram.h"
[email protected]7bf795d92010-05-22 00:14:2817#include "base/path_service.h"
[email protected]8380c092009-06-25 17:45:5118#include "base/process_util.h"
initial.commit09911bf2008-07-26 23:55:2919#include "base/string_piece.h"
20#include "base/string_util.h"
[email protected]55126132010-08-19 14:53:2821#include "base/sys_string_conversions.h"
[email protected]6fdd4182010-10-14 23:59:2622#include "base/time.h"
[email protected]be1ce6a72010-08-03 14:35:2223#include "base/utf_string_conversions.h"
[email protected]6c8afae52009-01-22 02:24:5724#include "build/build_config.h"
[email protected]19d6e1e82011-01-26 05:08:5825#include "chrome/common/autofill_messages.h"
[email protected]035545f2010-04-09 13:10:2126#include "chrome/common/appcache/appcache_dispatcher.h"
[email protected]81e63782009-02-27 19:35:0927#include "chrome/common/bindings_policy.h"
[email protected]ef916272009-07-08 21:40:5528#include "chrome/common/child_process_logging.h"
[email protected]f0af6a72009-05-30 05:25:1729#include "chrome/common/chrome_constants.h"
[email protected]7bf795d92010-05-22 00:14:2830#include "chrome/common/chrome_paths.h"
31#include "chrome/common/chrome_switches.h"
[email protected]26a9acf2010-12-13 19:35:0532#include "chrome/common/database_messages.h"
[email protected]a0cf04a2010-06-23 03:29:5533#include "chrome/common/extensions/extension.h"
[email protected]ec7db282011-01-29 01:11:3634#include "chrome/common/extensions/extension_set.h"
[email protected]c5a272d2010-09-27 18:37:0835#include "chrome/common/file_system/file_system_dispatcher.h"
36#include "chrome/common/file_system/webfilesystem_callback_dispatcher.h"
[email protected]bb461532010-11-26 21:50:2337#include "chrome/common/json_value_serializer.h"
initial.commit09911bf2008-07-26 23:55:2938#include "chrome/common/jstemplate_builder.h"
[email protected]97c5c592010-08-03 08:22:2139#include "chrome/common/notification_service.h"
[email protected]630e26b2008-10-14 22:55:1740#include "chrome/common/page_zoom.h"
[email protected]f0557932011-01-25 20:20:5141#include "chrome/common/pepper_messages.h"
[email protected]4e0616e2010-05-28 14:55:5342#include "chrome/common/pepper_plugin_registry.h"
[email protected]e09ba552009-02-05 03:26:2943#include "chrome/common/render_messages.h"
[email protected]13a1e4c3c2011-02-03 21:07:0944#include "chrome/common/render_view_commands.h"
[email protected]9b6f40e2009-06-11 15:54:2645#include "chrome/common/renderer_preferences.h"
initial.commit09911bf2008-07-26 23:55:2946#include "chrome/common/thumbnail_score.h"
[email protected]6de74452009-02-25 18:04:5947#include "chrome/common/url_constants.h"
[email protected]38789d82010-11-17 06:03:4448#include "chrome/common/web_apps.h"
[email protected]534c66c2010-04-28 22:53:1149#include "chrome/common/window_container_type.h"
initial.commit09911bf2008-07-26 23:55:2950#include "chrome/renderer/about_handler.h"
[email protected]5fb88962009-04-16 19:03:2551#include "chrome/renderer/audio_message_filter.h"
[email protected]78192082011-01-29 05:43:4452#include "chrome/renderer/autofill/autofill_agent.h"
53#include "chrome/renderer/autofill/form_manager.h"
54#include "chrome/renderer/autofill/password_autofill_manager.h"
[email protected]2f979172010-09-16 21:54:0355#include "chrome/renderer/automation/dom_automation_controller.h"
[email protected]00152e92010-07-19 11:47:4056#include "chrome/renderer/blocked_plugin.h"
[email protected]57ead352010-08-11 14:42:5357#include "chrome/renderer/device_orientation_dispatcher.h"
[email protected]e4ac5df2009-03-17 15:33:1158#include "chrome/renderer/devtools_agent.h"
59#include "chrome/renderer/devtools_client.h"
[email protected]912256b32009-09-18 09:47:3560#include "chrome/renderer/extension_groups.h"
[email protected]4026ce1e2010-09-14 19:35:0461#include "chrome/renderer/extensions/bindings_utils.h"
[email protected]f816c012009-06-26 21:48:3262#include "chrome/renderer/extensions/event_bindings.h"
[email protected]0f6053962009-07-09 19:26:3563#include "chrome/renderer/extensions/extension_process_bindings.h"
[email protected]78d5cfe2011-02-04 08:43:2264#include "chrome/renderer/extensions/extension_resource_request_policy.h"
[email protected]7120f132009-07-20 21:05:3765#include "chrome/renderer/extensions/renderer_extension_bindings.h"
[email protected]2f979172010-09-16 21:54:0366#include "chrome/renderer/external_host_bindings.h"
[email protected]caf706f2010-10-26 17:54:0867#include "chrome/renderer/external_popup_menu.h"
[email protected]ffd0abd2010-12-14 17:45:5068#include "chrome/renderer/geolocation_dispatcher.h"
[email protected]3bb08602010-10-07 21:47:1769#include "chrome/renderer/ggl/ggl.h"
[email protected]90109412010-12-15 17:14:2470#include "chrome/renderer/load_progress_tracker.h"
initial.commit09911bf2008-07-26 23:55:2971#include "chrome/renderer/localized_error.h"
[email protected]6f56d482009-02-20 05:02:5672#include "chrome/renderer/media/audio_renderer_impl.h"
[email protected]ee68378a2010-08-10 01:05:4173#include "chrome/renderer/media/ipc_video_decoder.h"
[email protected]ed3fb032009-06-16 19:50:5674#include "chrome/renderer/navigation_state.h"
[email protected]90e908552009-10-05 01:40:1275#include "chrome/renderer/notification_provider.h"
[email protected]6a8ddba52010-09-05 04:38:0676#include "chrome/renderer/page_click_tracker.h"
[email protected]a5a65ac2010-11-05 18:14:3677#include "chrome/renderer/page_load_histograms.h"
[email protected]8beff0762009-09-29 02:18:3078#include "chrome/renderer/plugin_channel_host.h"
[email protected]d81c1e52009-06-03 22:09:5079#include "chrome/renderer/print_web_view_helper.h"
[email protected]39008c02009-02-11 23:59:2580#include "chrome/renderer/render_process.h"
[email protected]00c39612010-03-06 02:53:2881#include "chrome/renderer/render_thread.h"
[email protected]676126f72011-01-15 00:03:5182#include "chrome/renderer/render_view_observer.h"
[email protected]4d51d5bf2010-07-26 18:48:2683#include "chrome/renderer/render_view_visitor.h"
[email protected]484955942010-08-19 16:13:1884#include "chrome/renderer/render_widget_fullscreen.h"
[email protected]79c7bed2010-09-14 22:28:3985#include "chrome/renderer/render_widget_fullscreen_pepper.h"
[email protected]035545f2010-04-09 13:10:2186#include "chrome/renderer/renderer_webapplicationcachehost_impl.h"
[email protected]bd92c3a2010-01-13 05:02:3487#include "chrome/renderer/renderer_webstoragenamespace_impl.h"
[email protected]3ead1322010-11-19 20:01:0088#include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h"
[email protected]ce833282010-11-04 15:48:3989#include "chrome/renderer/searchbox_extension.h"
[email protected]638694c2010-08-04 22:24:1190#include "chrome/renderer/speech_input_dispatcher.h"
[email protected]85c55dc2009-11-06 03:05:4691#include "chrome/renderer/spellchecker/spellcheck.h"
[email protected]81273622011-02-02 03:56:1392#include "chrome/renderer/translate_helper.h"
[email protected]25e18f82010-10-27 16:38:4393#include "chrome/renderer/user_script_idle_scheduler.h"
[email protected]0938d3c2009-01-09 20:37:3594#include "chrome/renderer/user_script_slave.h"
initial.commit09911bf2008-07-26 23:55:2995#include "chrome/renderer/visitedlink_slave.h"
[email protected]c50008512011-02-03 01:17:2796#include "chrome/renderer/web_ui_bindings.h"
[email protected]5aa6a312010-11-06 00:00:0797#include "chrome/renderer/webgraphicscontext3d_command_buffer_impl.h"
[email protected]d439ba072009-10-17 22:32:2998#include "chrome/renderer/webplugin_delegate_pepper.h"
[email protected]ba4b17f2009-02-11 21:32:2999#include "chrome/renderer/webplugin_delegate_proxy.h"
[email protected]9c00f002009-11-05 22:37:42100#include "chrome/renderer/websharedworker_proxy.h"
[email protected]eb47a132009-03-04 00:39:56101#include "chrome/renderer/webworker_proxy.h"
[email protected]34ac8f32009-02-22 23:03:27102#include "grit/generated_resources.h"
103#include "grit/renderer_resources.h"
[email protected]f8db8132010-12-03 00:27:49104#include "media/base/filter_collection.h"
[email protected]ee68378a2010-08-10 01:05:41105#include "media/base/media_switches.h"
[email protected]f78d1dfc2011-01-15 07:09:27106#include "media/base/message_loop_factory_impl.h"
[email protected]f11ca0732009-04-11 00:09:34107#include "net/base/data_url.h"
initial.commit09911bf2008-07-26 23:55:29108#include "net/base/escape.h"
109#include "net/base/net_errors.h"
[email protected]52c68652010-12-07 17:47:04110#include "net/http/http_util.h"
[email protected]1b4209f2011-01-07 00:25:40111#include "ppapi/c/private/ppb_flash.h"
[email protected]c399a8a2008-11-22 19:38:00112#include "skia/ext/bitmap_platform_device.h"
[email protected]83c9e6552008-12-03 16:22:10113#include "skia/ext/image_operations.h"
[email protected]8bd0fe62011-01-17 06:44:37114#include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityCache.h"
115#include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObject.h"
116#include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h"
117#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
118#include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h"
119#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
120#include "third_party/WebKit/Source/WebKit/chromium/public/WebDragData.h"
121#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
122#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserParams.h"
123#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystem.h"
124#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystemCallbacks.h"
125#include "third_party/WebKit/Source/WebKit/chromium/public/WebFindOptions.h"
126#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement.h"
127#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h"
128#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
129#include "third_party/WebKit/Source/WebKit/chromium/public/WebGraphicsContext3D.h"
130#include "third_party/WebKit/Source/WebKit/chromium/public/WebHistoryItem.h"
131#include "third_party/WebKit/Source/WebKit/chromium/public/WebImage.h"
132#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h"
133#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
134#include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeList.h"
135#include "third_party/WebKit/Source/WebKit/chromium/public/WebPageSerializer.h"
136#include "third_party/WebKit/Source/WebKit/chromium/public/WebPlugin.h"
137#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
138#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginDocument.h"
139#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h"
140#include "third_party/WebKit/Source/WebKit/chromium/public/WebPoint.h"
141#include "third_party/WebKit/Source/WebKit/chromium/public/WebRange.h"
142#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
143#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h"
144#include "third_party/WebKit/Source/WebKit/chromium/public/WebSearchableFormData.h"
145#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
146#include "third_party/WebKit/Source/WebKit/chromium/public/WebSettings.h"
147#include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
148#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageNamespace.h"
149#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
150#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
151#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h"
152#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h"
153#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"
154#include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
155#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
156#include "third_party/WebKit/Source/WebKit/chromium/public/WebWindowFeatures.h"
[email protected]6fdd4182010-10-14 23:59:26157#include "third_party/cld/encodings/compact_lang_det/win/cld_unicodetext.h"
158#include "third_party/skia/include/core/SkBitmap.h"
[email protected]9dd7e3d72011-01-20 18:27:06159#include "ui/base/message_box_flags.h"
[email protected]c051a1b2011-01-21 23:30:17160#include "ui/base/l10n/l10n_util.h"
[email protected]42ce29d2011-01-20 23:19:46161#include "ui/base/resource/resource_bundle.h"
[email protected]08397d52011-02-05 01:53:38162#include "ui/gfx/color_utils.h"
163#include "ui/gfx/favicon_size.h"
164#include "ui/gfx/native_widget_types.h"
165#include "ui/gfx/point.h"
166#include "ui/gfx/rect.h"
167#include "ui/gfx/skbitmap_operations.h"
[email protected]882b7b22010-10-05 03:34:53168#include "v8/include/v8.h"
[email protected]a6097f42011-01-10 08:50:51169#include "v8/include/v8-testing.h"
[email protected]80f584d92010-01-21 03:59:04170#include "webkit/appcache/web_application_cache_host_impl.h"
[email protected]25e18f82010-10-27 16:38:43171#include "webkit/glue/alt_error_page_resource_fetcher.h"
[email protected]7a4de7a62010-08-17 18:38:24172#include "webkit/glue/context_menu.h"
initial.commit09911bf2008-07-26 23:55:29173#include "webkit/glue/dom_operations.h"
[email protected]b1438212010-04-03 00:30:59174#include "webkit/glue/form_data.h"
[email protected]95056b582010-02-18 01:29:24175#include "webkit/glue/form_field.h"
[email protected]95056b582010-02-18 01:29:24176#include "webkit/glue/glue_serialize.h"
[email protected]f11ca0732009-04-11 00:09:34177#include "webkit/glue/image_decoder.h"
[email protected]4d51d5bf2010-07-26 18:48:26178#include "webkit/glue/image_resource_fetcher.h"
[email protected]85cc78c2010-05-04 18:30:09179#include "webkit/glue/media/video_renderer_impl.h"
[email protected]4d51d5bf2010-07-26 18:48:26180#include "webkit/glue/password_form_dom_manager.h"
[email protected]bb461532010-11-26 21:50:23181#include "webkit/glue/resource_fetcher.h"
[email protected]85cc78c2010-05-04 18:30:09182#include "webkit/glue/site_isolation_metrics.h"
[email protected]7a4de7a62010-08-17 18:38:24183#include "webkit/glue/webaccessibility.h"
initial.commit09911bf2008-07-26 23:55:29184#include "webkit/glue/webdropdata.h"
initial.commit09911bf2008-07-26 23:55:29185#include "webkit/glue/webkit_glue.h"
[email protected]add51772009-06-11 18:25:17186#include "webkit/glue/webmediaplayer_impl.h"
[email protected]191eb3f72010-12-21 06:27:50187#include "webkit/plugins/npapi/default_plugin_shared.h"
188#include "webkit/plugins/npapi/plugin_list.h"
189#include "webkit/plugins/npapi/webplugin_delegate.h"
190#include "webkit/plugins/npapi/webplugin_delegate_impl.h"
191#include "webkit/plugins/npapi/webplugin_impl.h"
192#include "webkit/plugins/npapi/webview_plugin.h"
[email protected]0bd753682010-12-16 18:15:52193#include "webkit/plugins/ppapi/ppapi_webplugin_impl.h"
initial.commit09911bf2008-07-26 23:55:29194
[email protected]6c8afae52009-01-22 02:24:57195#if defined(OS_WIN)
196// TODO(port): these files are currently Windows only because they concern:
[email protected]6c8afae52009-01-22 02:24:57197// * theming
[email protected]08397d52011-02-05 01:53:38198#include "ui/gfx/native_theme_win.h"
[email protected]6981f7f2010-03-09 00:53:03199#elif defined(USE_X11)
[email protected]8bd0fe62011-01-17 06:44:37200#include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebRenderTheme.h"
[email protected]08397d52011-02-05 01:53:38201#include "ui/gfx/native_theme_linux.h"
[email protected]78043bdd2010-04-05 18:45:33202#elif defined(OS_MACOSX)
203#include "skia/ext/skia_utils_mac.h"
[email protected]6c8afae52009-01-22 02:24:57204#endif
205
[email protected]c7287a92009-11-04 20:06:15206using WebKit::WebAccessibilityCache;
[email protected]9892b472010-09-16 00:23:42207using WebKit::WebAccessibilityNotification;
[email protected]cc0445f2009-10-13 16:09:08208using WebKit::WebAccessibilityObject;
[email protected]035545f2010-04-09 13:10:21209using WebKit::WebApplicationCacheHost;
210using WebKit::WebApplicationCacheHostClient;
[email protected]6fdd4182010-10-14 23:59:26211using WebKit::WebCString;
[email protected]1c83eb42009-09-11 21:08:41212using WebKit::WebColor;
213using WebKit::WebColorName;
[email protected]0dea3ea2009-03-31 23:30:59214using WebKit::WebConsoleMessage;
[email protected]79e37442009-10-09 18:17:44215using WebKit::WebContextMenuData;
[email protected]b921cfd22010-02-25 16:57:51216using WebKit::WebCookieJar;
[email protected]e6f546c32009-07-01 17:12:55217using WebKit::WebData;
[email protected]726985e22009-06-18 21:09:28218using WebKit::WebDataSource;
[email protected]2661b332009-11-03 18:42:29219using WebKit::WebDevToolsAgent;
[email protected]5bc8fe92010-03-11 18:19:00220using WebKit::WebDocument;
[email protected]e80c73b2009-04-07 23:24:58221using WebKit::WebDragData;
[email protected]1d9f4132009-09-08 17:29:25222using WebKit::WebDragOperation;
223using WebKit::WebDragOperationsMask;
[email protected]79dbc662009-09-04 05:42:51224using WebKit::WebEditingAction;
[email protected]9b66f34bf2010-10-27 20:45:51225using WebKit::WebElement;
[email protected]caf706f2010-10-26 17:54:08226using WebKit::WebExternalPopupMenu;
227using WebKit::WebExternalPopupMenuClient;
[email protected]cdaf8d02010-03-30 19:52:47228using WebKit::WebFileChooserCompletion;
[email protected]2b06a992010-08-21 05:48:22229using WebKit::WebFileSystem;
230using WebKit::WebFileSystemCallbacks;
[email protected]6069da8c2009-10-20 20:33:49231using WebKit::WebFindOptions;
[email protected]b1438212010-04-03 00:30:59232using WebKit::WebFormControlElement;
[email protected]979c28b2009-11-07 01:30:48233using WebKit::WebFormElement;
[email protected]dd7daa82009-08-10 05:46:45234using WebKit::WebFrame;
[email protected]ca948a22009-06-25 19:36:17235using WebKit::WebHistoryItem;
[email protected]c27ae592010-03-18 15:24:41236using WebKit::WebImage;
[email protected]e6efd022010-03-31 09:34:50237using WebKit::WebInputElement;
[email protected]3d9689372009-09-10 04:29:17238using WebKit::WebMediaPlayer;
[email protected]952cb702009-10-07 05:50:28239using WebKit::WebMediaPlayerAction;
[email protected]3d9689372009-09-10 04:29:17240using WebKit::WebMediaPlayerClient;
[email protected]4873c7d2009-07-16 06:36:28241using WebKit::WebNavigationPolicy;
[email protected]726985e22009-06-18 21:09:28242using WebKit::WebNavigationType;
[email protected]79dbc662009-09-04 05:42:51243using WebKit::WebNode;
[email protected]d9ec5c0f2009-12-23 11:55:07244using WebKit::WebPageSerializer;
245using WebKit::WebPageSerializerClient;
[email protected]3d9689372009-09-10 04:29:17246using WebKit::WebPlugin;
[email protected]00152e92010-07-19 11:47:40247using WebKit::WebPluginContainer;
[email protected]24a7f3c2010-03-25 08:26:49248using WebKit::WebPluginDocument;
[email protected]aad51d1c2010-08-05 08:38:09249using WebKit::WebPluginParams;
[email protected]48c9cf2d2009-09-16 16:47:52250using WebKit::WebPoint;
[email protected]88efb7ec2009-07-14 16:32:59251using WebKit::WebPopupMenuInfo;
[email protected]79dbc662009-09-04 05:42:51252using WebKit::WebRange;
[email protected]b3f2b912009-04-09 16:18:52253using WebKit::WebRect;
[email protected]4f999132009-03-31 18:08:40254using WebKit::WebScriptSource;
[email protected]ce0e250d2009-10-23 21:00:35255using WebKit::WebSearchableFormData;
[email protected]e3d60e5d2009-09-25 21:08:29256using WebKit::WebSecurityOrigin;
[email protected]2fab253a2009-08-17 23:00:59257using WebKit::WebSettings;
[email protected]9c00f002009-11-05 22:37:42258using WebKit::WebSharedWorker;
[email protected]8649fb32009-06-26 17:51:02259using WebKit::WebSize;
[email protected]bd92c3a2010-01-13 05:02:34260using WebKit::WebStorageNamespace;
[email protected]726985e22009-06-18 21:09:28261using WebKit::WebString;
[email protected]79dbc662009-09-04 05:42:51262using WebKit::WebTextAffinity;
[email protected]de570ef2009-07-29 18:27:52263using WebKit::WebTextDirection;
[email protected]726985e22009-06-18 21:09:28264using WebKit::WebURL;
265using WebKit::WebURLError;
266using WebKit::WebURLRequest;
267using WebKit::WebURLResponse;
[email protected]4873c7d2009-07-16 06:36:28268using WebKit::WebVector;
[email protected]50ae00ef2009-10-19 05:11:03269using WebKit::WebView;
[email protected]4873c7d2009-07-16 06:36:28270using WebKit::WebWidget;
[email protected]6fdd4182010-10-14 23:59:26271using WebKit::WebWindowFeatures;
[email protected]27ba8532009-04-24 20:22:43272using WebKit::WebWorker;
273using WebKit::WebWorkerClient;
[email protected]6fdd4182010-10-14 23:59:26274using appcache::WebApplicationCacheHostImpl;
[email protected]78192082011-01-29 05:43:44275using autofill::AutoFillAgent;
276using autofill::FormManager;
277using autofill::PasswordAutoFillManager;
[email protected]6fdd4182010-10-14 23:59:26278using base::Time;
279using base::TimeDelta;
280using webkit_glue::AltErrorPageResourceFetcher;
281using webkit_glue::FormData;
282using webkit_glue::FormField;
283using webkit_glue::ImageResourceFetcher;
284using webkit_glue::PasswordForm;
285using webkit_glue::PasswordFormDomManager;
[email protected]bb461532010-11-26 21:50:23286using webkit_glue::ResourceFetcher;
[email protected]6fdd4182010-10-14 23:59:26287using webkit_glue::SiteIsolationMetrics;
288using webkit_glue::WebAccessibility;
[email protected]e1acf6f2008-10-27 20:43:33289
initial.commit09911bf2008-07-26 23:55:29290//-----------------------------------------------------------------------------
291
[email protected]3354d3e2010-06-10 19:53:02292typedef std::map<WebKit::WebView*, RenderView*> ViewMap;
[email protected]625332e02010-12-14 07:48:49293static base::LazyInstance<ViewMap> g_view_map(base::LINKER_INITIALIZED);
[email protected]3354d3e2010-06-10 19:53:02294
initial.commit09911bf2008-07-26 23:55:29295// define to write the time necessary for thumbnail/DOM text retrieval,
296// respectively, into the system debug log
initial.commit09911bf2008-07-26 23:55:29297// #define TIME_TEXT_RETRIEVAL
298
299// maximum number of characters in the document to index, any text beyond this
300// point will be clipped
[email protected]6c8afae52009-01-22 02:24:57301static const size_t kMaxIndexChars = 65535;
initial.commit09911bf2008-07-26 23:55:29302
303// Size of the thumbnails that we'll generate
[email protected]8b4f4892009-09-04 21:52:37304static const int kThumbnailWidth = 212;
305static const int kThumbnailHeight = 132;
initial.commit09911bf2008-07-26 23:55:29306
307// Delay in milliseconds that we'll wait before capturing the page contents
308// and thumbnail.
309static const int kDelayForCaptureMs = 500;
310
311// Typically, we capture the page data once the page is loaded.
312// Sometimes, the page never finishes to load, preventing the page capture
313// To workaround this problem, we always perform a capture after the following
314// delay.
315static const int kDelayForForcedCaptureMs = 6000;
316
[email protected]882daa92009-11-05 16:31:31317// Time, in seconds, we delay before sending content state changes (such as form
318// state and scroll position) to the browser. We delay sending changes to avoid
319// spamming the browser.
320// To avoid having tab/session restore require sending a message to get the
321// current content state during tab closing we use a shorter timeout for the
322// foreground renderer. This means there is a small window of time from which
323// content state is modified and not sent to session restore, but this is
324// better than having to wake up all renderers during shutdown.
325static const int kDelaySecondsForContentStateSyncHidden = 5;
326static const int kDelaySecondsForContentStateSync = 1;
initial.commit09911bf2008-07-26 23:55:29327
[email protected]0aa55312008-10-17 21:53:08328// The maximum number of popups that can be spawned from one page.
329static const int kMaximumNumberOfUnacknowledgedPopups = 25;
330
[email protected]6fdd4182010-10-14 23:59:26331static const char kBackForwardNavigationScheme[] = "history";
[email protected]50b691c2008-10-31 19:08:35332
[email protected]726985e22009-06-18 21:09:28333static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
334 WebVector<WebURL> urls;
335 ds->redirectChain(urls);
336 result->reserve(urls.size());
337 for (size_t i = 0; i < urls.size(); ++i)
338 result->push_back(urls[i]);
339}
340
[email protected]30507922010-01-15 16:48:23341static bool PaintViewIntoCanvas(WebView* view,
342 skia::PlatformCanvas& canvas) {
343 view->layout();
344 const WebSize& size = view->size();
345
346 if (!canvas.initialize(size.width, size.height, true))
347 return false;
348
349 view->paint(webkit_glue::ToWebCanvas(&canvas),
350 WebRect(0, 0, size.width, size.height));
351 // TODO: Add a way to snapshot the whole page, not just the currently
352 // visible part.
353
354 return true;
355}
356
357// Calculates how "boring" a thumbnail is. The boring score is the
358// 0,1 ranged percentage of pixels that are the most common
359// luma. Higher boring scores indicate that a higher percentage of a
360// bitmap are all the same brightness.
361static double CalculateBoringScore(SkBitmap* bitmap) {
362 int histogram[256] = {0};
363 color_utils::BuildLumaHistogram(bitmap, histogram);
364
365 int color_count = *std::max_element(histogram, histogram + 256);
366 int pixel_count = bitmap->width() * bitmap->height();
367 return static_cast<double>(color_count) / pixel_count;
368}
369
[email protected]12bc8472010-04-15 07:29:40370// True if |frame| contains content that is white-listed for content settings.
371static bool IsWhitelistedForContentSettings(WebFrame* frame) {
372 WebSecurityOrigin origin = frame->securityOrigin();
373 if (origin.isEmpty())
374 return false; // Uninitialized document?
375
376 if (EqualsASCII(origin.protocol(), chrome::kChromeUIScheme))
377 return true; // Browser UI elements should still work.
378
379 // If the scheme is ftp: or file:, an empty file name indicates a directory
380 // listing, which requires JavaScript to function properly.
381 GURL frame_url = frame->url();
382 const char* kDirProtocols[] = { "ftp", "file" };
383 for (size_t i = 0; i < arraysize(kDirProtocols); ++i) {
384 if (EqualsASCII(origin.protocol(), kDirProtocols[i])) {
385 return frame_url.SchemeIs(kDirProtocols[i]) &&
386 frame_url.ExtractFileName().empty();
387 }
388 }
389
390 return false;
391}
392
[email protected]3a8eecb2010-04-22 23:56:30393// Returns true if the frame is navigating to an URL either into or out of an
394// extension app's extent.
[email protected]08e94b82010-12-15 22:51:04395// TODO(creis): Temporary workaround for crbug.com/65953: Only return true if
[email protected]88c15e972011-02-05 04:19:53396// we would enter an extension app's extent from a non-app, or if we leave an
397// extension with no web extent. We avoid swapping processes to exit a hosted
398// app with a web extent for now, since we do not yet restore context (such
[email protected]08e94b82010-12-15 22:51:04399// as window.opener) if the window navigates back.
[email protected]88c15e972011-02-05 04:19:53400static bool CrossesExtensionExtents(const ExtensionSet* extensions,
401 WebFrame* frame,
402 const GURL& new_url) {
[email protected]3a8eecb2010-04-22 23:56:30403 // If the URL is still empty, this is a window.open navigation. Check the
404 // opener's URL.
405 GURL old_url(frame->url());
406 if (old_url.is_empty() && frame->opener())
407 old_url = frame->opener()->url();
408
[email protected]88c15e972011-02-05 04:19:53409 bool old_url_is_hosted_app = extensions->GetByURL(old_url) &&
410 !extensions->GetByURL(old_url)->web_extent().is_empty();
[email protected]2a521c52011-01-26 18:45:21411 return !extensions->InSameExtent(old_url, new_url) &&
[email protected]88c15e972011-02-05 04:19:53412 !old_url_is_hosted_app;
[email protected]3a8eecb2010-04-22 23:56:30413}
414
[email protected]3354d3e2010-06-10 19:53:02415// Returns the ISO 639_1 language code of the specified |text|, or 'unknown'
416// if it failed.
[email protected]e5106202010-06-11 21:12:36417static std::string DetermineTextLanguage(const string16& text) {
[email protected]655f97c32010-07-22 21:24:17418 std::string language = chrome::kUnknownLanguageCode;
[email protected]3354d3e2010-06-10 19:53:02419 int num_languages = 0;
[email protected]a95586882010-08-02 18:40:08420 int text_bytes = 0;
[email protected]3354d3e2010-06-10 19:53:02421 bool is_reliable = false;
[email protected]3354d3e2010-06-10 19:53:02422 Language cld_language =
[email protected]e5106202010-06-11 21:12:36423 DetectLanguageOfUnicodeText(NULL, text.c_str(), true, &is_reliable,
[email protected]a95586882010-08-02 18:40:08424 &num_languages, NULL, &text_bytes);
425 // We don't trust the result if the CLD reports that the detection is not
426 // reliable, or if the actual text used to detect the language was less than
427 // 100 bytes (short texts can often lead to wrong results).
428 if (is_reliable && text_bytes >= 100 && cld_language != NUM_LANGUAGES &&
[email protected]3354d3e2010-06-10 19:53:02429 cld_language != UNKNOWN_LANGUAGE && cld_language != TG_UNKNOWN_LANGUAGE) {
430 // We should not use LanguageCode_ISO_639_1 because it does not cover all
431 // the languages CLD can detect. As a result, it'll return the invalid
432 // language code for tradtional Chinese among others.
433 // |LanguageCodeWithDialect| will go through ISO 639-1, ISO-639-2 and
434 // 'other' tables to do the 'right' thing. In addition, it'll return zh-CN
435 // for Simplified Chinese.
436 language = LanguageCodeWithDialects(cld_language);
437 }
438 return language;
439}
440
[email protected]9b66f34bf2010-10-27 20:45:51441// Returns true if the parameter node is a textfield, text area or a content
442// editable div.
443static bool IsEditableNode(const WebNode& node) {
444 bool is_editable_node = false;
445 if (!node.isNull()) {
446 if (node.isContentEditable()) {
447 is_editable_node = true;
448 } else if (node.isElementNode()) {
449 is_editable_node =
450 node.toConst<WebElement>().isTextFormControlElement();
451 }
452 }
453 return is_editable_node;
454}
455
[email protected]54ec7f82010-10-21 22:32:51456static bool WebAccessibilityNotificationToViewHostMsg(
457 WebAccessibilityNotification notification,
458 ViewHostMsg_AccessibilityNotification_Params::NotificationType* type) {
459 switch (notification) {
460 case WebKit::WebAccessibilityNotificationCheckedStateChanged:
461 *type = ViewHostMsg_AccessibilityNotification_Params::
462 NOTIFICATION_TYPE_CHECK_STATE_CHANGED;
463 break;
464 case WebKit::WebAccessibilityNotificationChildrenChanged:
465 *type = ViewHostMsg_AccessibilityNotification_Params::
466 NOTIFICATION_TYPE_CHILDREN_CHANGED;
467 break;
468 case WebKit::WebAccessibilityNotificationFocusedUIElementChanged:
469 *type = ViewHostMsg_AccessibilityNotification_Params::
470 NOTIFICATION_TYPE_FOCUS_CHANGED;
471 break;
472 case WebKit::WebAccessibilityNotificationLoadComplete:
473 *type = ViewHostMsg_AccessibilityNotification_Params::
474 NOTIFICATION_TYPE_LOAD_COMPLETE;
475 break;
476 case WebKit::WebAccessibilityNotificationValueChanged:
477 *type = ViewHostMsg_AccessibilityNotification_Params::
478 NOTIFICATION_TYPE_VALUE_CHANGED;
479 break;
480 case WebKit::WebAccessibilityNotificationSelectedTextChanged:
481 *type = ViewHostMsg_AccessibilityNotification_Params::
482 NOTIFICATION_TYPE_SELECTED_TEXT_CHANGED;
483 break;
484 default:
485 // TODO(ctguil): Support additional webkit notifications.
486 return false;
487 }
488 return true;
489}
490
[email protected]81f9fe0b2010-12-07 00:35:29491// Conversion for the incoming value. The map isn't perfect; v8 has Uint32,
492// and int64 which don't fit as Value::TYPE_INTEGER, so we let them fall into
[email protected]fb534c92011-02-01 01:02:07493// being TYPE_DOUBLEs. Dates are converted to a string (which can then be
494// parsed into a base::Time), as are regexps. Arrays are converted into lists,
[email protected]81f9fe0b2010-12-07 00:35:29495// recursively. We don't deal with binary objects or functions - they become
496// null values.
497static Value* ConvertV8Value(const v8::Handle<v8::Value>& v8value) {
498 if (v8value->IsBoolean()) {
499 return Value::CreateBooleanValue(v8value->BooleanValue());
500 } else if (v8value->IsInt32()) {
501 return Value::CreateIntegerValue(v8value->Int32Value());
502 } else if (v8value->IsNumber()) {
[email protected]fb534c92011-02-01 01:02:07503 return Value::CreateDoubleValue(v8value->NumberValue());
[email protected]81f9fe0b2010-12-07 00:35:29504 } else if (v8value->IsString()) {
505 return Value::CreateStringValue(*v8::String::Utf8Value(v8value));
506 } else if (v8value->IsDate()) {
507 v8::Date* date = v8::Date::Cast(*v8value);
[email protected]fb534c92011-02-01 01:02:07508 return Value::CreateDoubleValue(date->NumberValue() / 1000.0);
[email protected]81f9fe0b2010-12-07 00:35:29509 } else if (v8value->IsRegExp()) {
510 return Value::CreateStringValue(
511 *v8::String::Utf8Value(v8value->ToString()));
512 } else if (v8value->IsArray()) {
513 v8::Array* array = v8::Array::Cast(*v8value);
514 uint32_t length = array->Length();
515 scoped_ptr<ListValue> list(new ListValue);
516 for (uint32_t i = 0 ; i < length ; ++i) {
517 list->Set(i, ConvertV8Value(array->Get(i)));
518 }
519 return list.release();
520 }
521 return Value::CreateNullValue();
522}
523
initial.commit09911bf2008-07-26 23:55:29524///////////////////////////////////////////////////////////////////////////////
525
[email protected]60c42a8c72009-10-09 04:08:59526int32 RenderView::next_page_id_ = 1;
527
[email protected]cdaf8d02010-03-30 19:52:47528struct RenderView::PendingFileChooser {
529 PendingFileChooser(const ViewHostMsg_RunFileChooser_Params& p,
530 WebFileChooserCompletion* c)
531 : params(p),
532 completion(c) {
533 }
534 ViewHostMsg_RunFileChooser_Params params;
535 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback.
536};
537
[email protected]2fab253a2009-08-17 23:00:59538RenderView::RenderView(RenderThreadBase* render_thread,
[email protected]676126f72011-01-15 00:03:51539 gfx::NativeViewId parent_hwnd,
540 int32 opener_id,
541 const RendererPreferences& renderer_prefs,
542 const WebPreferences& webkit_prefs,
543 SharedRenderViewCounter* counter,
544 int32 routing_id,
545 int64 session_storage_namespace_id,
546 const string16& frame_name)
[email protected]3e2b375b2010-04-07 17:03:12547 : RenderWidget(render_thread, WebKit::WebPopupTypeNone),
[email protected]676126f72011-01-15 00:03:51548 webkit_preferences_(webkit_prefs),
[email protected]3354d3e2010-06-10 19:53:02549 send_content_state_immediately_(false),
[email protected]81e63782009-02-27 19:35:09550 enabled_bindings_(0),
[email protected]3354d3e2010-06-10 19:53:02551 send_preferred_size_changes_(false),
552 script_can_close_(true),
[email protected]81a34412009-01-05 19:17:24553 is_loading_(false),
[email protected]e75cb49e2009-01-05 23:13:21554 navigation_gesture_(NavigationGestureUnknown),
[email protected]3354d3e2010-06-10 19:53:02555 opened_by_user_gesture_(true),
556 opener_suppressed_(false),
[email protected]81a34412009-01-05 19:17:24557 page_id_(-1),
558 last_page_id_sent_to_browser_(-1),
559 last_indexed_page_id_(-1),
[email protected]3cc72b12010-03-18 23:03:00560 history_list_offset_(-1),
561 history_list_length_(0),
[email protected]81a34412009-01-05 19:17:24562 has_unload_listener_(false),
[email protected]83dde542009-09-11 20:59:55563#if defined(OS_MACOSX)
564 has_document_tag_(false),
565#endif
[email protected]98324892009-09-09 21:16:05566 document_tag_(0),
[email protected]3354d3e2010-06-10 19:53:02567 target_url_status_(TARGET_NONE),
568 spelling_panel_visible_(false),
569 view_type_(ViewType::INVALID),
570 browser_window_id_(-1),
[email protected]18ca9a6b2010-06-02 19:05:18571 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)),
[email protected]e47aec52010-08-12 00:50:30572 ALLOW_THIS_IN_INITIALIZER_LIST(page_info_method_factory_(this)),
[email protected]54ec7f82010-10-21 22:32:51573 ALLOW_THIS_IN_INITIALIZER_LIST(accessibility_method_factory_(this)),
[email protected]3354d3e2010-06-10 19:53:02574 ALLOW_THIS_IN_INITIALIZER_LIST(cookie_jar_(this)),
[email protected]676126f72011-01-15 00:03:51575 devtools_client_(NULL),
576 geolocation_dispatcher_(NULL),
577 speech_input_dispatcher_(NULL),
578 device_orientation_dispatcher_(NULL),
[email protected]54ec7f82010-10-21 22:32:51579 accessibility_ack_pending_(false),
[email protected]bb461532010-11-26 21:50:23580 pending_app_icon_requests_(0),
[email protected]5ee0cfd02011-01-18 05:42:22581 session_storage_namespace_id_(session_storage_namespace_id) {
[email protected]8de12d942010-11-17 20:42:44582#if defined(OS_MACOSX)
583 // On Mac, the select popups are rendered by the browser.
584 // Note that we don't do this in RenderMain otherwise this would not be called
585 // in single-process mode.
586 WebKit::WebView::setUseExternalPopupMenus(true);
587#endif
[email protected]676126f72011-01-15 00:03:51588
[email protected]71b0d5d2010-02-15 05:43:07589 ClearBlockedContentSettings();
[email protected]3ead1322010-11-19 20:01:00590 if (CommandLine::ForCurrentProcess()->HasSwitch(
591 switches::kEnableClientSidePhishingDetection)) {
592 phishing_delegate_.reset(
593 new safe_browsing::PhishingClassifierDelegate(this, NULL));
594 RenderThread* thread = RenderThread::current();
595 if (thread && thread->phishing_scorer()) {
596 phishing_delegate_->SetPhishingScorer(thread->phishing_scorer());
597 }
598 }
[email protected]676126f72011-01-15 00:03:51599
600 routing_id_ = routing_id;
601 if (opener_id != MSG_ROUTING_NONE)
602 opener_id_ = opener_id;
603
604 if (counter) {
605 shared_popup_counter_ = counter;
606 shared_popup_counter_->data++;
607 decrement_shared_popup_at_destruction_ = true;
608 } else {
609 shared_popup_counter_ = new SharedRenderViewCounter(0);
610 decrement_shared_popup_at_destruction_ = false;
611 }
612
613 notification_provider_ = new NotificationProvider(this);
614
615 devtools_agent_ = new DevToolsAgent(this);
[email protected]78192082011-01-29 05:43:44616 PasswordAutoFillManager* password_autofill_manager =
617 new PasswordAutoFillManager(this);
618 AutoFillAgent* autofill_agent = new AutoFillAgent(this,
619 password_autofill_manager);
[email protected]676126f72011-01-15 00:03:51620
[email protected]78192082011-01-29 05:43:44621 webwidget_ = WebView::create(this, devtools_agent_, autofill_agent);
[email protected]676126f72011-01-15 00:03:51622 g_view_map.Get().insert(std::make_pair(webview(), this));
623 webkit_preferences_.Apply(webview());
624 webview()->initializeMainFrame(this);
625 if (!frame_name.empty())
626 webview()->mainFrame()->setName(frame_name);
627
628 OnSetRendererPrefs(renderer_prefs);
629
630 render_thread_->AddRoute(routing_id_, this);
631 // Take a reference on behalf of the RenderThread. This will be balanced
632 // when we receive ViewMsg_Close.
633 AddRef();
634
635 // If this is a popup, we must wait for the CreatingNew_ACK message before
636 // completing initialization. Otherwise, we can finish it now.
637 if (opener_id == MSG_ROUTING_NONE) {
638 did_show_ = true;
639 CompleteInit(parent_hwnd);
640 }
641
642 host_window_ = parent_hwnd;
643
644 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
645 if (command_line.HasSwitch(switches::kDomAutomationController))
646 enabled_bindings_ |= BindingsPolicy::DOM_AUTOMATION;
647 if (command_line.HasSwitch(switches::kEnableAccessibility))
648 WebAccessibilityCache::enableAccessibility();
649
650 audio_message_filter_ = new AudioMessageFilter(routing_id_);
651 render_thread_->AddFilter(audio_message_filter_);
652
653 PageClickTracker* page_click_tracker = new PageClickTracker(this);
654 // Note that the order of insertion of the listeners is important.
655 // The password_autocomplete_manager takes the first shot at processing the
656 // notification and can stop the propagation.
[email protected]78192082011-01-29 05:43:44657 page_click_tracker->AddListener(password_autofill_manager);
658 page_click_tracker->AddListener(autofill_agent);
[email protected]81273622011-02-02 03:56:13659 new TranslateHelper(this);
initial.commit09911bf2008-07-26 23:55:29660}
661
662RenderView::~RenderView() {
[email protected]0aa55312008-10-17 21:53:08663 if (decrement_shared_popup_at_destruction_)
664 shared_popup_counter_->data--;
665
[email protected]a1128322009-10-06 18:38:46666 // If file chooser is still waiting for answer, dispatch empty answer.
[email protected]cdaf8d02010-03-30 19:52:47667 while (!file_chooser_completions_.empty()) {
668 if (file_chooser_completions_.front()->completion) {
669 file_chooser_completions_.front()->completion->didChooseFile(
670 WebVector<WebString>());
671 }
672 file_chooser_completions_.pop_front();
673 }
[email protected]a1128322009-10-06 18:38:46674
[email protected]83dde542009-09-11 20:59:55675#if defined(OS_MACOSX)
[email protected]98324892009-09-09 21:16:05676 // Tell the spellchecker that the document is closed.
[email protected]83dde542009-09-11 20:59:55677 if (has_document_tag_)
678 Send(new ViewHostMsg_DocumentWithTagClosed(routing_id_, document_tag_));
[email protected]c36a9b62010-10-14 00:41:11679
680 // Destroy all fake plugin window handles on the browser side.
681 while (!fake_plugin_window_handles_.empty()) {
682 // Make sure no NULL plugin window handles were inserted into this list.
683 DCHECK(*fake_plugin_window_handles_.begin());
684 // DestroyFakePluginWindowHandle modifies fake_plugin_window_handles_.
685 DestroyFakePluginWindowHandle(*fake_plugin_window_handles_.begin());
686 }
[email protected]83dde542009-09-11 20:59:55687#endif
[email protected]98324892009-09-09 21:16:05688
[email protected]5fb88962009-04-16 19:03:25689 render_thread_->RemoveFilter(audio_message_filter_);
[email protected]60c42a8c72009-10-09 04:08:59690
[email protected]3ead1322010-11-19 20:01:00691 // Tell the PhishingClassifierDelegate that the view is going away.
692 if (phishing_delegate_.get())
693 phishing_delegate_->CancelPendingClassification();
694
[email protected]60c42a8c72009-10-09 04:08:59695#ifndef NDEBUG
696 // Make sure we are no longer referenced by the ViewMap.
[email protected]625332e02010-12-14 07:48:49697 ViewMap* views = g_view_map.Pointer();
[email protected]60c42a8c72009-10-09 04:08:59698 for (ViewMap::iterator it = views->begin(); it != views->end(); ++it)
699 DCHECK_NE(this, it->second) << "Failed to call Close?";
700#endif
[email protected]676126f72011-01-15 00:03:51701
702 FOR_EACH_OBSERVER(RenderViewObserver, observers_, set_render_view(NULL));
703 FOR_EACH_OBSERVER(RenderViewObserver, observers_, OnDestruct());
[email protected]60c42a8c72009-10-09 04:08:59704}
705
706/*static*/
707void RenderView::ForEach(RenderViewVisitor* visitor) {
[email protected]625332e02010-12-14 07:48:49708 ViewMap* views = g_view_map.Pointer();
[email protected]60c42a8c72009-10-09 04:08:59709 for (ViewMap::iterator it = views->begin(); it != views->end(); ++it) {
710 if (!visitor->Visit(it->second))
711 return;
712 }
713}
714
715/*static*/
716RenderView* RenderView::FromWebView(WebView* webview) {
[email protected]625332e02010-12-14 07:48:49717 ViewMap* views = g_view_map.Pointer();
[email protected]60c42a8c72009-10-09 04:08:59718 ViewMap::iterator it = views->find(webview);
719 return it == views->end() ? NULL : it->second;
initial.commit09911bf2008-07-26 23:55:29720}
721
722/*static*/
[email protected]0aa55312008-10-17 21:53:08723RenderView* RenderView::Create(
[email protected]81a34412009-01-05 19:17:24724 RenderThreadBase* render_thread,
[email protected]18bcc3c2009-01-27 21:39:15725 gfx::NativeViewId parent_hwnd,
[email protected]0aa55312008-10-17 21:53:08726 int32 opener_id,
[email protected]80d96fa2009-06-10 22:34:51727 const RendererPreferences& renderer_prefs,
[email protected]0aa55312008-10-17 21:53:08728 const WebPreferences& webkit_prefs,
729 SharedRenderViewCounter* counter,
[email protected]4e6419c2010-01-15 04:50:34730 int32 routing_id,
[email protected]8ab04652010-06-12 02:47:26731 int64 session_storage_namespace_id,
732 const string16& frame_name) {
initial.commit09911bf2008-07-26 23:55:29733 DCHECK(routing_id != MSG_ROUTING_NONE);
[email protected]676126f72011-01-15 00:03:51734 return new RenderView(
735 render_thread,
736 parent_hwnd,
737 opener_id,
738 renderer_prefs,
739 webkit_prefs,
740 counter,
741 routing_id,
742 session_storage_namespace_id,
743 frame_name); // adds reference
initial.commit09911bf2008-07-26 23:55:29744}
745
[email protected]bb461532010-11-26 21:50:23746// static
initial.commit09911bf2008-07-26 23:55:29747void RenderView::SetNextPageID(int32 next_page_id) {
748 // This method should only be called during process startup, and the given
749 // page id had better not exceed our current next page id!
[email protected]4646f292009-05-20 03:49:05750 DCHECK_EQ(next_page_id_, 1);
initial.commit09911bf2008-07-26 23:55:29751 DCHECK(next_page_id >= next_page_id_);
752 next_page_id_ = next_page_id;
753}
754
[email protected]676126f72011-01-15 00:03:51755void RenderView::AddObserver(RenderViewObserver* observer) {
756 observers_.AddObserver(observer);
757}
758
759void RenderView::RemoveObserver(RenderViewObserver* observer) {
760 observer->set_render_view(NULL);
761 observers_.RemoveObserver(observer);
762}
763
[email protected]70eee342010-11-05 01:59:37764bool RenderView::RendererAccessibilityNotification::ShouldIncludeChildren() {
765 typedef ViewHostMsg_AccessibilityNotification_Params params;
766 if (type == params::NOTIFICATION_TYPE_CHILDREN_CHANGED ||
767 type == params::NOTIFICATION_TYPE_LOAD_COMPLETE) {
768 return true;
769 }
770 return false;
771}
772
[email protected]8a3125a712010-08-09 18:58:51773WebKit::WebView* RenderView::webview() const {
[email protected]4d51d5bf2010-07-26 18:48:26774 return static_cast<WebKit::WebView*>(webwidget());
775}
776
[email protected]afe3a1672009-11-17 19:04:12777void RenderView::UserMetricsRecordAction(const std::string& action) {
[email protected]15d04ae2010-10-30 01:04:50778 Send(new ViewHostMsg_UserMetricsRecordAction(action));
[email protected]1dbafaf72009-09-23 19:43:56779}
780
[email protected]bb461532010-11-26 21:50:23781bool RenderView::InstallWebApplicationUsingDefinitionFile(WebFrame* frame,
782 string16* error) {
783 // There is an issue of drive-by installs with the below implementation. A web
784 // site could force a user to install an app by timing the dialog to come up
785 // just before the user clicks.
786 //
787 // We do show a success UI that allows users to uninstall, but it seems that
788 // we might still want to put up an infobar before showing the install dialog.
789 //
790 // TODO(aa): Figure out this issue before removing the kEnableCrxlessWebApps
791 // switch.
792 if (!CommandLine::ForCurrentProcess()->HasSwitch(
793 switches::kEnableCrxlessWebApps)) {
794 *error = ASCIIToUTF16("CRX-less web apps aren't enabled.");
795 return false;
796 }
797
798 if (frame != frame->top()) {
799 *error = ASCIIToUTF16("Applications can only be installed from the top "
800 "frame.");
801 return false;
802 }
803
804 if (pending_app_info_.get()) {
805 *error = ASCIIToUTF16("An application install is already in progress.");
806 return false;
807 }
808
809 pending_app_info_.reset(new WebApplicationInfo());
810 if (!web_apps::ParseWebAppFromWebDocument(frame, pending_app_info_.get(),
811 error)) {
812 return false;
813 }
814
815 if (!pending_app_info_->manifest_url.is_valid()) {
816 *error = ASCIIToUTF16("Web application definition not found or invalid.");
817 return false;
818 }
819
820 app_definition_fetcher_.reset(new ResourceFetcher(
821 pending_app_info_->manifest_url, webview()->mainFrame(),
822 NewCallback(this, &RenderView::DidDownloadApplicationDefinition)));
823 return true;
824}
825
[email protected]1a3c3cb2010-12-16 21:03:40826void RenderView::SetReportLoadProgressEnabled(bool enabled) {
827 if (!enabled) {
828 load_progress_tracker_.reset(NULL);
829 return;
830 }
831 if (load_progress_tracker_ == NULL)
832 load_progress_tracker_.reset(new LoadProgressTracker(this));
833}
834
[email protected]bb461532010-11-26 21:50:23835void RenderView::DidDownloadApplicationDefinition(
836 const WebKit::WebURLResponse& response,
837 const std::string& data) {
838 scoped_ptr<WebApplicationInfo> app_info(
839 pending_app_info_.release());
840
841 JSONStringValueSerializer serializer(data);
842 int error_code = 0;
843 std::string error_message;
844 scoped_ptr<Value> result(serializer.Deserialize(&error_code, &error_message));
845 if (!result.get()) {
846 AddErrorToRootConsole(UTF8ToUTF16(error_message));
847 return;
848 }
849
850 string16 error_message_16;
851 if (!web_apps::ParseWebAppFromDefinitionFile(result.get(), app_info.get(),
852 &error_message_16)) {
853 AddErrorToRootConsole(error_message_16);
854 return;
855 }
856
857 if (!app_info->icons.empty()) {
858 pending_app_info_.reset(app_info.release());
859 pending_app_icon_requests_ =
860 static_cast<int>(pending_app_info_->icons.size());
861 for (size_t i = 0; i < pending_app_info_->icons.size(); ++i) {
862 app_icon_fetchers_.push_back(linked_ptr<ImageResourceFetcher>(
863 new ImageResourceFetcher(
864 pending_app_info_->icons[i].url,
865 webview()->mainFrame(),
866 static_cast<int>(i),
867 pending_app_info_->icons[i].width,
868 NewCallback(this, &RenderView::DidDownloadApplicationIcon))));
869 }
870 } else {
871 Send(new ViewHostMsg_InstallApplication(routing_id_, *app_info));
872 }
873}
874
875void RenderView::DidDownloadApplicationIcon(ImageResourceFetcher* fetcher,
876 const SkBitmap& image) {
877 pending_app_info_->icons[fetcher->id()].data = image;
878
879 // Remove the image fetcher from our pending list. We're in the callback from
880 // ImageResourceFetcher, best to delay deletion.
881 for (ImageResourceFetcherList::iterator iter = app_icon_fetchers_.begin();
882 iter != app_icon_fetchers_.end(); ++iter) {
883 if (iter->get() == fetcher) {
884 iter->release();
885 app_icon_fetchers_.erase(iter);
886 break;
887 }
888 }
889
890 // We're in the callback from the ImageResourceFetcher, best to delay
891 // deletion.
892 MessageLoop::current()->DeleteSoon(FROM_HERE, fetcher);
893
894 if (--pending_app_icon_requests_ > 0)
895 return;
896
897 // There is a maximum size of IPC on OS X and Linux that we have run into in
898 // some situations. We're not sure what it is, but our hypothesis is in the
899 // neighborhood of 1 MB.
900 //
901 // To be on the safe side, we give ourselves 128 KB for just the image data.
902 // This should be more than enough for 128, 48, and 16 px 32-bit icons. If we
903 // want to start allowing larger icons (see bug 63406), we'll have to either
904 // experiment mor ewith this and find the real limit, or else come up with
905 // some alternative way to transmit the icon data to the browser process.
906 //
907 // See also: bug 63729.
[email protected]678a7d72011-01-05 20:37:32908 const size_t kMaxIconSize = 1024 * 128;
909 size_t actual_icon_size = 0;
[email protected]bb461532010-11-26 21:50:23910 for (size_t i = 0; i < pending_app_info_->icons.size(); ++i) {
[email protected]678a7d72011-01-05 20:37:32911 size_t current_size = pending_app_info_->icons[i].data.getSize();
912 if (current_size > kMaxIconSize - actual_icon_size) {
913 AddErrorToRootConsole(ASCIIToUTF16(
[email protected]bb461532010-11-26 21:50:23914 "Icons are too large. Maximum total size for app icons is 128 KB."));
[email protected]678a7d72011-01-05 20:37:32915 return;
916 }
917 actual_icon_size += current_size;
[email protected]bb461532010-11-26 21:50:23918 }
919
920 Send(new ViewHostMsg_InstallApplication(routing_id_, *pending_app_info_));
921 pending_app_info_.reset(NULL);
922}
923
[email protected]a3a8fb6d2009-10-22 20:12:51924void RenderView::PluginCrashed(const FilePath& plugin_path) {
925 Send(new ViewHostMsg_CrashedPlugin(routing_id_, plugin_path));
initial.commit09911bf2008-07-26 23:55:29926}
927
[email protected]aad51d1c2010-08-05 08:38:09928WebPlugin* RenderView::CreatePluginNoCheck(WebFrame* frame,
929 const WebPluginParams& params) {
[email protected]191eb3f72010-12-21 06:27:50930 webkit::npapi::WebPluginInfo info;
[email protected]6fdd4182010-10-14 23:59:26931 bool found;
932 ContentSetting setting;
933 std::string mime_type;
934 Send(new ViewHostMsg_GetPluginInfo(
[email protected]c8f73ab2011-01-22 00:05:17935 routing_id_, params.url, frame->top()->url(), params.mimeType.utf8(),
936 &found, &info, &setting, &mime_type));
[email protected]b83ff222011-01-24 17:37:12937 if (!found || !webkit::npapi::IsPluginEnabled(info))
[email protected]aad51d1c2010-08-05 08:38:09938 return NULL;
[email protected]1a78d9f32010-12-08 06:38:45939
[email protected]0bd753682010-12-16 18:15:52940 scoped_refptr<webkit::ppapi::PluginModule> pepper_module(
[email protected]1a78d9f32010-12-08 06:38:45941 pepper_delegate_.CreatePepperPlugin(info.path));
[email protected]aad51d1c2010-08-05 08:38:09942 if (pepper_module)
[email protected]6fdd4182010-10-14 23:59:26943 return CreatePepperPlugin(frame, params, info.path, pepper_module.get());
[email protected]1a78d9f32010-12-08 06:38:45944 return CreateNPAPIPlugin(frame, params, info.path, mime_type);
[email protected]aad51d1c2010-08-05 08:38:09945}
946
[email protected]d8fd6fa2010-02-01 15:54:26947void RenderView::RegisterPluginDelegate(WebPluginDelegateProxy* delegate) {
948 plugin_delegates_.insert(delegate);
[email protected]49232292010-09-03 19:07:30949 // If the renderer is visible, set initial visibility and focus state.
950 if (!is_hidden()) {
[email protected]784ea1ab2010-09-18 00:02:34951#if defined(OS_MACOSX)
[email protected]49232292010-09-03 19:07:30952 delegate->SetContainerVisibility(true);
953 if (webview() && webview()->isActive())
954 delegate->SetWindowFocus(true);
[email protected]784ea1ab2010-09-18 00:02:34955#endif
[email protected]49232292010-09-03 19:07:30956 }
[email protected]784ea1ab2010-09-18 00:02:34957 // Plugins start assuming the content has focus (so that they work in
958 // environments where RenderView isn't hosting them), so we always have to
959 // set the initial state. See webplugin_delegate_impl.h for details.
960 delegate->SetContentAreaFocus(has_focus());
[email protected]d8fd6fa2010-02-01 15:54:26961}
962
963void RenderView::UnregisterPluginDelegate(WebPluginDelegateProxy* delegate) {
964 plugin_delegates_.erase(delegate);
965}
[email protected]d8fd6fa2010-02-01 15:54:26966
[email protected]a95986a82010-12-24 06:19:28967bool RenderView::OnMessageReceived(const IPC::Message& message) {
[email protected]26aa0482009-09-30 16:55:27968 WebFrame* main_frame = webview() ? webview()->mainFrame() : NULL;
[email protected]a9f607e2009-10-23 19:59:27969 if (main_frame)
970 child_process_logging::SetActiveURL(main_frame->url());
[email protected]f8b6b6f2009-03-10 16:48:26971
[email protected]676126f72011-01-15 00:03:51972 ObserverListBase<RenderViewObserver>::Iterator it(observers_);
973 RenderViewObserver* observer;
974 while ((observer = it.GetNext()) != NULL)
975 if (observer->OnMessageReceived(message))
976 return true;
[email protected]b2abac72009-02-26 12:39:28977
[email protected]a95986a82010-12-24 06:19:28978 bool handled = true;
initial.commit09911bf2008-07-26 23:55:29979 IPC_BEGIN_MESSAGE_MAP(RenderView, message)
[email protected]9b18a84f2010-06-10 15:54:04980 IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, OnCaptureThumbnail)
981 IPC_MESSAGE_HANDLER(ViewMsg_CaptureSnapshot, OnCaptureSnapshot)
initial.commit09911bf2008-07-26 23:55:29982 IPC_MESSAGE_HANDLER(ViewMsg_PrintPages, OnPrintPages)
[email protected]82270452009-06-19 15:58:01983 IPC_MESSAGE_HANDLER(ViewMsg_PrintingDone, OnPrintingDone)
[email protected]521b2482011-01-15 00:10:10984 IPC_MESSAGE_HANDLER(ViewMsg_PrintPreview, OnPrintPreview)
985 IPC_MESSAGE_HANDLER(ViewMsg_PrintNodeUnderContextMenu,
986 OnPrintNodeUnderContextMenu)
initial.commit09911bf2008-07-26 23:55:29987 IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
988 IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
[email protected]1dda4022010-01-28 18:24:56989 IPC_MESSAGE_HANDLER(ViewMsg_ReloadFrame, OnReloadFrame)
initial.commit09911bf2008-07-26 23:55:29990 IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)
991 IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)
992 IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)
993 IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)
[email protected]c0cc3092009-09-12 08:27:27994#if defined(OS_MACOSX)
[email protected]a954bf72009-09-12 07:30:35995 IPC_MESSAGE_HANDLER(ViewMsg_CopyToFindPboard, OnCopyToFindPboard)
[email protected]c0cc3092009-09-12 08:27:27996#endif
initial.commit09911bf2008-07-26 23:55:29997 IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)
998 IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)
[email protected]98324892009-09-09 21:16:05999 IPC_MESSAGE_HANDLER(ViewMsg_ToggleSpellPanel, OnToggleSpellPanel)
1000 IPC_MESSAGE_HANDLER(ViewMsg_AdvanceToNextMisspelling,
1001 OnAdvanceToNextMisspelling)
[email protected]bbbd545c2008-12-15 20:18:041002 IPC_MESSAGE_HANDLER(ViewMsg_ToggleSpellCheck, OnToggleSpellCheck)
initial.commit09911bf2008-07-26 23:55:291003 IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)
1004 IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)
1005 IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
[email protected]4b59ae602009-06-23 20:58:151006 IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand)
initial.commit09911bf2008-07-26 23:55:291007 IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
[email protected]24a7f3c2010-03-25 08:26:491008 IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
1009 IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)
[email protected]630e26b2008-10-14 22:55:171010 IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
[email protected]9d797f32010-04-23 07:17:541011 IPC_MESSAGE_HANDLER(ViewMsg_SetContentSettingsForLoadingURL,
1012 OnSetContentSettingsForLoadingURL)
[email protected]d0b8d092010-10-25 04:05:171013 IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevel, OnSetZoomLevel)
[email protected]9d797f32010-04-23 07:17:541014 IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForLoadingURL,
1015 OnSetZoomLevelForLoadingURL)
initial.commit09911bf2008-07-26 23:55:291016 IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
[email protected]a697f4c2009-09-14 22:30:181017 IPC_MESSAGE_HANDLER(ViewMsg_ResetPageEncodingToDefault,
1018 OnResetPageEncodingToDefault)
[email protected]b2abac72009-02-26 12:39:281019 IPC_MESSAGE_HANDLER(ViewMsg_SetupDevToolsClient, OnSetupDevToolsClient)
[email protected]bf5c2ff392009-07-08 16:24:331020 IPC_MESSAGE_HANDLER(ViewMsg_DownloadFavIcon, OnDownloadFavIcon)
initial.commit09911bf2008-07-26 23:55:291021 IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
[email protected]1810e132009-03-24 23:35:481022 IPC_MESSAGE_HANDLER(ViewMsg_CSSInsertRequest, OnCSSInsertRequest)
initial.commit09911bf2008-07-26 23:55:291023 IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)
initial.commit09911bf2008-07-26 23:55:291024 IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)
initial.commit09911bf2008-07-26 23:55:291025 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)
1026 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)
1027 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)
1028 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)
[email protected]18cb2572008-08-21 20:34:451029 IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)
initial.commit09911bf2008-07-26 23:55:291030 IPC_MESSAGE_HANDLER(ViewMsg_SetDOMUIProperty, OnSetDOMUIProperty)
[email protected]266eb6f2008-09-30 23:56:501031 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved,
1032 OnDragSourceEndedOrMoved)
initial.commit09911bf2008-07-26 23:55:291033 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,
1034 OnDragSourceSystemDragEnded)
1035 IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)
[email protected]9b66f34bf2010-10-27 20:45:511036 IPC_MESSAGE_HANDLER(ViewMsg_ScrollFocusedEditableNodeIntoView,
1037 OnScrollFocusedEditableNodeIntoView)
initial.commit09911bf2008-07-26 23:55:291038 IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)
1039 IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
1040 IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)
1041 IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)
[email protected]90dba072011-01-20 20:10:201042 IPC_MESSAGE_HANDLER(ViewMsg_DisplayPrerenderedPage,
1043 OnDisplayPrerenderedPage)
initial.commit09911bf2008-07-26 23:55:291044 IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
1045 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)
initial.commit09911bf2008-07-26 23:55:291046 IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,
1047 OnGetAllSavableResourceLinksForCurrentPage)
[email protected]f09c7182009-03-10 12:54:041048 IPC_MESSAGE_HANDLER(
1049 ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,
1050 OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)
initial.commit09911bf2008-07-26 23:55:291051 IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)
[email protected]9b18a84f2010-06-10 15:54:041052 IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnShouldClose)
initial.commit09911bf2008-07-26 23:55:291053 IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
1054 IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)
[email protected]18cb2572008-08-21 20:34:451055 IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,
[email protected]9b18a84f2010-06-10 15:54:041056 OnHandleMessageFromExternalHost)
[email protected]0aa55312008-10-17 21:53:081057 IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
1058 OnDisassociateFromPopupCount)
[email protected]e8345242010-05-06 03:00:401059 IPC_MESSAGE_HANDLER(ViewMsg_AllowScriptToClose,
1060 OnAllowScriptToClose)
[email protected]30f75e62009-02-25 22:01:001061 IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
[email protected]309d7a282009-03-24 09:18:271062 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionResponse, OnExtensionResponse)
[email protected]7120f132009-07-20 21:05:371063 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionMessageInvoke,
1064 OnExtensionMessageInvoke)
[email protected]05d478752009-04-08 23:38:161065 IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
[email protected]699ab0d2009-04-23 23:19:141066 IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
[email protected]ab32b16c2009-10-16 14:57:251067 IPC_MESSAGE_HANDLER(ViewMsg_EnablePreferredSizeChangedMode,
1068 OnEnablePreferredSizeChangedMode)
[email protected]ce833282010-11-04 15:48:391069 IPC_MESSAGE_HANDLER(ViewMsg_SearchBoxChange, OnSearchBoxChange)
1070 IPC_MESSAGE_HANDLER(ViewMsg_SearchBoxSubmit, OnSearchBoxSubmit)
1071 IPC_MESSAGE_HANDLER(ViewMsg_SearchBoxCancel, OnSearchBoxCancel)
1072 IPC_MESSAGE_HANDLER(ViewMsg_SearchBoxResize, OnSearchBoxResize)
1073 IPC_MESSAGE_HANDLER(ViewMsg_DetermineIfPageSupportsInstant,
1074 OnDetermineIfPageSupportsInstant)
[email protected]cda45c02010-02-25 19:28:101075 IPC_MESSAGE_HANDLER(ViewMsg_DisableScrollbarsForSmallWindows,
1076 OnDisableScrollbarsForSmallWindows)
[email protected]80d96fa2009-06-10 22:34:511077 IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
[email protected]7b291f92009-08-14 05:43:531078 IPC_MESSAGE_HANDLER(ViewMsg_UpdateBrowserWindowId,
1079 OnUpdateBrowserWindowId)
1080 IPC_MESSAGE_HANDLER(ViewMsg_NotifyRenderViewType,
1081 OnNotifyRendererViewType)
[email protected]581b87eb2009-07-23 23:06:561082 IPC_MESSAGE_HANDLER(ViewMsg_MediaPlayerActionAt, OnMediaPlayerActionAt)
[email protected]8c66c5a2009-07-22 17:26:341083 IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
[email protected]6ce7abc52010-02-02 18:40:141084#if defined(OS_MACOSX)
1085 IPC_MESSAGE_HANDLER(ViewMsg_SetWindowVisibility, OnSetWindowVisibility)
[email protected]1e6e3c992010-02-08 15:52:131086 IPC_MESSAGE_HANDLER(ViewMsg_WindowFrameChanged, OnWindowFrameChanged)
[email protected]b7f75862011-01-21 21:15:131087 IPC_MESSAGE_HANDLER(ViewMsg_PluginImeCompositionCompleted,
1088 OnPluginImeCompositionCompleted)
[email protected]6ce7abc52010-02-02 18:40:141089#endif
[email protected]446705872009-09-10 07:22:481090 IPC_MESSAGE_HANDLER(ViewMsg_SetEditCommandsForNextKeyEvent,
[email protected]a0c7153e2009-12-09 14:36:331091 OnSetEditCommandsForNextKeyEvent)
[email protected]912256b32009-09-18 09:47:351092 IPC_MESSAGE_HANDLER(ViewMsg_ExecuteCode,
1093 OnExecuteCode)
[email protected]a0c7153e2009-12-09 14:36:331094 IPC_MESSAGE_HANDLER(ViewMsg_CustomContextMenuAction,
1095 OnCustomContextMenuAction)
[email protected]dea2d372010-09-25 06:41:141096 IPC_MESSAGE_HANDLER(ViewMsg_EnableAccessibility, OnEnableAccessibility)
[email protected]aef92842010-05-21 16:54:361097 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityFocus, OnSetAccessibilityFocus)
1098 IPC_MESSAGE_HANDLER(ViewMsg_AccessibilityDoDefaultAction,
1099 OnAccessibilityDoDefaultAction)
[email protected]9892b472010-09-16 00:23:421100 IPC_MESSAGE_HANDLER(ViewMsg_AccessibilityNotifications_ACK,
1101 OnAccessibilityNotificationsAck)
[email protected]27a9ef32010-09-10 04:06:241102 IPC_MESSAGE_HANDLER(ViewMsg_AsyncOpenFile_ACK, OnAsyncFileOpened)
[email protected]caf706f2010-10-26 17:54:081103#if defined(OS_MACOSX)
1104 IPC_MESSAGE_HANDLER(ViewMsg_SelectPopupMenuItem, OnSelectPopupMenuItem)
1105#endif
[email protected]a6097f42011-01-10 08:50:511106 IPC_MESSAGE_HANDLER(ViewMsg_JavaScriptStressTestControl,
1107 OnJavaScriptStressTestControl)
[email protected]521b2482011-01-15 00:10:101108 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed)
[email protected]634a6f92008-12-01 21:39:311109
[email protected]f0557932011-01-25 20:20:511110 // TODO(viettrungluu): Move to a separate message filter.
1111#if defined(ENABLE_FLAPPER_HACKS)
1112 IPC_MESSAGE_HANDLER(PepperMsg_ConnectTcpACK, OnConnectTcpACK)
1113#endif
1114
initial.commit09911bf2008-07-26 23:55:291115 // Have the super handle all other messages.
[email protected]a95986a82010-12-24 06:19:281116 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message))
initial.commit09911bf2008-07-26 23:55:291117 IPC_END_MESSAGE_MAP()
[email protected]a95986a82010-12-24 06:19:281118 return handled;
initial.commit09911bf2008-07-26 23:55:291119}
1120
[email protected]9b18a84f2010-06-10 15:54:041121void RenderView::OnCaptureThumbnail() {
[email protected]26aa0482009-09-30 16:55:271122 WebFrame* main_frame = webview()->mainFrame();
initial.commit09911bf2008-07-26 23:55:291123 if (!main_frame)
1124 return;
1125
1126 // get the URL for this page
[email protected]dd7daa82009-08-10 05:46:451127 GURL url(main_frame->url());
initial.commit09911bf2008-07-26 23:55:291128 if (url.is_empty())
1129 return;
1130
1131 if (size_.IsEmpty())
1132 return; // Don't create an empty thumbnail!
1133
1134 ThumbnailScore score;
1135 SkBitmap thumbnail;
[email protected]8649fb32009-06-26 17:51:021136 if (!CaptureThumbnail(webview(), kThumbnailWidth, kThumbnailHeight,
[email protected]b6e4bec2008-11-12 01:17:151137 &thumbnail, &score))
1138 return;
1139
initial.commit09911bf2008-07-26 23:55:291140 // send the thumbnail message to the browser process
[email protected]674741932009-02-04 23:44:461141 Send(new ViewHostMsg_Thumbnail(routing_id_, url, score, thumbnail));
initial.commit09911bf2008-07-26 23:55:291142}
1143
[email protected]9b18a84f2010-06-10 15:54:041144void RenderView::OnCaptureSnapshot() {
[email protected]30507922010-01-15 16:48:231145 SkBitmap snapshot;
1146 bool error = false;
1147
1148 WebFrame* main_frame = webview()->mainFrame();
1149 if (!main_frame)
1150 error = true;
1151
1152 if (!error && !CaptureSnapshot(webview(), &snapshot))
1153 error = true;
1154
1155 DCHECK(error == snapshot.empty()) <<
1156 "Snapshot should be empty on error, non-empty otherwise.";
1157
1158 // Send the snapshot to the browser process.
1159 Send(new ViewHostMsg_Snapshot(routing_id_, snapshot));
1160}
1161
[email protected]068637222009-01-29 16:58:071162void RenderView::OnPrintPages() {
[email protected]c7a827e2011-01-21 00:27:011163 OnPrint(false);
initial.commit09911bf2008-07-26 23:55:291164}
1165
[email protected]82270452009-06-19 15:58:011166void RenderView::OnPrintingDone(int document_cookie, bool success) {
1167 // Ignoring document cookie here since only one print job can be outstanding
1168 // per renderer and document_cookie is 0 when printing is successful.
1169 DCHECK(print_helper_.get());
1170 if (print_helper_.get() != NULL) {
1171 print_helper_->DidFinishPrinting(success);
1172 }
1173}
1174
[email protected]212a49d2010-10-25 18:23:471175void RenderView::OnPrintPreview() {
[email protected]c7a827e2011-01-21 00:27:011176 OnPrint(true);
[email protected]212a49d2010-10-25 18:23:471177}
1178
[email protected]521b2482011-01-15 00:10:101179void RenderView::OnPrintNodeUnderContextMenu() {
1180 if (context_menu_node_.isNull()) {
1181 NOTREACHED();
1182 return;
1183 }
1184
1185 // Make a copy of the node, since we will do a sync call to the browser and
1186 // during that time OnContextMenuClosed might reset context_menu_node_.
1187 WebNode context_menu_node(context_menu_node_);
1188 GetPrintWebViewHelper()->PrintNode(&context_menu_node, false, false);
1189}
1190
initial.commit09911bf2008-07-26 23:55:291191void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) {
1192 if (load_id != page_id_)
1193 return; // this capture call is no longer relevant due to navigation
1194 if (load_id == last_indexed_page_id_)
1195 return; // we already indexed this page
1196
1197 if (!webview())
1198 return;
1199
[email protected]26aa0482009-09-30 16:55:271200 WebFrame* main_frame = webview()->mainFrame();
initial.commit09911bf2008-07-26 23:55:291201 if (!main_frame)
1202 return;
1203
1204 // Don't index/capture pages that are in view source mode.
[email protected]dd7daa82009-08-10 05:46:451205 if (main_frame->isViewSourceModeEnabled())
initial.commit09911bf2008-07-26 23:55:291206 return;
1207
1208 // Don't index/capture pages that failed to load. This only checks the top
1209 // level frame so the thumbnail may contain a frame that failed to load.
[email protected]dd7daa82009-08-10 05:46:451210 WebDataSource* ds = main_frame->dataSource();
[email protected]726985e22009-06-18 21:09:281211 if (ds && ds->hasUnreachableURL())
initial.commit09911bf2008-07-26 23:55:291212 return;
1213
1214 if (!preliminary_capture)
1215 last_indexed_page_id_ = load_id;
1216
[email protected]a8a81292010-01-21 00:32:451217 // Get the URL for this page.
[email protected]dd7daa82009-08-10 05:46:451218 GURL url(main_frame->url());
initial.commit09911bf2008-07-26 23:55:291219 if (url.is_empty())
1220 return;
1221
[email protected]a8a81292010-01-21 00:32:451222 // Retrieve the frame's full text.
[email protected]e5106202010-06-11 21:12:361223 string16 contents;
initial.commit09911bf2008-07-26 23:55:291224 CaptureText(main_frame, &contents);
1225 if (contents.size()) {
[email protected]1c57b7b2010-07-12 17:38:101226 WebKit::WebDocument document = main_frame->document();
[email protected]5ddfd63e2010-09-01 15:48:371227 // If the page explicitly specifies a language, use it, otherwise we'll
1228 // determine it based on the text content using the CLD.
1229 std::string language =
1230 TranslateHelper::GetPageLanguageFromMetaTag(&document);
1231 if (language.empty()) {
1232 base::TimeTicks begin_time = base::TimeTicks::Now();
1233 language = DetermineTextLanguage(contents);
1234 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer4.LanguageDetection",
1235 base::TimeTicks::Now() - begin_time);
1236 }
[email protected]a8a81292010-01-21 00:32:451237 // Send the text to the browser for indexing (the browser might decide not
1238 // to index, if the URL is HTTPS for instance) and language discovery.
[email protected]5ddfd63e2010-09-01 15:48:371239 Send(new ViewHostMsg_PageContents(
1240 routing_id_, url, load_id, contents, language,
1241 TranslateHelper::IsPageTranslatable(&document)));
[email protected]5c4266922009-07-10 16:41:271242 }
1243
[email protected]d54169e92011-01-21 09:19:521244 // Generate the thumbnail here if the in-browser thumbnailing isn't
1245 // enabled. TODO(satorux): Remove this and related code once
1246 // crbug.com/65936 is complete.
1247 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1248 switches::kEnableInBrowserThumbnailing)) {
1249 OnCaptureThumbnail();
1250 }
[email protected]3ead1322010-11-19 20:01:001251
1252 if (phishing_delegate_.get())
1253 phishing_delegate_->FinishedLoad(&contents);
initial.commit09911bf2008-07-26 23:55:291254}
1255
[email protected]e5106202010-06-11 21:12:361256void RenderView::CaptureText(WebFrame* frame, string16* contents) {
initial.commit09911bf2008-07-26 23:55:291257 contents->clear();
1258 if (!frame)
1259 return;
1260
1261#ifdef TIME_TEXT_RETRIEVAL
1262 double begin = time_util::GetHighResolutionTimeNow();
1263#endif
1264
1265 // get the contents of the frame
[email protected]e5106202010-06-11 21:12:361266 *contents = frame->contentAsText(kMaxIndexChars);
initial.commit09911bf2008-07-26 23:55:291267
1268#ifdef TIME_TEXT_RETRIEVAL
1269 double end = time_util::GetHighResolutionTimeNow();
1270 char buf[128];
1271 sprintf_s(buf, "%d chars retrieved for indexing in %gms\n",
1272 contents.size(), (end - begin)*1000);
1273 OutputDebugStringA(buf);
1274#endif
1275
1276 // When the contents are clipped to the maximum, we don't want to have a
1277 // partial word indexed at the end that might have been clipped. Therefore,
1278 // terminate the string at the last space to ensure no words are clipped.
1279 if (contents->size() == kMaxIndexChars) {
[email protected]e5106202010-06-11 21:12:361280 size_t last_space_index = contents->find_last_of(kWhitespaceUTF16);
initial.commit09911bf2008-07-26 23:55:291281 if (last_space_index == std::wstring::npos)
1282 return; // don't index if we got a huge block of text with no spaces
1283 contents->resize(last_space_index);
1284 }
1285}
1286
[email protected]8649fb32009-06-26 17:51:021287bool RenderView::CaptureThumbnail(WebView* view,
initial.commit09911bf2008-07-26 23:55:291288 int w,
1289 int h,
1290 SkBitmap* thumbnail,
1291 ThumbnailScore* score) {
[email protected]30507922010-01-15 16:48:231292 base::TimeTicks beginning_time = base::TimeTicks::Now();
[email protected]b6e4bec2008-11-12 01:17:151293
[email protected]8649fb32009-06-26 17:51:021294 skia::PlatformCanvas canvas;
[email protected]30507922010-01-15 16:48:231295
1296 // Paint |view| into |canvas|.
1297 if (!PaintViewIntoCanvas(view, canvas))
[email protected]8649fb32009-06-26 17:51:021298 return false;
[email protected]8649fb32009-06-26 17:51:021299
1300 skia::BitmapPlatformDevice& device =
1301 static_cast<skia::BitmapPlatformDevice&>(canvas.getTopPlatformDevice());
1302
1303 const SkBitmap& src_bmp = device.accessBitmap(false);
initial.commit09911bf2008-07-26 23:55:291304
[email protected]cab34d6a2009-09-24 01:14:521305 SkRect dest_rect = { 0, 0, SkIntToScalar(w), SkIntToScalar(h) };
initial.commit09911bf2008-07-26 23:55:291306 float dest_aspect = dest_rect.width() / dest_rect.height();
1307
1308 // Get the src rect so that we can preserve the aspect ratio while filling
1309 // the destination.
1310 SkIRect src_rect;
1311 if (src_bmp.width() < dest_rect.width() ||
1312 src_bmp.height() < dest_rect.height()) {
1313 // Source image is smaller: we clip the part of source image within the
1314 // dest rect, and then stretch it to fill the dest rect. We don't respect
1315 // the aspect ratio in this case.
1316 src_rect.set(0, 0, static_cast<S16CPU>(dest_rect.width()),
1317 static_cast<S16CPU>(dest_rect.height()));
1318 score->good_clipping = false;
1319 } else {
1320 float src_aspect = static_cast<float>(src_bmp.width()) / src_bmp.height();
1321 if (src_aspect > dest_aspect) {
1322 // Wider than tall, clip horizontally: we center the smaller thumbnail in
1323 // the wider screen.
1324 S16CPU new_width = static_cast<S16CPU>(src_bmp.height() * dest_aspect);
1325 S16CPU x_offset = (src_bmp.width() - new_width) / 2;
1326 src_rect.set(x_offset, 0, new_width + x_offset, src_bmp.height());
1327 score->good_clipping = false;
1328 } else {
1329 src_rect.set(0, 0, src_bmp.width(),
1330 static_cast<S16CPU>(src_bmp.width() / dest_aspect));
1331 score->good_clipping = true;
1332 }
1333 }
1334
[email protected]26aa0482009-09-30 16:55:271335 score->at_top = (view->mainFrame()->scrollOffset().height == 0);
initial.commit09911bf2008-07-26 23:55:291336
1337 SkBitmap subset;
[email protected]8649fb32009-06-26 17:51:021338 device.accessBitmap(false).extractSubset(&subset, src_rect);
initial.commit09911bf2008-07-26 23:55:291339
[email protected]82afe4b2010-11-12 20:36:221340 // First do a fast downsample by powers of two to get close to the final size.
1341 SkBitmap downsampled_subset =
1342 SkBitmapOperations::DownsampleByTwoUntilSize(subset, w, h);
1343
1344 // Do a high-quality resize from the downscaled size to the final size.
[email protected]465b34b72008-12-12 20:19:141345 *thumbnail = skia::ImageOperations::Resize(
[email protected]82afe4b2010-11-12 20:36:221346 downsampled_subset, skia::ImageOperations::RESIZE_LANCZOS3, w, h);
initial.commit09911bf2008-07-26 23:55:291347
1348 score->boring_score = CalculateBoringScore(thumbnail);
1349
[email protected]30507922010-01-15 16:48:231350 HISTOGRAM_TIMES("Renderer4.Thumbnail",
1351 base::TimeTicks::Now() - beginning_time);
[email protected]82afe4b2010-11-12 20:36:221352
[email protected]b6e4bec2008-11-12 01:17:151353 return true;
initial.commit09911bf2008-07-26 23:55:291354}
1355
[email protected]30507922010-01-15 16:48:231356bool RenderView::CaptureSnapshot(WebView* view, SkBitmap* snapshot) {
1357 base::TimeTicks beginning_time = base::TimeTicks::Now();
initial.commit09911bf2008-07-26 23:55:291358
[email protected]30507922010-01-15 16:48:231359 skia::PlatformCanvas canvas;
1360 if (!PaintViewIntoCanvas(view, canvas))
1361 return false;
1362
1363 skia::BitmapPlatformDevice& device =
1364 static_cast<skia::BitmapPlatformDevice&>(canvas.getTopPlatformDevice());
1365
1366 const SkBitmap& bitmap = device.accessBitmap(false);
1367 if (!bitmap.copyTo(snapshot, SkBitmap::kARGB_8888_Config))
1368 return false;
1369
1370 HISTOGRAM_TIMES("Renderer4.Snapshot",
1371 base::TimeTicks::Now() - beginning_time);
1372 return true;
initial.commit09911bf2008-07-26 23:55:291373}
1374
1375void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {
1376 if (!webview())
1377 return;
1378
[email protected]3cc72b12010-03-18 23:03:001379 history_list_offset_ = params.current_history_list_offset;
1380 history_list_length_ = params.current_history_list_length;
1381
[email protected]a9f607e2009-10-23 19:59:271382 child_process_logging::SetActiveURL(params.url);
[email protected]f8b6b6f2009-03-10 16:48:261383
initial.commit09911bf2008-07-26 23:55:291384 AboutHandler::MaybeHandle(params.url);
1385
[email protected]ecbf10d2010-02-18 13:03:291386 bool is_reload =
1387 params.navigation_type == ViewMsg_Navigate_Params::RELOAD ||
1388 params.navigation_type == ViewMsg_Navigate_Params::RELOAD_IGNORING_CACHE;
initial.commit09911bf2008-07-26 23:55:291389
[email protected]26aa0482009-09-30 16:55:271390 WebFrame* main_frame = webview()->mainFrame();
[email protected]dd7daa82009-08-10 05:46:451391 if (is_reload && main_frame->currentHistoryItem().isNull()) {
initial.commit09911bf2008-07-26 23:55:291392 // We cannot reload if we do not have any history state. This happens, for
1393 // example, when recovering from a crash. Our workaround here is a bit of
1394 // a hack since it means that reload after a crashed tab does not cause an
1395 // end-to-end cache validation.
1396 is_reload = false;
1397 }
1398
[email protected]77f17a82009-05-21 04:42:541399 // A navigation resulting from loading a javascript URL should not be treated
1400 // as a browser initiated event. Instead, we want it to look as if the page
1401 // initiated any load resulting from JS execution.
1402 if (!params.url.SchemeIs(chrome::kJavaScriptScheme)) {
[email protected]5e369672009-11-03 23:48:301403 NavigationState* state = NavigationState::CreateBrowserInitiated(
[email protected]3cc72b12010-03-18 23:03:001404 params.page_id,
1405 params.pending_history_list_offset,
1406 params.transition,
1407 params.request_time);
[email protected]5e369672009-11-03 23:48:301408 if (params.navigation_type == ViewMsg_Navigate_Params::RESTORE) {
1409 // We're doing a load of a page that was restored from the last session.
1410 // By default this prefers the cache over loading (LOAD_PREFERRING_CACHE)
1411 // which can result in stale data for pages that are set to expire. We
1412 // explicitly override that by setting the policy here so that as
1413 // necessary we load from the network.
1414 state->set_cache_policy_override(WebURLRequest::UseProtocolCachePolicy);
1415 }
1416 pending_navigation_state_.reset(state);
[email protected]77f17a82009-05-21 04:42:541417 }
initial.commit09911bf2008-07-26 23:55:291418
[email protected]a7ccc4d2010-01-27 08:14:481419 NavigationState* navigation_state = pending_navigation_state_.get();
1420
[email protected]04d3c6e2009-05-22 17:00:131421 // If we are reloading, then WebKit will use the history state of the current
1422 // page, so we should just ignore any given history state. Otherwise, if we
1423 // have history state, then we need to navigate to it, which corresponds to a
1424 // back/forward navigation event.
[email protected]e6f546c32009-07-01 17:12:551425 if (is_reload) {
[email protected]a7ccc4d2010-01-27 08:14:481426 if (navigation_state)
1427 navigation_state->set_load_type(NavigationState::RELOAD);
[email protected]ecbf10d2010-02-18 13:03:291428 bool ignore_cache = (params.navigation_type ==
1429 ViewMsg_Navigate_Params::RELOAD_IGNORING_CACHE);
1430 main_frame->reload(ignore_cache);
[email protected]e6f546c32009-07-01 17:12:551431 } else if (!params.state.empty()) {
[email protected]04d3c6e2009-05-22 17:00:131432 // We must know the page ID of the page we are navigating back to.
[email protected]f929f2f22009-06-12 16:56:581433 DCHECK_NE(params.page_id, -1);
[email protected]a7ccc4d2010-01-27 08:14:481434 if (navigation_state)
1435 navigation_state->set_load_type(NavigationState::HISTORY_LOAD);
[email protected]dd7daa82009-08-10 05:46:451436 main_frame->loadHistoryItem(
[email protected]ca948a22009-06-25 19:36:171437 webkit_glue::HistoryItemFromString(params.state));
[email protected]04d3c6e2009-05-22 17:00:131438 } else {
1439 // Navigate to the given URL.
[email protected]726985e22009-06-18 21:09:281440 WebURLRequest request(params.url);
initial.commit09911bf2008-07-26 23:55:291441
[email protected]e6f546c32009-07-01 17:12:551442 // A session history navigation should have been accompanied by state.
1443 DCHECK_EQ(params.page_id, -1);
[email protected]04d3c6e2009-05-22 17:00:131444
[email protected]dd7daa82009-08-10 05:46:451445 if (main_frame->isViewSourceModeEnabled())
[email protected]e6f546c32009-07-01 17:12:551446 request.setCachePolicy(WebURLRequest::ReturnCacheDataElseLoad);
[email protected]04d3c6e2009-05-22 17:00:131447
[email protected]726985e22009-06-18 21:09:281448 if (params.referrer.is_valid()) {
1449 request.setHTTPHeaderField(WebString::fromUTF8("Referer"),
1450 WebString::fromUTF8(params.referrer.spec()));
1451 }
[email protected]04d3c6e2009-05-22 17:00:131452
[email protected]52c68652010-12-07 17:47:041453 if (!params.extra_headers.empty()) {
1454 for (net::HttpUtil::HeadersIterator i(params.extra_headers.begin(),
1455 params.extra_headers.end(), "\n");
1456 i.GetNext(); ) {
1457 request.addHTTPHeaderField(WebString::fromUTF8(i.name()),
1458 WebString::fromUTF8(i.values()));
1459 }
1460 }
1461
[email protected]90dba072011-01-20 20:10:201462 if (navigation_state) {
1463 if (params.navigation_type != ViewMsg_Navigate_Params::PRERENDER) {
1464 navigation_state->set_load_type(NavigationState::NORMAL_LOAD);
1465 } else {
1466 navigation_state->set_load_type(NavigationState::PRERENDER_LOAD);
1467 navigation_state->set_is_prerendering(true);
1468 }
1469 }
[email protected]dd7daa82009-08-10 05:46:451470 main_frame->loadRequest(request);
[email protected]c0588052008-10-27 23:01:501471 }
1472
[email protected]77f17a82009-05-21 04:42:541473 // In case LoadRequest failed before DidCreateDataSource was called.
1474 pending_navigation_state_.reset();
initial.commit09911bf2008-07-26 23:55:291475}
1476
1477// Stop loading the current page
1478void RenderView::OnStop() {
1479 if (webview())
[email protected]b4bb2502009-10-01 22:35:271480 webview()->mainFrame()->stopLoading();
initial.commit09911bf2008-07-26 23:55:291481}
1482
[email protected]ecbf10d2010-02-18 13:03:291483// Reload current focused frame.
1484// E.g. called by right-clicking on the frame and picking "reload this frame".
[email protected]1dda4022010-01-28 18:24:561485void RenderView::OnReloadFrame() {
[email protected]ecbf10d2010-02-18 13:03:291486 if (webview() && webview()->focusedFrame()) {
1487 // We always obey the cache (ignore_cache=false) here.
1488 // TODO(evanm): perhaps we could allow shift-clicking the menu item to do
1489 // a cache-ignoring reload of the frame.
1490 webview()->focusedFrame()->reload(false);
1491 }
[email protected]1dda4022010-01-28 18:24:561492}
1493
initial.commit09911bf2008-07-26 23:55:291494void RenderView::OnCopyImageAt(int x, int y) {
[email protected]26aa0482009-09-30 16:55:271495 webview()->copyImageAt(WebPoint(x, y));
initial.commit09911bf2008-07-26 23:55:291496}
1497
[email protected]68b1e922009-06-23 16:00:251498void RenderView::OnExecuteEditCommand(const std::string& name,
1499 const std::string& value) {
[email protected]26aa0482009-09-30 16:55:271500 if (!webview() || !webview()->focusedFrame())
[email protected]68b1e922009-06-23 16:00:251501 return;
1502
[email protected]26aa0482009-09-30 16:55:271503 webview()->focusedFrame()->executeCommand(
[email protected]dd7daa82009-08-10 05:46:451504 WebString::fromUTF8(name), WebString::fromUTF8(value));
[email protected]68b1e922009-06-23 16:00:251505}
1506
[email protected]b2abac72009-02-26 12:39:281507void RenderView::OnSetupDevToolsClient() {
[email protected]676126f72011-01-15 00:03:511508 DCHECK(!devtools_client_);
1509 devtools_client_ = new DevToolsClient(this);
[email protected]b2abac72009-02-26 12:39:281510}
1511
initial.commit09911bf2008-07-26 23:55:291512void RenderView::OnUpdateTargetURLAck() {
1513 // Check if there is a targeturl waiting to be sent.
1514 if (target_url_status_ == TARGET_PENDING) {
1515 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_,
1516 pending_target_url_));
1517 }
1518
1519 target_url_status_ = TARGET_NONE;
1520}
1521
1522void RenderView::OnUndo() {
1523 if (!webview())
1524 return;
1525
[email protected]26aa0482009-09-30 16:55:271526 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Undo"));
[email protected]afe3a1672009-11-17 19:04:121527 UserMetricsRecordAction("Undo");
initial.commit09911bf2008-07-26 23:55:291528}
1529
1530void RenderView::OnRedo() {
1531 if (!webview())
1532 return;
1533
[email protected]26aa0482009-09-30 16:55:271534 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Redo"));
[email protected]afe3a1672009-11-17 19:04:121535 UserMetricsRecordAction("Redo");
initial.commit09911bf2008-07-26 23:55:291536}
1537
1538void RenderView::OnCut() {
1539 if (!webview())
1540 return;
1541
[email protected]26aa0482009-09-30 16:55:271542 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Cut"));
[email protected]afe3a1672009-11-17 19:04:121543 UserMetricsRecordAction("Cut");
initial.commit09911bf2008-07-26 23:55:291544}
1545
1546void RenderView::OnCopy() {
1547 if (!webview())
1548 return;
1549
[email protected]26aa0482009-09-30 16:55:271550 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Copy"));
[email protected]afe3a1672009-11-17 19:04:121551 UserMetricsRecordAction("Copy");
initial.commit09911bf2008-07-26 23:55:291552}
1553
[email protected]c0cc3092009-09-12 08:27:271554#if defined(OS_MACOSX)
[email protected]a954bf72009-09-12 07:30:351555void RenderView::OnCopyToFindPboard() {
1556 if (!webview())
1557 return;
1558
1559 // Since the find pasteboard supports only plain text, this can be simpler
1560 // than the |OnCopy()| case.
[email protected]26aa0482009-09-30 16:55:271561 WebFrame* frame = webview()->focusedFrame();
[email protected]a954bf72009-09-12 07:30:351562 if (frame->hasSelection()) {
1563 string16 selection = frame->selectionAsText();
1564 RenderThread::current()->Send(
1565 new ViewHostMsg_ClipboardFindPboardWriteStringAsync(selection));
1566 }
1567
[email protected]afe3a1672009-11-17 19:04:121568 UserMetricsRecordAction("CopyToFindPboard");
[email protected]a954bf72009-09-12 07:30:351569}
[email protected]c0cc3092009-09-12 08:27:271570#endif
[email protected]a954bf72009-09-12 07:30:351571
initial.commit09911bf2008-07-26 23:55:291572void RenderView::OnPaste() {
1573 if (!webview())
1574 return;
1575
[email protected]26aa0482009-09-30 16:55:271576 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Paste"));
[email protected]afe3a1672009-11-17 19:04:121577 UserMetricsRecordAction("Paste");
initial.commit09911bf2008-07-26 23:55:291578}
1579
[email protected]2a3a7762009-10-19 19:17:321580void RenderView::OnReplace(const string16& text) {
initial.commit09911bf2008-07-26 23:55:291581 if (!webview())
1582 return;
1583
[email protected]1ff7a032010-02-03 02:46:031584 WebFrame* frame = webview()->focusedFrame();
1585 if (!frame->hasSelection())
1586 frame->selectWordAroundCaret();
1587 frame->replaceSelection(text);
initial.commit09911bf2008-07-26 23:55:291588}
1589
[email protected]98324892009-09-09 21:16:051590void RenderView::OnAdvanceToNextMisspelling() {
1591 if (!webview())
1592 return;
[email protected]26aa0482009-09-30 16:55:271593 webview()->focusedFrame()->executeCommand(
[email protected]98324892009-09-09 21:16:051594 WebString::fromUTF8("AdvanceToNextMisspelling"));
1595}
1596
1597void RenderView::OnToggleSpellPanel(bool is_currently_visible) {
1598 if (!webview())
1599 return;
1600 // We need to tell the webView whether the spelling panel is visible or not so
1601 // that it won't need to make ipc calls later.
[email protected]8922e1f2009-10-03 05:01:261602 spelling_panel_visible_ = is_currently_visible;
[email protected]26aa0482009-09-30 16:55:271603 webview()->focusedFrame()->executeCommand(
[email protected]98324892009-09-09 21:16:051604 WebString::fromUTF8("ToggleSpellPanel"));
1605}
1606
[email protected]bbbd545c2008-12-15 20:18:041607void RenderView::OnToggleSpellCheck() {
1608 if (!webview())
1609 return;
1610
[email protected]26aa0482009-09-30 16:55:271611 WebFrame* frame = webview()->focusedFrame();
[email protected]dd7daa82009-08-10 05:46:451612 frame->enableContinuousSpellChecking(
1613 !frame->isContinuousSpellCheckingEnabled());
[email protected]bbbd545c2008-12-15 20:18:041614}
1615
initial.commit09911bf2008-07-26 23:55:291616void RenderView::OnDelete() {
1617 if (!webview())
1618 return;
1619
[email protected]26aa0482009-09-30 16:55:271620 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Delete"));
[email protected]afe3a1672009-11-17 19:04:121621 UserMetricsRecordAction("DeleteSelection");
initial.commit09911bf2008-07-26 23:55:291622}
1623
1624void RenderView::OnSelectAll() {
1625 if (!webview())
1626 return;
1627
[email protected]26aa0482009-09-30 16:55:271628 webview()->focusedFrame()->executeCommand(
[email protected]a100d76bb2009-08-14 17:50:221629 WebString::fromUTF8("SelectAll"));
[email protected]afe3a1672009-11-17 19:04:121630 UserMetricsRecordAction("SelectAll");
initial.commit09911bf2008-07-26 23:55:291631}
1632
1633void RenderView::OnSetInitialFocus(bool reverse) {
1634 if (!webview())
1635 return;
[email protected]26aa0482009-09-30 16:55:271636 webview()->setInitialFocus(reverse);
initial.commit09911bf2008-07-26 23:55:291637}
1638
[email protected]9b66f34bf2010-10-27 20:45:511639void RenderView::OnScrollFocusedEditableNodeIntoView() {
[email protected]13a1e4c3c2011-02-03 21:07:091640 WebKit::WebNode node = GetFocusedNode();
1641 if (!node.isNull()) {
1642 if (IsEditableNode(node))
1643 // TODO(varunjain): Change webkit API to scroll a particular node into
1644 // view and use that API here instead.
1645 webview()->scrollFocusedNodeIntoView();
[email protected]9b66f34bf2010-10-27 20:45:511646 }
1647}
1648
initial.commit09911bf2008-07-26 23:55:291649///////////////////////////////////////////////////////////////////////////////
1650
[email protected]433819d2010-01-30 20:20:011651void RenderView::SetContentSettings(const ContentSettings& settings) {
1652 current_content_settings_ = settings;
[email protected]f85f0702010-01-30 09:31:011653}
1654
initial.commit09911bf2008-07-26 23:55:291655// Tell the embedding application that the URL of the active page has changed
1656void RenderView::UpdateURL(WebFrame* frame) {
[email protected]dd7daa82009-08-10 05:46:451657 WebDataSource* ds = frame->dataSource();
initial.commit09911bf2008-07-26 23:55:291658 DCHECK(ds);
1659
[email protected]726985e22009-06-18 21:09:281660 const WebURLRequest& request = ds->request();
1661 const WebURLRequest& original_request = ds->originalRequest();
1662 const WebURLResponse& response = ds->response();
initial.commit09911bf2008-07-26 23:55:291663
[email protected]daa8c58e2009-06-15 17:21:101664 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
1665 DCHECK(navigation_state);
initial.commit09911bf2008-07-26 23:55:291666
1667 ViewHostMsg_FrameNavigate_Params params;
[email protected]726985e22009-06-18 21:09:281668 params.http_status_code = response.httpStatusCode();
initial.commit09911bf2008-07-26 23:55:291669 params.is_post = false;
1670 params.page_id = page_id_;
[email protected]dabb0d12010-10-05 12:50:071671 params.frame_id = frame->identifier();
[email protected]726985e22009-06-18 21:09:281672 params.is_content_filtered = response.isContentFiltered();
[email protected]af15bed2010-08-25 21:12:091673 params.was_within_same_page = navigation_state->was_within_same_page();
[email protected]e6f546c32009-07-01 17:12:551674 if (!navigation_state->security_info().empty()) {
initial.commit09911bf2008-07-26 23:55:291675 // SSL state specified in the request takes precedence over the one in the
1676 // response.
1677 // So far this is only intended for error pages that are not expected to be
1678 // over ssl, so we should not get any clash.
[email protected]726985e22009-06-18 21:09:281679 DCHECK(response.securityInfo().isEmpty());
[email protected]e6f546c32009-07-01 17:12:551680 params.security_info = navigation_state->security_info();
initial.commit09911bf2008-07-26 23:55:291681 } else {
[email protected]726985e22009-06-18 21:09:281682 params.security_info = response.securityInfo();
initial.commit09911bf2008-07-26 23:55:291683 }
1684
1685 // Set the URL to be displayed in the browser UI to the user.
[email protected]726985e22009-06-18 21:09:281686 if (ds->hasUnreachableURL()) {
1687 params.url = ds->unreachableURL();
initial.commit09911bf2008-07-26 23:55:291688 } else {
[email protected]726985e22009-06-18 21:09:281689 params.url = request.url();
initial.commit09911bf2008-07-26 23:55:291690 }
1691
[email protected]726985e22009-06-18 21:09:281692 GetRedirectChain(ds, &params.redirects);
[email protected]d94dc1e2010-03-04 09:29:241693 params.should_update_history = !ds->hasUnreachableURL() &&
1694 !response.isMultipartPayload();
initial.commit09911bf2008-07-26 23:55:291695
[email protected]ce0e250d2009-10-23 21:00:351696 params.searchable_form_url = navigation_state->searchable_form_url();
1697 params.searchable_form_encoding =
1698 navigation_state->searchable_form_encoding();
initial.commit09911bf2008-07-26 23:55:291699
1700 const PasswordForm* password_form_data =
[email protected]daa8c58e2009-06-15 17:21:101701 navigation_state->password_form_data();
initial.commit09911bf2008-07-26 23:55:291702 if (password_form_data)
1703 params.password_form = *password_form_data;
1704
1705 params.gesture = navigation_gesture_;
1706 navigation_gesture_ = NavigationGestureUnknown;
1707
[email protected]dd7daa82009-08-10 05:46:451708 if (!frame->parent()) {
initial.commit09911bf2008-07-26 23:55:291709 // Top-level navigation.
1710
[email protected]71b0d5d2010-02-15 05:43:071711 // Clear "block" flags for the new page. This needs to happen before any of
1712 // allowScripts(), allowImages(), allowPlugins() is called for the new page
1713 // so that these functions can correctly detect that a piece of content
1714 // flipped from "not blocked" to "blocked".
1715 ClearBlockedContentSettings();
1716
[email protected]62d2a112010-04-07 00:53:021717 // Set content settings. Default them from the parent window if one exists.
1718 // This makes sure about:blank windows work as expected.
[email protected]f85f0702010-01-30 09:31:011719 HostContentSettings::iterator host_content_settings =
[email protected]9d797f32010-04-23 07:17:541720 host_content_settings_.find(GURL(request.url()));
[email protected]f85f0702010-01-30 09:31:011721 if (host_content_settings != host_content_settings_.end()) {
[email protected]433819d2010-01-30 20:20:011722 SetContentSettings(host_content_settings->second);
[email protected]f85f0702010-01-30 09:31:011723
1724 // These content settings were merely recorded transiently for this load.
1725 // We can erase them now. If at some point we reload this page, the
1726 // browser will send us new, up-to-date content settings.
1727 host_content_settings_.erase(host_content_settings);
[email protected]3a387ae2010-04-08 01:58:401728 } else if (frame->opener()) {
[email protected]8128cdd02010-07-21 20:40:101729 // The opener's view is not guaranteed to be non-null (it could be
1730 // detached from its page but not yet destructed).
1731 if (WebView* opener_view = frame->opener()->view()) {
1732 RenderView* opener = FromWebView(opener_view);
1733 SetContentSettings(opener->current_content_settings_);
1734 }
[email protected]f85f0702010-01-30 09:31:011735 }
1736
[email protected]b75b8292010-10-01 07:28:251737 // Set zoom level, but don't do it for full-page plugin since they don't use
1738 // the same zoom settings.
[email protected]f85f0702010-01-30 09:31:011739 HostZoomLevels::iterator host_zoom =
[email protected]9d797f32010-04-23 07:17:541740 host_zoom_levels_.find(GURL(request.url()));
[email protected]b75b8292010-10-01 07:28:251741 if (webview()->mainFrame()->document().isPluginDocument()) {
1742 // Reset the zoom levels for plugins.
[email protected]b75b8292010-10-01 07:28:251743 webview()->setZoomLevel(false, 0);
[email protected]b75b8292010-10-01 07:28:251744 } else {
1745 if (host_zoom != host_zoom_levels_.end())
[email protected]b75b8292010-10-01 07:28:251746 webview()->setZoomLevel(false, host_zoom->second);
[email protected]b75b8292010-10-01 07:28:251747 }
1748
[email protected]f85f0702010-01-30 09:31:011749 if (host_zoom != host_zoom_levels_.end()) {
[email protected]40bd6582009-12-04 23:49:511750 // This zoom level was merely recorded transiently for this load. We can
1751 // erase it now. If at some point we reload this page, the browser will
1752 // send us a new, up-to-date zoom level.
[email protected]f85f0702010-01-30 09:31:011753 host_zoom_levels_.erase(host_zoom);
[email protected]40bd6582009-12-04 23:49:511754 }
1755
[email protected]b75b8292010-10-01 07:28:251756 // Reset the zoom limits in case a plugin had changed them previously. This
1757 // will also call us back which will cause us to send a message to
1758 // update TabContents.
[email protected]b75b8292010-10-01 07:28:251759 webview()->zoomLimitsChanged(
1760 WebView::zoomFactorToZoomLevel(WebView::minTextSizeMultiplier),
1761 WebView::zoomFactorToZoomLevel(WebView::maxTextSizeMultiplier));
[email protected]b75b8292010-10-01 07:28:251762
initial.commit09911bf2008-07-26 23:55:291763 // Update contents MIME type for main frame.
[email protected]9c5645b2009-08-11 03:37:551764 params.contents_mime_type = ds->response().mimeType().utf8();
initial.commit09911bf2008-07-26 23:55:291765
[email protected]daa8c58e2009-06-15 17:21:101766 params.transition = navigation_state->transition_type();
initial.commit09911bf2008-07-26 23:55:291767 if (!PageTransition::IsMainFrame(params.transition)) {
1768 // If the main frame does a load, it should not be reported as a subframe
1769 // navigation. This can occur in the following case:
1770 // 1. You're on a site with frames.
1771 // 2. You do a subframe navigation. This is stored with transition type
1772 // MANUAL_SUBFRAME.
1773 // 3. You navigate to some non-frame site, say, google.com.
1774 // 4. You navigate back to the page from step 2. Since it was initially
1775 // MANUAL_SUBFRAME, it will be that same transition type here.
1776 // We don't want that, because any navigation that changes the toplevel
1777 // frame should be tracked as a toplevel navigation (this allows us to
1778 // update the URL bar, etc).
1779 params.transition = PageTransition::LINK;
1780 }
1781
initial.commit09911bf2008-07-26 23:55:291782 // If we have a valid consumed client redirect source,
1783 // the page contained a client redirect (meta refresh, document.loc...),
1784 // so we set the referrer and transition to match.
1785 if (completed_client_redirect_src_.is_valid()) {
[email protected]77e09a92008-08-01 18:11:041786 DCHECK(completed_client_redirect_src_ == params.redirects[0]);
initial.commit09911bf2008-07-26 23:55:291787 params.referrer = completed_client_redirect_src_;
1788 params.transition = static_cast<PageTransition::Type>(
1789 params.transition | PageTransition::CLIENT_REDIRECT);
1790 } else {
1791 // Bug 654101: the referrer will be empty on https->http transitions. It
1792 // would be nice if we could get the real referrer from somewhere.
[email protected]726985e22009-06-18 21:09:281793 params.referrer = GURL(
1794 original_request.httpHeaderField(WebString::fromUTF8("Referer")));
initial.commit09911bf2008-07-26 23:55:291795 }
1796
[email protected]726985e22009-06-18 21:09:281797 string16 method = request.httpMethod();
1798 if (EqualsASCII(method, "POST"))
initial.commit09911bf2008-07-26 23:55:291799 params.is_post = true;
1800
[email protected]c2a797d2009-09-21 16:46:321801 // Save some histogram data so we can compute the average memory used per
1802 // page load of the glyphs.
1803 UMA_HISTOGRAM_COUNTS_10000("Memory.GlyphPagesPerLoad",
1804 webkit_glue::GetGlyphPageCount());
1805
[email protected]15cf526b2010-02-12 06:33:491806 // This message needs to be sent before any of allowScripts(),
1807 // allowImages(), allowPlugins() is called for the new page, so that when
1808 // these functions send a ViewHostMsg_ContentBlocked message, it arrives
1809 // after the ViewHostMsg_FrameNavigate message.
initial.commit09911bf2008-07-26 23:55:291810 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
1811 } else {
1812 // Subframe navigation: the type depends on whether this navigation
1813 // generated a new session history entry. When they do generate a session
1814 // history entry, it means the user initiated the navigation and we should
1815 // mark it as such. This test checks if this is the first time UpdateURL
1816 // has been called since WillNavigateToURL was called to initiate the load.
1817 if (page_id_ > last_page_id_sent_to_browser_)
1818 params.transition = PageTransition::MANUAL_SUBFRAME;
1819 else
1820 params.transition = PageTransition::AUTO_SUBFRAME;
1821
initial.commit09911bf2008-07-26 23:55:291822 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
1823 }
1824
1825 last_page_id_sent_to_browser_ =
1826 std::max(last_page_id_sent_to_browser_, page_id_);
1827
1828 // If we end up reusing this WebRequest (for example, due to a #ref click),
[email protected]daa8c58e2009-06-15 17:21:101829 // we don't want the transition type to persist. Just clear it.
1830 navigation_state->set_transition_type(PageTransition::LINK);
[email protected]266eb6f2008-09-30 23:56:501831
[email protected]af15bed2010-08-25 21:12:091832 // Check if the navigation was within the same page, in which case we don't
1833 // want to clear the accessibility cache.
1834 if (accessibility_.get() && !navigation_state->was_within_same_page()) {
[email protected]17455962010-02-24 01:39:351835 accessibility_.reset();
[email protected]dea2d372010-09-25 06:41:141836 pending_accessibility_notifications_.clear();
[email protected]266eb6f2008-09-30 23:56:501837 }
initial.commit09911bf2008-07-26 23:55:291838}
1839
1840// Tell the embedding application that the title of the active page has changed
[email protected]3d9689372009-09-10 04:29:171841void RenderView::UpdateTitle(WebFrame* frame, const string16& title) {
initial.commit09911bf2008-07-26 23:55:291842 // Ignore all but top level navigations...
[email protected]3d9689372009-09-10 04:29:171843 if (!frame->parent()) {
[email protected]f0af6a72009-05-30 05:25:171844 Send(new ViewHostMsg_UpdateTitle(
[email protected]3d9689372009-09-10 04:29:171845 routing_id_,
1846 page_id_,
1847 UTF16ToWideHack(title.length() > chrome::kMaxTitleChars ?
1848 title.substr(0, chrome::kMaxTitleChars) : title)));
[email protected]f0af6a72009-05-30 05:25:171849 }
initial.commit09911bf2008-07-26 23:55:291850}
1851
1852void RenderView::UpdateEncoding(WebFrame* frame,
[email protected]41fc0322009-09-04 22:23:401853 const std::string& encoding_name) {
initial.commit09911bf2008-07-26 23:55:291854 // Only update main frame's encoding_name.
[email protected]26aa0482009-09-30 16:55:271855 if (webview()->mainFrame() == frame &&
initial.commit09911bf2008-07-26 23:55:291856 last_encoding_name_ != encoding_name) {
[email protected]e38f40152008-09-12 23:08:301857 // Save the encoding name for later comparing.
initial.commit09911bf2008-07-26 23:55:291858 last_encoding_name_ = encoding_name;
1859
[email protected]e38f40152008-09-12 23:08:301860 Send(new ViewHostMsg_UpdateEncoding(routing_id_, last_encoding_name_));
initial.commit09911bf2008-07-26 23:55:291861 }
1862}
1863
[email protected]e15f680732010-11-23 22:30:201864// Sends the last committed session history state to the browser so it will be
1865// saved before we navigate to a new page. This must be called *before* the
1866// page ID has been updated so we know what it was.
initial.commit09911bf2008-07-26 23:55:291867void RenderView::UpdateSessionHistory(WebFrame* frame) {
1868 // If we have a valid page ID at this point, then it corresponds to the page
1869 // we are navigating away from. Otherwise, this is the first navigation, so
1870 // there is no past session history to record.
1871 if (page_id_ == -1)
1872 return;
1873
[email protected]ca948a22009-06-25 19:36:171874 const WebHistoryItem& item =
[email protected]26aa0482009-09-30 16:55:271875 webview()->mainFrame()->previousHistoryItem();
[email protected]ca948a22009-06-25 19:36:171876 if (item.isNull())
initial.commit09911bf2008-07-26 23:55:291877 return;
[email protected]ca948a22009-06-25 19:36:171878
1879 Send(new ViewHostMsg_UpdateState(
1880 routing_id_, page_id_, webkit_glue::HistoryItemToString(item)));
initial.commit09911bf2008-07-26 23:55:291881}
1882
[email protected]3d9689372009-09-10 04:29:171883void RenderView::OpenURL(
1884 const GURL& url, const GURL& referrer, WebNavigationPolicy policy) {
1885 Send(new ViewHostMsg_OpenURL(
1886 routing_id_, url, referrer, NavigationPolicyToDisposition(policy)));
1887}
1888
[email protected]79dbc662009-09-04 05:42:511889// WebViewDelegate ------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291890
initial.commit09911bf2008-07-26 23:55:291891void RenderView::LoadNavigationErrorPage(WebFrame* frame,
[email protected]726985e22009-06-18 21:09:281892 const WebURLRequest& failed_request,
1893 const WebURLError& error,
initial.commit09911bf2008-07-26 23:55:291894 const std::string& html,
1895 bool replace) {
[email protected]726985e22009-06-18 21:09:281896 GURL failed_url = error.unreachableURL;
initial.commit09911bf2008-07-26 23:55:291897 std::string alt_html;
[email protected]2a521c52011-01-26 18:45:211898 const Extension* extension = NULL;
initial.commit09911bf2008-07-26 23:55:291899 if (html.empty()) {
1900 // Use a local error page.
1901 int resource_id;
1902 DictionaryValue error_strings;
[email protected]5351dbc2010-08-27 15:22:111903
[email protected]81654282010-10-04 17:08:061904 if (failed_url.is_valid() && !failed_url.SchemeIs(chrome::kExtensionScheme))
[email protected]2a521c52011-01-26 18:45:211905 extension = render_thread_->GetExtensions()->GetByURL(failed_url);
[email protected]5351dbc2010-08-27 15:22:111906 if (extension) {
[email protected]3f853a52010-09-13 19:15:081907 LocalizedError::GetAppErrorStrings(error, failed_url, extension,
1908 &error_strings);
[email protected]5351dbc2010-08-27 15:22:111909
1910 // TODO(erikkay): Should we use a different template for different
1911 // error messages?
1912 resource_id = IDR_ERROR_APP_HTML;
initial.commit09911bf2008-07-26 23:55:291913 } else {
[email protected]3f853a52010-09-13 19:15:081914 if (error.domain == WebString::fromUTF8(net::kErrorDomain) &&
1915 error.reason == net::ERR_CACHE_MISS &&
[email protected]5351dbc2010-08-27 15:22:111916 EqualsASCII(failed_request.httpMethod(), "POST")) {
[email protected]3f853a52010-09-13 19:15:081917 LocalizedError::GetFormRepostStrings(failed_url, &error_strings);
[email protected]5351dbc2010-08-27 15:22:111918 } else {
[email protected]3f853a52010-09-13 19:15:081919 LocalizedError::GetStrings(error, &error_strings);
[email protected]5351dbc2010-08-27 15:22:111920 }
[email protected]75891fe2010-11-20 15:55:181921 resource_id = IDR_NET_ERROR_HTML;
initial.commit09911bf2008-07-26 23:55:291922 }
initial.commit09911bf2008-07-26 23:55:291923
1924 alt_html = GetAltHTMLForTemplate(error_strings, resource_id);
1925 } else {
1926 alt_html = html;
1927 }
1928
[email protected]dd7daa82009-08-10 05:46:451929 frame->loadHTMLString(alt_html,
[email protected]144143c2010-10-28 08:17:361930 GURL(chrome::kUnreachableWebDataURL),
[email protected]e6f546c32009-07-01 17:12:551931 failed_url,
1932 replace);
initial.commit09911bf2008-07-26 23:55:291933}
1934
[email protected]7ccddb8c2009-08-04 17:36:551935void RenderView::BindDOMAutomationController(WebFrame* frame) {
[email protected]2f979172010-09-16 21:54:031936 if (!dom_automation_controller_.get()) {
1937 dom_automation_controller_.reset(new DomAutomationController());
1938 }
1939 dom_automation_controller_->set_message_sender(this);
1940 dom_automation_controller_->set_routing_id(routing_id_);
1941 dom_automation_controller_->BindToJavascript(frame,
[email protected]906690b2010-12-03 18:11:251942 "domAutomationController");
initial.commit09911bf2008-07-26 23:55:291943}
1944
initial.commit09911bf2008-07-26 23:55:291945bool RenderView::RunJavaScriptMessage(int type,
1946 const std::wstring& message,
1947 const std::wstring& default_value,
[email protected]a455d3812009-03-05 20:18:071948 const GURL& frame_url,
initial.commit09911bf2008-07-26 23:55:291949 std::wstring* result) {
1950 bool success = false;
1951 std::wstring result_temp;
1952 if (!result)
1953 result = &result_temp;
initial.commit09911bf2008-07-26 23:55:291954
[email protected]12636df2009-09-28 22:32:211955 SendAndRunNestedMessageLoop(new ViewHostMsg_RunJavaScriptMessage(
1956 routing_id_, message, default_value, frame_url, type, &success, result));
initial.commit09911bf2008-07-26 23:55:291957 return success;
1958}
1959
[email protected]c1f50aa2010-02-18 03:46:571960bool RenderView::SendAndRunNestedMessageLoop(IPC::SyncMessage* message) {
1961 // Before WebKit asks us to show an alert (etc.), it takes care of doing the
1962 // equivalent of WebView::willEnterModalLoop. In the case of showModalDialog
1963 // it is particularly important that we do not call willEnterModalLoop as
1964 // that would defer resource loads for the dialog itself.
1965 if (RenderThread::current()) // Will be NULL during unit tests.
1966 RenderThread::current()->DoNotNotifyWebKitOfModalLoop();
1967
1968 message->EnableMessagePumping(); // Runs a nested message loop.
1969 return Send(message);
1970}
1971
[email protected]2de7e002010-10-11 22:58:201972void RenderView::AddGURLSearchProvider(
1973 const GURL& osd_url,
1974 const ViewHostMsg_PageHasOSDD_Type& provider_type) {
initial.commit09911bf2008-07-26 23:55:291975 if (!osd_url.is_empty())
1976 Send(new ViewHostMsg_PageHasOSDD(routing_id_, page_id_, osd_url,
[email protected]2de7e002010-10-11 22:58:201977 provider_type));
initial.commit09911bf2008-07-26 23:55:291978}
1979
[email protected]e8345242010-05-06 03:00:401980void RenderView::OnAllowScriptToClose(bool script_can_close) {
1981 script_can_close_ = script_can_close;
[email protected]634a6f92008-12-01 21:39:311982}
1983
initial.commit09911bf2008-07-26 23:55:291984uint32 RenderView::GetCPBrowsingContext() {
1985 uint32 context = 0;
1986 Send(new ViewHostMsg_GetCPBrowsingContext(&context));
1987 return context;
1988}
1989
[email protected]2de7e002010-10-11 22:58:201990void RenderView::AddSearchProvider(
1991 const std::string& url,
1992 const ViewHostMsg_PageHasOSDD_Type& provider_type) {
1993 if (provider_type.type ==
1994 ViewHostMsg_PageHasOSDD_Type::EXPLICIT_DEFAULT_PROVIDER &&
1995 !webview()->mainFrame()->isProcessingUserGesture())
1996 return;
1997
1998 AddGURLSearchProvider(GURL(url), provider_type);
initial.commit09911bf2008-07-26 23:55:291999}
2000
[email protected]155f35e2010-07-17 00:30:182001ViewHostMsg_GetSearchProviderInstallState_Params
[email protected]52ded452010-08-23 22:01:252002RenderView::GetSearchProviderInstallState(WebFrame* frame,
2003 const std::string& url) {
[email protected]155f35e2010-07-17 00:30:182004 GURL inquiry_url = GURL(url);
2005 if (inquiry_url.is_empty())
2006 return ViewHostMsg_GetSearchProviderInstallState_Params::Denied();
[email protected]52ded452010-08-23 22:01:252007
[email protected]155f35e2010-07-17 00:30:182008 ViewHostMsg_GetSearchProviderInstallState_Params install;
2009 Send(new ViewHostMsg_GetSearchProviderInstallState(routing_id_,
[email protected]52ded452010-08-23 22:01:252010 frame->url(),
[email protected]155f35e2010-07-17 00:30:182011 inquiry_url,
2012 &install));
2013 return install;
2014}
2015
[email protected]f103ab72009-09-02 17:10:592016void RenderView::OnMissingPluginStatus(
2017 WebPluginDelegateProxy* delegate,
2018 int status) {
[email protected]6c8afae52009-01-22 02:24:572019#if defined(OS_WIN)
[email protected]f103ab72009-09-02 17:10:592020 if (!first_default_plugin_) {
initial.commit09911bf2008-07-26 23:55:292021 // Show the InfoBar for the first available plugin.
[email protected]191eb3f72010-12-21 06:27:502022 if (status == webkit::npapi::default_plugin::MISSING_PLUGIN_AVAILABLE) {
[email protected]f103ab72009-09-02 17:10:592023 first_default_plugin_ = delegate->AsWeakPtr();
initial.commit09911bf2008-07-26 23:55:292024 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
2025 }
2026 } else {
2027 // Closes the InfoBar if user clicks on the plugin (instead of the InfoBar)
2028 // to start the download/install.
[email protected]191eb3f72010-12-21 06:27:502029 if (status ==
2030 webkit::npapi::default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD) {
initial.commit09911bf2008-07-26 23:55:292031 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
2032 }
2033 }
[email protected]6c8afae52009-01-22 02:24:572034#else
[email protected]76c3b312010-05-20 21:38:292035 // TODO(port): Implement the infobar that accompanies the default plugin.
2036 // Linux: http://crbug.com/10952
2037 // Mac: http://crbug.com/17392
[email protected]6c8afae52009-01-22 02:24:572038 NOTIMPLEMENTED();
2039#endif
initial.commit09911bf2008-07-26 23:55:292040}
2041
[email protected]48c9cf2d2009-09-16 16:47:522042// WebKit::WebViewClient ------------------------------------------------------
2043
[email protected]844acf372011-01-14 10:49:272044WebView* RenderView::createView(
2045 WebFrame* creator,
2046 const WebURLRequest& request,
2047 const WebWindowFeatures& features,
2048 const WebString& frame_name) {
[email protected]48c9cf2d2009-09-16 16:47:522049 // Check to make sure we aren't overloading on popups.
2050 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups)
2051 return NULL;
2052
2053 // This window can't be closed from a window.close() call until we receive a
2054 // message from the Browser process explicitly allowing it.
[email protected]e8345242010-05-06 03:00:402055 script_can_close_ = false;
[email protected]48c9cf2d2009-09-16 16:47:522056
[email protected]8ab04652010-06-12 02:47:262057 ViewHostMsg_CreateWindow_Params params;
2058 params.opener_id = routing_id_;
2059 params.user_gesture = creator->isProcessingUserGesture();
2060 params.window_container_type = WindowFeaturesToContainerType(features);
2061 params.session_storage_namespace_id = session_storage_namespace_id_;
2062 params.frame_name = frame_name;
[email protected]41e65502011-01-21 09:29:112063 params.opener_frame_id = creator->identifier();
2064 params.opener_url = creator->url();
2065 params.opener_security_origin = creator->securityOrigin().toString().utf8();
2066 if (!request.isNull())
2067 params.target_url = request.url();
[email protected]8ab04652010-06-12 02:47:262068
[email protected]48c9cf2d2009-09-16 16:47:522069 int32 routing_id = MSG_ROUTING_NONE;
[email protected]4e6419c2010-01-15 04:50:342070 int64 cloned_session_storage_namespace_id;
[email protected]8ab04652010-06-12 02:47:262071 bool opener_suppressed = creator->willSuppressOpenerInNewFrame();
[email protected]48c9cf2d2009-09-16 16:47:522072
[email protected]48c9cf2d2009-09-16 16:47:522073 render_thread_->Send(
[email protected]8ab04652010-06-12 02:47:262074 new ViewHostMsg_CreateWindow(params,
2075 &routing_id,
2076 &cloned_session_storage_namespace_id));
[email protected]12636df2009-09-28 22:32:212077 if (routing_id == MSG_ROUTING_NONE)
[email protected]48c9cf2d2009-09-16 16:47:522078 return NULL;
[email protected]48c9cf2d2009-09-16 16:47:522079
[email protected]48c9cf2d2009-09-16 16:47:522080 RenderView* view = RenderView::Create(render_thread_,
[email protected]659f73fa2009-10-13 13:43:422081 0,
[email protected]12636df2009-09-28 22:32:212082 routing_id_,
[email protected]48c9cf2d2009-09-16 16:47:522083 renderer_preferences_,
2084 webkit_preferences_,
[email protected]12636df2009-09-28 22:32:212085 shared_popup_counter_,
[email protected]4e6419c2010-01-15 04:50:342086 routing_id,
[email protected]8ab04652010-06-12 02:47:262087 cloned_session_storage_namespace_id,
2088 frame_name);
2089 view->opened_by_user_gesture_ = params.user_gesture;
[email protected]48c9cf2d2009-09-16 16:47:522090
[email protected]007a848b2009-10-26 15:55:462091 // Record whether the creator frame is trying to suppress the opener field.
2092 view->opener_suppressed_ = opener_suppressed;
2093
[email protected]48c9cf2d2009-09-16 16:47:522094 // Record the security origin of the creator.
[email protected]91733b62009-09-18 06:21:092095 GURL creator_url(creator->securityOrigin().toString().utf8());
[email protected]48c9cf2d2009-09-16 16:47:522096 if (!creator_url.is_valid() || !creator_url.IsStandard())
2097 creator_url = GURL();
2098 view->creator_url_ = creator_url;
2099
2100 // Copy over the alternate error page URL so we can have alt error pages in
2101 // the new render view (we don't need the browser to send the URL back down).
2102 view->alternate_error_page_url_ = alternate_error_page_url_;
2103
2104 return view->webview();
2105}
2106
[email protected]3e2b375b2010-04-07 17:03:122107WebWidget* RenderView::createPopupMenu(WebKit::WebPopupType popup_type) {
[email protected]48c9cf2d2009-09-16 16:47:522108 RenderWidget* widget = RenderWidget::Create(routing_id_,
2109 render_thread_,
[email protected]3e2b375b2010-04-07 17:03:122110 popup_type);
[email protected]48c9cf2d2009-09-16 16:47:522111 return widget->webwidget();
2112}
2113
2114WebWidget* RenderView::createPopupMenu(const WebPopupMenuInfo& info) {
[email protected]8de12d942010-11-17 20:42:442115 // TODO(jcivelli): Remove this deprecated method when its been removed from
2116 // the WebViewClient interface. It's been replaced by
2117 // createExternalPopupMenu.
2118 NOTREACHED();
2119 return NULL;
[email protected]48c9cf2d2009-09-16 16:47:522120}
2121
[email protected]caf706f2010-10-26 17:54:082122WebExternalPopupMenu* RenderView::createExternalPopupMenu(
2123 const WebPopupMenuInfo& popup_menu_info,
2124 WebExternalPopupMenuClient* popup_menu_client) {
2125 DCHECK(!external_popup_menu_.get());
2126 external_popup_menu_.reset(
2127 new ExternalPopupMenu(this, popup_menu_info, popup_menu_client));
2128 return external_popup_menu_.get();
2129}
2130
[email protected]484955942010-08-19 16:13:182131WebWidget* RenderView::createFullscreenWindow(WebKit::WebPopupType popup_type) {
2132 RenderWidget* widget = RenderWidgetFullscreen::Create(routing_id_,
2133 render_thread_,
2134 popup_type);
2135 return widget->webwidget();
2136}
2137
[email protected]0bd753682010-12-16 18:15:522138webkit::ppapi::FullscreenContainer*
2139RenderView::CreatePepperFullscreenContainer(
2140 webkit::ppapi::PluginInstance* plugin) {
[email protected]79c7bed2010-09-14 22:28:392141 RenderWidgetFullscreenPepper* widget =
2142 RenderWidgetFullscreenPepper::Create(routing_id_, render_thread_, plugin);
2143 widget->show(WebKit::WebNavigationPolicyIgnore);
[email protected]92abcb832011-01-06 20:39:562144 return widget;
[email protected]79c7bed2010-09-14 22:28:392145}
2146
[email protected]68c50e52010-05-12 11:14:392147WebStorageNamespace* RenderView::createSessionStorageNamespace(unsigned quota) {
[email protected]bd92c3a2010-01-13 05:02:342148 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess))
[email protected]68c50e52010-05-12 11:14:392149 return WebStorageNamespace::createSessionStorageNamespace(quota);
[email protected]59afea12010-01-20 04:48:292150 CHECK(session_storage_namespace_id_ != kInvalidSessionStorageNamespaceId);
2151 return new RendererWebStorageNamespaceImpl(DOM_STORAGE_SESSION,
2152 session_storage_namespace_id_);
[email protected]bd92c3a2010-01-13 05:02:342153}
2154
[email protected]48c9cf2d2009-09-16 16:47:522155void RenderView::didAddMessageToConsole(
2156 const WebConsoleMessage& message, const WebString& source_name,
2157 unsigned source_line) {
2158 Send(new ViewHostMsg_AddMessageToConsole(routing_id_,
2159 UTF16ToWideHack(message.text),
2160 static_cast<int32>(source_line),
2161 UTF16ToWideHack(source_name)));
2162}
2163
2164void RenderView::printPage(WebFrame* frame) {
[email protected]71a14262009-09-22 20:02:582165 DCHECK(frame);
[email protected]212a49d2010-10-25 18:23:472166 if (CommandLine::ForCurrentProcess()->HasSwitch(
2167 switches::kEnablePrintPreview)) {
2168 Print(frame, true, true);
2169 } else {
2170 Print(frame, true, false);
2171 }
[email protected]48c9cf2d2009-09-16 16:47:522172}
2173
[email protected]3354d3e2010-06-10 19:53:022174WebKit::WebNotificationPresenter* RenderView::notificationPresenter() {
[email protected]676126f72011-01-15 00:03:512175 return notification_provider_;
[email protected]3354d3e2010-06-10 19:53:022176}
2177
[email protected]48c9cf2d2009-09-16 16:47:522178void RenderView::didStartLoading() {
2179 if (is_loading_) {
2180 DLOG(WARNING) << "didStartLoading called while loading";
2181 return;
2182 }
2183
2184 is_loading_ = true;
2185 // Clear the pointer so that we can assign it only when there is an unknown
2186 // plugin on a page.
2187 first_default_plugin_.reset();
2188
2189 Send(new ViewHostMsg_DidStartLoading(routing_id_));
2190}
2191
2192void RenderView::didStopLoading() {
2193 if (!is_loading_) {
2194 DLOG(WARNING) << "DidStopLoading called while not loading";
2195 return;
2196 }
2197
2198 is_loading_ = false;
2199
2200 // NOTE: For now we're doing the safest thing, and sending out notification
2201 // when done loading. This currently isn't an issue as the favicon is only
2202 // displayed when done loading. Ideally we would send notification when
2203 // finished parsing the head, but webkit doesn't support that yet.
2204 // The feed discovery code would also benefit from access to the head.
[email protected]26aa0482009-09-30 16:55:272205 GURL favicon_url(webview()->mainFrame()->favIconURL());
[email protected]48c9cf2d2009-09-16 16:47:522206 if (!favicon_url.is_empty())
2207 Send(new ViewHostMsg_UpdateFavIconURL(routing_id_, page_id_, favicon_url));
2208
[email protected]26aa0482009-09-30 16:55:272209 AddGURLSearchProvider(webview()->mainFrame()->openSearchDescriptionURL(),
[email protected]2de7e002010-10-11 22:58:202210 ViewHostMsg_PageHasOSDD_Type::Autodetected());
[email protected]48c9cf2d2009-09-16 16:47:522211
2212 Send(new ViewHostMsg_DidStopLoading(routing_id_));
2213
[email protected]90109412010-12-15 17:14:242214 if (load_progress_tracker_ != NULL)
2215 load_progress_tracker_->DidStopLoading();
2216
[email protected]f9f4841b2010-03-20 05:41:422217 MessageLoop::current()->PostDelayedTask(
2218 FROM_HERE,
[email protected]e47aec52010-08-12 00:50:302219 page_info_method_factory_.NewRunnableMethod(
2220 &RenderView::CapturePageInfo, page_id_, false),
[email protected]5ddfd63e2010-09-01 15:48:372221 send_content_state_immediately_ ? 0 : kDelayForCaptureMs);
[email protected]48c9cf2d2009-09-16 16:47:522222}
2223
[email protected]90109412010-12-15 17:14:242224void RenderView::didChangeLoadProgress(WebFrame* frame, double load_progress) {
2225 if (load_progress_tracker_ != NULL)
2226 load_progress_tracker_->DidChangeLoadProgress(frame, load_progress);
2227}
2228
[email protected]f55039a2010-02-17 14:12:062229bool RenderView::isSmartInsertDeleteEnabled() {
2230#if defined(OS_MACOSX)
2231 return true;
2232#else
2233 return false;
2234#endif
2235}
2236
[email protected]04fc9482009-09-18 22:13:032237bool RenderView::isSelectTrailingWhitespaceEnabled() {
2238#if defined(OS_WIN)
2239 return true;
2240#else
2241 return false;
2242#endif
2243}
2244
[email protected]04fc9482009-09-18 22:13:032245void RenderView::didChangeSelection(bool is_empty_selection) {
[email protected]0ff0ff32010-12-21 19:34:422246#if defined(OS_POSIX)
[email protected]04fc9482009-09-18 22:13:032247 if (!handling_input_event_)
2248 return;
2249 // TODO(estade): investigate incremental updates to the selection so that we
2250 // don't send the entire selection over IPC every time.
2251 if (!is_empty_selection) {
2252 // Sometimes we get repeated didChangeSelection calls from webkit when
2253 // the selection hasn't actually changed. We don't want to report these
2254 // because it will cause us to continually claim the X clipboard.
2255 const std::string& this_selection =
[email protected]26aa0482009-09-30 16:55:272256 webview()->focusedFrame()->selectionAsText().utf8();
[email protected]04fc9482009-09-18 22:13:032257 if (this_selection == last_selection_)
2258 return;
2259
2260 Send(new ViewHostMsg_SelectionChanged(routing_id_,
2261 this_selection));
2262 last_selection_ = this_selection;
2263 } else {
2264 last_selection_.clear();
[email protected]eef99c22010-08-17 05:55:162265 Send(new ViewHostMsg_SelectionChanged(routing_id_,
2266 last_selection_));
[email protected]04fc9482009-09-18 22:13:032267 }
[email protected]0ff0ff32010-12-21 19:34:422268#endif // defined(OS_POSIX)
[email protected]04fc9482009-09-18 22:13:032269}
2270
2271void RenderView::didExecuteCommand(const WebString& command_name) {
[email protected]afe3a1672009-11-17 19:04:122272 const std::string& name = UTF16ToUTF8(command_name);
2273 if (StartsWithASCII(name, "Move", true) ||
2274 StartsWithASCII(name, "Insert", true) ||
2275 StartsWithASCII(name, "Delete", true))
[email protected]04fc9482009-09-18 22:13:032276 return;
2277 UserMetricsRecordAction(name);
2278}
2279
[email protected]54ec7f82010-10-21 22:32:512280void RenderView::SendPendingAccessibilityNotifications() {
2281 if (!accessibility_.get())
2282 return;
2283
2284 if (pending_accessibility_notifications_.empty())
2285 return;
2286
2287 // Send all pending accessibility notifications.
2288 std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications;
2289 for (size_t i = 0; i < pending_accessibility_notifications_.size(); i++) {
2290 RendererAccessibilityNotification& notification =
2291 pending_accessibility_notifications_[i];
2292 WebAccessibilityObject obj = accessibility_->getObjectById(notification.id);
2293 if (!obj.isValid())
2294 continue;
2295
2296 ViewHostMsg_AccessibilityNotification_Params param;
2297 param.notification_type = pending_accessibility_notifications_[i].type;
[email protected]70eee342010-11-05 01:59:372298 param.acc_obj = WebAccessibility(
2299 obj, accessibility_.get(), notification.ShouldIncludeChildren());
[email protected]54ec7f82010-10-21 22:32:512300 notifications.push_back(param);
2301 }
2302 pending_accessibility_notifications_.clear();
2303 Send(new ViewHostMsg_AccessibilityNotifications(routing_id_, notifications));
2304 accessibility_ack_pending_ = true;
2305}
2306
[email protected]b2528b72009-09-24 06:57:102307bool RenderView::handleCurrentKeyboardEvent() {
2308 if (edit_commands_.empty())
2309 return false;
2310
[email protected]26aa0482009-09-30 16:55:272311 WebFrame* frame = webview()->focusedFrame();
[email protected]b2528b72009-09-24 06:57:102312 if (!frame)
2313 return false;
2314
2315 EditCommands::iterator it = edit_commands_.begin();
2316 EditCommands::iterator end = edit_commands_.end();
2317
[email protected]507b33ea2009-09-29 03:56:512318 bool did_execute_command = false;
[email protected]b2528b72009-09-24 06:57:102319 for (; it != end; ++it) {
[email protected]e6e15012009-09-30 14:59:332320 // In gtk and cocoa, it's possible to bind multiple edit commands to one
2321 // key (but it's the exception). Once one edit command is not executed, it
2322 // seems safest to not execute the rest.
[email protected]b2528b72009-09-24 06:57:102323 if (!frame->executeCommand(WebString::fromUTF8(it->name),
2324 WebString::fromUTF8(it->value)))
2325 break;
[email protected]507b33ea2009-09-29 03:56:512326 did_execute_command = true;
[email protected]b2528b72009-09-24 06:57:102327 }
2328
[email protected]507b33ea2009-09-29 03:56:512329 return did_execute_command;
[email protected]b2528b72009-09-24 06:57:102330}
2331
[email protected]2a3a7762009-10-19 19:17:322332void RenderView::spellCheck(const WebString& text,
2333 int& misspelled_offset,
2334 int& misspelled_length) {
[email protected]1dbafaf72009-09-23 19:43:562335 EnsureDocumentTag();
[email protected]85c55dc2009-11-06 03:05:462336
[email protected]85c55dc2009-11-06 03:05:462337 string16 word(text);
[email protected]cb6037d2009-11-16 22:55:172338 RenderThread* thread = RenderThread::current();
2339 // Will be NULL during unit tests.
2340 if (thread) {
[email protected]c27324b2009-11-19 22:44:292341 thread->spellchecker()->SpellCheckWord(
[email protected]cb6037d2009-11-16 22:55:172342 word.c_str(), word.size(), document_tag_,
2343 &misspelled_offset, &misspelled_length, NULL);
2344 }
[email protected]1dbafaf72009-09-23 19:43:562345}
2346
2347WebString RenderView::autoCorrectWord(const WebKit::WebString& word) {
[email protected]2a3a7762009-10-19 19:17:322348 string16 autocorrect_word;
[email protected]1dbafaf72009-09-23 19:43:562349 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]b86c8c12009-10-05 22:01:262350 if (command_line.HasSwitch(switches::kExperimentalSpellcheckerFeatures)) {
[email protected]1dbafaf72009-09-23 19:43:562351 EnsureDocumentTag();
[email protected]cb6037d2009-11-16 22:55:172352 RenderThread* thread = RenderThread::current();
2353 // Will be NULL during unit tests.
2354 if (thread) {
2355 autocorrect_word =
[email protected]c27324b2009-11-19 22:44:292356 thread->spellchecker()->GetAutoCorrectionWord(
[email protected]cb6037d2009-11-16 22:55:172357 word, document_tag_);
2358 }
[email protected]1dbafaf72009-09-23 19:43:562359 }
[email protected]2a3a7762009-10-19 19:17:322360 return autocorrect_word;
[email protected]1dbafaf72009-09-23 19:43:562361}
2362
[email protected]c49085c72009-10-02 16:28:562363void RenderView::showSpellingUI(bool show) {
2364 Send(new ViewHostMsg_ShowSpellingPanel(routing_id_, show));
2365}
2366
[email protected]8922e1f2009-10-03 05:01:262367bool RenderView::isShowingSpellingUI() {
2368 return spelling_panel_visible_;
2369}
2370
[email protected]1dbafaf72009-09-23 19:43:562371void RenderView::updateSpellingUIWithMisspelledWord(const WebString& word) {
[email protected]2a3a7762009-10-19 19:17:322372 Send(new ViewHostMsg_UpdateSpellingPanelWithMisspelledWord(routing_id_,
2373 word));
[email protected]1dbafaf72009-09-23 19:43:562374}
2375
[email protected]13a1e4c3c2011-02-03 21:07:092376void RenderView::continuousSpellCheckingEnabledStateChanged() {
2377 UpdateToggleSpellCheckCommandState();
2378}
2379
[email protected]a1128322009-10-06 18:38:462380bool RenderView::runFileChooser(
[email protected]01178b52010-01-15 06:59:352381 const WebKit::WebFileChooserParams& params,
[email protected]cdaf8d02010-03-30 19:52:472382 WebFileChooserCompletion* chooser_completion) {
[email protected]7ef03e02010-10-23 11:58:352383 // Do not open the file dialog in a hidden RenderView.
2384 if (is_hidden())
2385 return false;
[email protected]cdaf8d02010-03-30 19:52:472386 ViewHostMsg_RunFileChooser_Params ipc_params;
[email protected]b5977a0c2010-08-24 19:46:262387 if (params.directory)
2388 ipc_params.mode = ViewHostMsg_RunFileChooser_Params::OpenFolder;
2389 else if (params.multiSelect)
2390 ipc_params.mode = ViewHostMsg_RunFileChooser_Params::OpenMultiple;
2391 else
2392 ipc_params.mode = ViewHostMsg_RunFileChooser_Params::Open;
[email protected]cdaf8d02010-03-30 19:52:472393 ipc_params.title = params.title;
2394 ipc_params.default_file_name =
2395 webkit_glue::WebStringToFilePath(params.initialValue);
[email protected]099949132010-09-08 20:24:592396 ipc_params.accept_types = params.acceptTypes;
[email protected]cdaf8d02010-03-30 19:52:472397
2398 return ScheduleFileChooser(ipc_params, chooser_completion);
[email protected]a1128322009-10-06 18:38:462399}
2400
[email protected]48c9cf2d2009-09-16 16:47:522401void RenderView::runModalAlertDialog(
2402 WebFrame* frame, const WebString& message) {
[email protected]9dd7e3d72011-01-20 18:27:062403 RunJavaScriptMessage(ui::MessageBoxFlags::kIsJavascriptAlert,
[email protected]48c9cf2d2009-09-16 16:47:522404 UTF16ToWideHack(message),
2405 std::wstring(),
2406 frame->url(),
2407 NULL);
2408}
2409
2410bool RenderView::runModalConfirmDialog(
2411 WebFrame* frame, const WebString& message) {
[email protected]9dd7e3d72011-01-20 18:27:062412 return RunJavaScriptMessage(ui::MessageBoxFlags::kIsJavascriptConfirm,
[email protected]48c9cf2d2009-09-16 16:47:522413 UTF16ToWideHack(message),
2414 std::wstring(),
2415 frame->url(),
2416 NULL);
2417}
2418
2419bool RenderView::runModalPromptDialog(
2420 WebFrame* frame, const WebString& message, const WebString& default_value,
2421 WebString* actual_value) {
2422 std::wstring result;
[email protected]9dd7e3d72011-01-20 18:27:062423 bool ok = RunJavaScriptMessage(ui::MessageBoxFlags::kIsJavascriptPrompt,
[email protected]48c9cf2d2009-09-16 16:47:522424 UTF16ToWideHack(message),
2425 UTF16ToWideHack(default_value),
2426 frame->url(),
2427 &result);
2428 if (ok)
2429 actual_value->assign(WideToUTF16Hack(result));
2430 return ok;
2431}
2432
2433bool RenderView::runModalBeforeUnloadDialog(
2434 WebFrame* frame, const WebString& message) {
2435 bool success = false;
2436 // This is an ignored return value, but is included so we can accept the same
2437 // response as RunJavaScriptMessage.
2438 std::wstring ignored_result;
[email protected]12636df2009-09-28 22:32:212439 SendAndRunNestedMessageLoop(new ViewHostMsg_RunBeforeUnloadConfirm(
[email protected]48c9cf2d2009-09-16 16:47:522440 routing_id_, frame->url(), UTF16ToWideHack(message), &success,
[email protected]12636df2009-09-28 22:32:212441 &ignored_result));
[email protected]48c9cf2d2009-09-16 16:47:522442 return success;
2443}
2444
[email protected]79e37442009-10-09 18:17:442445void RenderView::showContextMenu(
2446 WebFrame* frame, const WebContextMenuData& data) {
[email protected]c27324b2009-11-19 22:44:292447 ContextMenuParams params = ContextMenuParams(data);
2448 if (!params.misspelled_word.empty() && RenderThread::current()) {
2449 int misspelled_offset, misspelled_length;
[email protected]c76a36a2010-01-26 22:44:042450 bool spelled_right = RenderThread::current()->spellchecker()->
2451 SpellCheckWord(
2452 params.misspelled_word.c_str(), params.misspelled_word.size(),
2453 document_tag_,
2454 &misspelled_offset, &misspelled_length,
2455 &params.dictionary_suggestions);
2456 if (spelled_right)
[email protected]c27324b2009-11-19 22:44:292457 params.misspelled_word.clear();
2458 }
[email protected]216932c2010-08-26 21:44:272459 // Serializing a GURL longer than chrome::kMaxURLChars will fail, so don't do
2460 // it. We replace it with an empty GURL so the appropriate items are disabled
2461 // in the context menu.
2462 // TODO(jcivelli): http://crbug.com/45160 This prevents us from saving large
2463 // data encoded images. We should have a way to save them.
2464 if (params.src_url.spec().size() > chrome::kMaxURLChars)
2465 params.src_url = GURL();
[email protected]521b2482011-01-15 00:10:102466 context_menu_node_ = data.node;
[email protected]c27324b2009-11-19 22:44:292467 Send(new ViewHostMsg_ContextMenu(routing_id_, params));
[email protected]79e37442009-10-09 18:17:442468}
2469
[email protected]52f139e2c2010-06-11 16:56:092470bool RenderView::supportsFullscreen() {
2471 return CommandLine::ForCurrentProcess()->HasSwitch(
2472 switches::kEnableVideoFullscreen);
2473}
2474
2475void RenderView::enterFullscreenForNode(const WebKit::WebNode& node) {
2476 NOTIMPLEMENTED();
2477}
2478
2479void RenderView::exitFullscreenForNode(const WebKit::WebNode& node) {
2480 NOTIMPLEMENTED();
2481}
2482
[email protected]48c9cf2d2009-09-16 16:47:522483void RenderView::setStatusText(const WebString& text) {
2484}
2485
[email protected]163f8242009-10-30 20:19:552486void RenderView::UpdateTargetURL(const GURL& url, const GURL& fallback_url) {
[email protected]aa6b90b32010-04-26 15:49:582487 GURL latest_url = url.is_empty() ? fallback_url : url;
[email protected]48c9cf2d2009-09-16 16:47:522488 if (latest_url == target_url_)
2489 return;
[email protected]163f8242009-10-30 20:19:552490
[email protected]48c9cf2d2009-09-16 16:47:522491 // Tell the browser to display a destination link.
2492 if (target_url_status_ == TARGET_INFLIGHT ||
2493 target_url_status_ == TARGET_PENDING) {
2494 // If we have a request in-flight, save the URL to be sent when we
2495 // receive an ACK to the in-flight request. We can happily overwrite
2496 // any existing pending sends.
2497 pending_target_url_ = latest_url;
2498 target_url_status_ = TARGET_PENDING;
2499 } else {
2500 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_, latest_url));
2501 target_url_ = latest_url;
2502 target_url_status_ = TARGET_INFLIGHT;
2503 }
2504}
2505
[email protected]13a1e4c3c2011-02-03 21:07:092506void RenderView::UpdateToggleSpellCheckCommandState() {
2507 bool is_enabled = false;
2508 WebKit::WebNode node = GetFocusedNode();
2509 if (!node.isNull())
2510 is_enabled = IsEditableNode(node);
2511
2512 RenderViewCommandCheckedState checked_state =
2513 RENDER_VIEW_COMMAND_CHECKED_STATE_UNCHECKED;
2514 if (is_enabled && webview()) {
2515 WebFrame* frame = webview()->focusedFrame();
2516 if (frame->isContinuousSpellCheckingEnabled())
2517 checked_state = RENDER_VIEW_COMMAND_CHECKED_STATE_CHECKED;
2518 }
2519
2520 Send(new ViewHostMsg_CommandStateChanged(
2521 routing_id_,
2522 RENDER_VIEW_COMMAND_TOGGLE_SPELL_CHECK,
2523 is_enabled,
2524 checked_state));
2525}
2526
[email protected]882daa92009-11-05 16:31:312527void RenderView::StartNavStateSyncTimerIfNecessary() {
2528 int delay;
2529 if (send_content_state_immediately_)
2530 delay = 0;
2531 else if (is_hidden())
2532 delay = kDelaySecondsForContentStateSyncHidden;
2533 else
2534 delay = kDelaySecondsForContentStateSync;
2535
2536 if (nav_state_sync_timer_.IsRunning()) {
2537 // The timer is already running. If the delay of the timer maches the amount
2538 // we want to delay by, then return. Otherwise stop the timer so that it
2539 // gets started with the right delay.
2540 if (nav_state_sync_timer_.GetCurrentDelay().InSeconds() == delay)
2541 return;
2542 nav_state_sync_timer_.Stop();
2543 }
2544
2545 nav_state_sync_timer_.Start(
2546 TimeDelta::FromSeconds(delay), this, &RenderView::SyncNavigationState);
2547}
2548
[email protected]163f8242009-10-30 20:19:552549void RenderView::setMouseOverURL(const WebURL& url) {
2550 mouse_over_url_ = GURL(url);
2551 UpdateTargetURL(mouse_over_url_, focus_url_);
2552}
2553
2554void RenderView::setKeyboardFocusURL(const WebURL& url) {
2555 focus_url_ = GURL(url);
2556 UpdateTargetURL(focus_url_, mouse_over_url_);
2557}
2558
[email protected]48c9cf2d2009-09-16 16:47:522559void RenderView::setToolTipText(const WebString& text, WebTextDirection hint) {
2560 Send(new ViewHostMsg_SetTooltipText(routing_id_, UTF16ToWideHack(text),
2561 hint));
2562}
2563
[email protected]c27ae592010-03-18 15:24:412564void RenderView::startDragging(const WebDragData& data,
2565 WebDragOperationsMask mask,
2566 const WebImage& image,
2567 const WebPoint& imageOffset) {
2568#if WEBKIT_USING_SKIA
2569 SkBitmap bitmap(image.getSkBitmap());
2570#elif WEBKIT_USING_CG
[email protected]78043bdd2010-04-05 18:45:332571 SkBitmap bitmap = gfx::CGImageToSkBitmap(image.getCGImageRef());
[email protected]c27ae592010-03-18 15:24:412572#endif
2573
[email protected]48c9cf2d2009-09-16 16:47:522574 Send(new ViewHostMsg_StartDragging(routing_id_,
2575 WebDropData(data),
[email protected]c27ae592010-03-18 15:24:412576 mask,
2577 bitmap,
2578 imageOffset));
[email protected]48c9cf2d2009-09-16 16:47:522579}
2580
[email protected]28b92df2009-09-25 17:35:452581bool RenderView::acceptsLoadDrops() {
2582 return renderer_preferences_.can_accept_load_drops;
2583}
2584
[email protected]48c9cf2d2009-09-16 16:47:522585void RenderView::focusNext() {
2586 Send(new ViewHostMsg_TakeFocus(routing_id_, false));
2587}
2588
2589void RenderView::focusPrevious() {
2590 Send(new ViewHostMsg_TakeFocus(routing_id_, true));
2591}
2592
[email protected]08e9e132010-06-01 16:58:492593void RenderView::focusedNodeChanged(const WebNode& node) {
[email protected]9b66f34bf2010-10-27 20:45:512594 Send(new ViewHostMsg_FocusedNodeChanged(routing_id_, IsEditableNode(node)));
[email protected]a4b103b2010-10-05 18:46:072595
2596 if (WebAccessibilityCache::accessibilityEnabled() && node.isNull()) {
2597 // TODO(ctguil): Make WebKit send this notification.
2598 // When focus is cleared notify accessibility that the document is focused.
2599 postAccessibilityNotification(
2600 webview()->accessibilityObject(),
2601 WebKit::WebAccessibilityNotificationFocusedUIElementChanged);
2602 }
[email protected]13a1e4c3c2011-02-03 21:07:092603
2604 UpdateToggleSpellCheckCommandState();
[email protected]08e9e132010-06-01 16:58:492605}
2606
[email protected]48c9cf2d2009-09-16 16:47:522607void RenderView::navigateBackForwardSoon(int offset) {
[email protected]48c9cf2d2009-09-16 16:47:522608 Send(new ViewHostMsg_GoToEntryAtOffset(routing_id_, offset));
2609}
2610
2611int RenderView::historyBackListCount() {
[email protected]3cc72b12010-03-18 23:03:002612 return history_list_offset_ < 0 ? 0 : history_list_offset_;
[email protected]48c9cf2d2009-09-16 16:47:522613}
2614
2615int RenderView::historyForwardListCount() {
[email protected]3cc72b12010-03-18 23:03:002616 return history_list_length_ - historyBackListCount() - 1;
[email protected]48c9cf2d2009-09-16 16:47:522617}
2618
[email protected]c4e98902010-06-01 10:20:142619void RenderView::didUpdateInspectorSetting(const WebString& key,
2620 const WebString& value) {
2621 Send(new ViewHostMsg_UpdateInspectorSetting(routing_id_,
2622 key.utf8(),
2623 value.utf8()));
[email protected]8922e1f2009-10-03 05:01:262624}
2625
[email protected]79dbc662009-09-04 05:42:512626// WebKit::WebWidgetClient ----------------------------------------------------
2627
[email protected]ea42e7782010-08-23 23:58:122628void RenderView::didFocus() {
2629 // TODO(jcivelli): when https://bugs.webkit.org/show_bug.cgi?id=33389 is fixed
2630 // we won't have to test for user gesture anymore and we can
2631 // move that code back to render_widget.cc
2632 if (webview() && webview()->mainFrame() &&
2633 webview()->mainFrame()->isProcessingUserGesture()) {
2634 Send(new ViewHostMsg_Focus(routing_id_));
2635 }
2636}
2637
2638void RenderView::didBlur() {
2639 // TODO(jcivelli): see TODO above in didFocus().
2640 if (webview() && webview()->mainFrame() &&
2641 webview()->mainFrame()->isProcessingUserGesture()) {
2642 Send(new ViewHostMsg_Blur(routing_id_));
2643 }
2644}
2645
initial.commit09911bf2008-07-26 23:55:292646// We are supposed to get a single call to Show for a newly created RenderView
2647// that was created via RenderView::CreateWebView. So, we wait until this
2648// point to dispatch the ShowView message.
2649//
2650// This method provides us with the information about how to display the newly
2651// created RenderView (i.e., as a constrained popup or as a new tab).
2652//
[email protected]4873c7d2009-07-16 06:36:282653void RenderView::show(WebNavigationPolicy policy) {
initial.commit09911bf2008-07-26 23:55:292654 DCHECK(!did_show_) << "received extraneous Show call";
2655 DCHECK(opener_id_ != MSG_ROUTING_NONE);
2656
2657 if (did_show_)
2658 return;
2659 did_show_ = true;
2660
[email protected]4026ce1e2010-09-14 19:35:042661 // Extensions and apps always allowed to create unrequested popups. The second
2662 // check is necessary to include content scripts.
[email protected]2a521c52011-01-26 18:45:212663 if (render_thread_->GetExtensions()->GetByURL(creator_url_) ||
[email protected]4026ce1e2010-09-14 19:35:042664 bindings_utils::GetInfoForCurrentContext()) {
2665 opened_by_user_gesture_ = true;
2666 }
2667
[email protected]28295ec2009-10-16 05:34:332668 // Force new windows to a popup if they were not opened with a user gesture.
2669 if (!opened_by_user_gesture_) {
2670 // We exempt background tabs for compat with older versions of Chrome.
2671 // TODO(darin): This seems bogus. These should have a user gesture, so
2672 // we probably don't need this check.
2673 if (policy != WebKit::WebNavigationPolicyNewBackgroundTab)
2674 policy = WebKit::WebNavigationPolicyNewPopup;
2675 }
2676
initial.commit09911bf2008-07-26 23:55:292677 // NOTE: initial_pos_ may still have its default values at this point, but
2678 // that's okay. It'll be ignored if disposition is not NEW_POPUP, or the
2679 // browser process will impose a default position otherwise.
[email protected]4873c7d2009-07-16 06:36:282680 Send(new ViewHostMsg_ShowView(opener_id_, routing_id_,
2681 NavigationPolicyToDisposition(policy), initial_pos_,
[email protected]7e7414ae2010-01-26 20:19:292682 opened_by_user_gesture_));
[email protected]2533ce12009-05-09 00:02:242683 SetPendingWindowRect(initial_pos_);
initial.commit09911bf2008-07-26 23:55:292684}
2685
[email protected]4873c7d2009-07-16 06:36:282686void RenderView::closeWidgetSoon() {
[email protected]3ead1322010-11-19 20:01:002687 // Same for the phishing classifier.
2688 if (phishing_delegate_.get())
2689 phishing_delegate_->CancelPendingClassification();
2690
[email protected]e8345242010-05-06 03:00:402691 if (script_can_close_)
[email protected]4873c7d2009-07-16 06:36:282692 RenderWidget::closeWidgetSoon();
[email protected]634a6f92008-12-01 21:39:312693}
2694
[email protected]4873c7d2009-07-16 06:36:282695void RenderView::runModal() {
initial.commit09911bf2008-07-26 23:55:292696 DCHECK(did_show_) << "should already have shown the view";
2697
[email protected]c1f50aa2010-02-18 03:46:572698 // We must keep WebKit's shared timer running in this case in order to allow
2699 // showModalDialog to function properly.
2700 //
2701 // TODO(darin): WebKit should really be smarter about suppressing events and
2702 // timers so that we do not need to manage the shared timer in such a heavy
2703 // handed manner.
2704 //
2705 if (RenderThread::current()) // Will be NULL during unit tests.
2706 RenderThread::current()->DoNotSuspendWebKitSharedTimer();
2707
[email protected]12636df2009-09-28 22:32:212708 SendAndRunNestedMessageLoop(new ViewHostMsg_RunModal(routing_id_));
initial.commit09911bf2008-07-26 23:55:292709}
2710
[email protected]3d9689372009-09-10 04:29:172711// WebKit::WebFrameClient -----------------------------------------------------
2712
[email protected]00152e92010-07-19 11:47:402713WebPlugin* RenderView::createPlugin(WebFrame* frame,
2714 const WebPluginParams& params) {
[email protected]6fdd4182010-10-14 23:59:262715 bool found = false;
[email protected]414508d2010-11-02 10:45:392716 ContentSetting plugin_setting = CONTENT_SETTING_DEFAULT;
[email protected]55126132010-08-19 14:53:282717 CommandLine* cmd = CommandLine::ForCurrentProcess();
[email protected]191eb3f72010-12-21 06:27:502718 webkit::npapi::WebPluginInfo info;
[email protected]7a13e792010-08-03 08:18:242719 GURL url(params.url);
[email protected]6fdd4182010-10-14 23:59:262720 std::string actual_mime_type;
[email protected]c8f73ab2011-01-22 00:05:172721 Send(new ViewHostMsg_GetPluginInfo(routing_id_,
2722 url,
[email protected]6fdd4182010-10-14 23:59:262723 frame->top()->url(),
2724 params.mimeType.utf8(),
2725 &found,
2726 &info,
[email protected]44fda5c2010-11-02 10:50:542727 &plugin_setting,
[email protected]6fdd4182010-10-14 23:59:262728 &actual_mime_type));
[email protected]7a13e792010-08-03 08:18:242729
[email protected]6fdd4182010-10-14 23:59:262730 if (!found)
[email protected]0cdafff2010-07-26 09:54:372731 return NULL;
[email protected]414508d2010-11-02 10:45:392732 DCHECK(plugin_setting != CONTENT_SETTING_DEFAULT);
[email protected]4e0616e2010-05-28 14:55:532733
[email protected]191eb3f72010-12-21 06:27:502734 const webkit::npapi::PluginGroup* group =
2735 webkit::npapi::PluginList::Singleton()->GetPluginGroup(info);
[email protected]79ce1032010-12-07 13:29:412736 DCHECK(group != NULL);
[email protected]851b1eb2010-08-09 13:32:292737
[email protected]6e74a3b2010-12-21 22:27:542738 if (group->IsVulnerable() &&
2739 !cmd->HasSwitch(switches::kAllowOutdatedPlugins)) {
[email protected]3c2826852010-12-16 19:09:142740 Send(new ViewHostMsg_BlockedOutdatedPlugin(routing_id_,
2741 group->GetGroupName(),
2742 GURL(group->GetUpdateURL())));
2743 return CreatePluginPlaceholder(frame,
2744 params,
2745 *group,
[email protected]2e34ab3f2010-12-17 05:47:372746 IDR_BLOCKED_PLUGIN_HTML,
[email protected]90dba072011-01-20 20:10:202747 IDS_PLUGIN_OUTDATED,
2748 false);
[email protected]851b1eb2010-08-09 13:32:292749 }
[email protected]6e74a3b2010-12-21 22:27:542750
[email protected]b83ff222011-01-24 17:37:122751 if (!webkit::npapi::IsPluginEnabled(info))
[email protected]3c2826852010-12-16 19:09:142752 return NULL;
[email protected]851b1eb2010-08-09 13:32:292753
[email protected]414508d2010-11-02 10:45:392754 ContentSetting host_setting =
2755 current_content_settings_.settings[CONTENT_SETTINGS_TYPE_PLUGINS];
[email protected]d12dcdd62011-01-27 06:53:252756
2757 if (group->RequiresAuthorization() &&
2758 !cmd->HasSwitch(switches::kAlwaysAuthorizePlugins) &&
2759 (plugin_setting == CONTENT_SETTING_ALLOW ||
2760 plugin_setting == CONTENT_SETTING_ASK) &&
2761 host_setting == CONTENT_SETTING_DEFAULT) {
2762 Send(new ViewHostMsg_BlockedOutdatedPlugin(routing_id_,
2763 group->GetGroupName(),
2764 GURL()));
2765 return CreatePluginPlaceholder(frame,
2766 params,
2767 *group,
2768 IDR_BLOCKED_PLUGIN_HTML,
2769 IDS_PLUGIN_NOT_AUTHORIZED,
2770 false);
2771 }
2772
[email protected]191eb3f72010-12-21 06:27:502773 if (info.path.value() == webkit::npapi::kDefaultPluginLibraryName ||
[email protected]414508d2010-11-02 10:45:392774 plugin_setting == CONTENT_SETTING_ALLOW ||
2775 host_setting == CONTENT_SETTING_ALLOW) {
[email protected]90dba072011-01-20 20:10:202776 // Delay loading plugins if prerendering.
2777 WebDataSource* ds = frame->dataSource();
2778 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
2779 if (navigation_state->is_prerendering()) {
2780 return CreatePluginPlaceholder(frame,
2781 params,
2782 *group,
2783 IDR_CLICK_TO_PLAY_PLUGIN_HTML,
2784 IDS_PLUGIN_LOAD,
2785 true);
2786 }
2787
[email protected]0bd753682010-12-16 18:15:522788 scoped_refptr<webkit::ppapi::PluginModule> pepper_module(
[email protected]1a78d9f32010-12-08 06:38:452789 pepper_delegate_.CreatePepperPlugin(info.path));
2790 if (pepper_module)
2791 return CreatePepperPlugin(frame, params, info.path, pepper_module.get());
[email protected]6fdd4182010-10-14 23:59:262792 return CreateNPAPIPlugin(frame, params, info.path, actual_mime_type);
[email protected]0cdafff2010-07-26 09:54:372793 }
[email protected]fc61e222010-10-11 15:42:142794 std::string resource;
2795 if (cmd->HasSwitch(switches::kEnableResourceContentSettings))
2796 resource = group->identifier();
2797 DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, resource);
[email protected]414508d2010-11-02 10:45:392798 if (plugin_setting == CONTENT_SETTING_ASK) {
[email protected]3c2826852010-12-16 19:09:142799 return CreatePluginPlaceholder(frame,
2800 params,
2801 *group,
[email protected]2e34ab3f2010-12-17 05:47:372802 IDR_CLICK_TO_PLAY_PLUGIN_HTML,
[email protected]90dba072011-01-20 20:10:202803 IDS_PLUGIN_LOAD,
2804 false);
[email protected]fc61e222010-10-11 15:42:142805 } else {
[email protected]3c2826852010-12-16 19:09:142806 return CreatePluginPlaceholder(frame,
2807 params,
2808 *group,
[email protected]2e34ab3f2010-12-17 05:47:372809 IDR_BLOCKED_PLUGIN_HTML,
[email protected]90dba072011-01-20 20:10:202810 IDS_PLUGIN_BLOCKED,
2811 false);
[email protected]fc61e222010-10-11 15:42:142812 }
[email protected]3d9689372009-09-10 04:29:172813}
2814
2815WebWorker* RenderView::createWorker(WebFrame* frame, WebWorkerClient* client) {
[email protected]14396e92010-05-06 20:40:562816 WebApplicationCacheHostImpl* appcache_host =
2817 WebApplicationCacheHostImpl::FromFrame(frame);
2818 int appcache_host_id = appcache_host ? appcache_host->host_id() : 0;
2819 return new WebWorkerProxy(client, RenderThread::current(), routing_id_,
2820 appcache_host_id);
[email protected]3d9689372009-09-10 04:29:172821}
2822
[email protected]9c00f002009-11-05 22:37:422823WebSharedWorker* RenderView::createSharedWorker(
2824 WebFrame* frame, const WebURL& url, const WebString& name,
[email protected]30447b62009-11-13 01:13:372825 unsigned long long document_id) {
[email protected]9c00f002009-11-05 22:37:422826
[email protected]30447b62009-11-13 01:13:372827 int route_id = MSG_ROUTING_NONE;
[email protected]6de0bcf2010-02-17 22:00:512828 bool exists = false;
[email protected]30447b62009-11-13 01:13:372829 bool url_mismatch = false;
[email protected]6de0bcf2010-02-17 22:00:512830 ViewHostMsg_CreateWorker_Params params;
2831 params.url = url;
2832 params.is_shared = true;
2833 params.name = name;
2834 params.document_id = document_id;
2835 params.render_view_route_id = routing_id_;
2836 params.route_id = MSG_ROUTING_NONE;
[email protected]f9bc9c02010-05-24 19:19:232837 params.parent_appcache_host_id = 0;
2838 params.script_resource_appcache_id = 0;
[email protected]30447b62009-11-13 01:13:372839 Send(new ViewHostMsg_LookupSharedWorker(
[email protected]6de0bcf2010-02-17 22:00:512840 params, &exists, &route_id, &url_mismatch));
[email protected]30447b62009-11-13 01:13:372841 if (url_mismatch) {
2842 return NULL;
2843 } else {
2844 return new WebSharedWorkerProxy(RenderThread::current(),
[email protected]0791d3a2010-01-28 01:28:492845 document_id,
[email protected]6de0bcf2010-02-17 22:00:512846 exists,
[email protected]30447b62009-11-13 01:13:372847 route_id,
2848 routing_id_);
2849 }
[email protected]9c00f002009-11-05 22:37:422850}
2851
[email protected]3d9689372009-09-10 04:29:172852WebMediaPlayer* RenderView::createMediaPlayer(
2853 WebFrame* frame, WebMediaPlayerClient* client) {
[email protected]f78d1dfc2011-01-15 07:09:272854 scoped_ptr<media::MessageLoopFactory> message_loop_factory(
2855 new media::MessageLoopFactoryImpl());
[email protected]f8db8132010-12-03 00:27:492856 scoped_ptr<media::FilterCollection> collection(
2857 new media::FilterCollection());
[email protected]457d8342010-10-23 01:20:372858
[email protected]3d9689372009-09-10 04:29:172859 // Add in any custom filter factories first.
2860 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
2861 if (!cmd_line->HasSwitch(switches::kDisableAudio)) {
2862 // Add the chrome specific audio renderer.
[email protected]b7ba5b52010-11-15 22:04:492863 collection->AddAudioRenderer(new AudioRendererImpl(audio_message_filter()));
[email protected]3d9689372009-09-10 04:29:172864 }
2865
[email protected]3bb08602010-10-07 21:47:172866 if (cmd_line->HasSwitch(switches::kEnableAcceleratedDecoding) &&
[email protected]11c4c812010-10-22 19:50:122867 !cmd_line->HasSwitch(switches::kDisableAcceleratedCompositing)) {
[email protected]5aa6a312010-11-06 00:00:072868 WebGraphicsContext3DCommandBufferImpl* context =
2869 static_cast<WebGraphicsContext3DCommandBufferImpl*>(
2870 frame->view()->graphicsContext3D());
2871 if (!context)
2872 return NULL;
[email protected]a9a43012010-11-05 01:54:062873
[email protected]5aa6a312010-11-06 00:00:072874 // Add the hardware video decoder factory.
2875 // TODO(hclam): This will cause the renderer process to crash on context
2876 // lost.
2877 bool ret = context->makeContextCurrent();
2878 CHECK(ret) << "Failed to switch context";
[email protected]b7ba5b52010-11-15 22:04:492879 collection->AddVideoDecoder(new IpcVideoDecoder(
[email protected]5aa6a312010-11-06 00:00:072880 MessageLoop::current(), context->context()));
[email protected]3bb08602010-10-07 21:47:172881 }
2882
[email protected]457d8342010-10-23 01:20:372883 scoped_refptr<webkit_glue::WebVideoRenderer> video_renderer;
[email protected]77128dec2010-11-08 17:05:312884 bool pts_logging = cmd_line->HasSwitch(switches::kEnableVideoLogging);
2885 scoped_refptr<webkit_glue::VideoRendererImpl> renderer(
2886 new webkit_glue::VideoRendererImpl(pts_logging));
[email protected]b7ba5b52010-11-15 22:04:492887 collection->AddVideoRenderer(renderer);
[email protected]77128dec2010-11-08 17:05:312888 video_renderer = renderer;
[email protected]8400e032010-02-26 18:50:112889
[email protected]a8e24d522010-12-01 07:13:582890 scoped_ptr<webkit_glue::WebMediaPlayerImpl> result(
[email protected]f78d1dfc2011-01-15 07:09:272891 new webkit_glue::WebMediaPlayerImpl(client,
2892 collection.release(),
2893 message_loop_factory.release()));
[email protected]79684282010-12-06 21:15:462894 if (!result->Initialize(frame,
[email protected]a8e24d522010-12-01 07:13:582895 cmd_line->HasSwitch(switches::kSimpleDataSource),
2896 video_renderer)) {
2897 return NULL;
2898 }
2899 return result.release();
[email protected]3d9689372009-09-10 04:29:172900}
2901
[email protected]035545f2010-04-09 13:10:212902WebApplicationCacheHost* RenderView::createApplicationCacheHost(
2903 WebFrame* frame, WebApplicationCacheHostClient* client) {
2904 return new RendererWebApplicationCacheHostImpl(
2905 FromWebView(frame->view()), client,
2906 RenderThread::current()->appcache_dispatcher()->backend_proxy());
2907}
2908
[email protected]8ff181072010-11-29 17:09:382909WebCookieJar* RenderView::cookieJar(WebFrame* frame) {
2910 return &cookie_jar_;
2911}
2912
[email protected]5041f982010-08-11 21:40:452913void RenderView::frameDetached(WebFrame* frame) {
[email protected]676126f72011-01-15 00:03:512914 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame));
[email protected]5041f982010-08-11 21:40:452915}
2916
[email protected]3d9689372009-09-10 04:29:172917void RenderView::willClose(WebFrame* frame) {
[email protected]fa7b6b542009-11-03 05:02:302918 WebDataSource* ds = frame->dataSource();
2919 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
[email protected]05c8e502010-08-15 15:13:522920
[email protected]a5a65ac2010-11-05 18:14:362921 page_load_histograms_.Dump(frame);
[email protected]fa7b6b542009-11-03 05:02:302922 navigation_state->user_script_idle_scheduler()->Cancel();
[email protected]f3ce0a32011-01-11 08:18:182923
[email protected]676126f72011-01-15 00:03:512924 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame));
[email protected]3d9689372009-09-10 04:29:172925}
2926
[email protected]684e4a42010-01-30 06:44:112927bool RenderView::allowImages(WebFrame* frame, bool enabled_per_settings) {
[email protected]12bc8472010-04-15 07:29:402928 if (enabled_per_settings &&
2929 AllowContentType(CONTENT_SETTINGS_TYPE_IMAGES))
2930 return true;
2931
2932 if (IsWhitelistedForContentSettings(frame))
2933 return true;
2934
[email protected]55126132010-08-19 14:53:282935 DidBlockContentType(CONTENT_SETTINGS_TYPE_IMAGES, std::string());
[email protected]12bc8472010-04-15 07:29:402936 return false; // Other protocols fall through here.
[email protected]684e4a42010-01-30 06:44:112937}
2938
[email protected]d5f9e4f2010-07-28 08:31:302939bool RenderView::allowPlugins(WebFrame* frame, bool enabled_per_settings) {
[email protected]3627b06d2010-11-12 16:36:162940 return WebFrameClient::allowPlugins(frame, enabled_per_settings);
[email protected]d5f9e4f2010-07-28 08:31:302941}
2942
2943
[email protected]3d9689372009-09-10 04:29:172944void RenderView::loadURLExternally(
2945 WebFrame* frame, const WebURLRequest& request,
2946 WebNavigationPolicy policy) {
[email protected]efce17b2009-09-11 18:04:592947 GURL referrer(request.httpHeaderField(WebString::fromUTF8("Referer")));
2948 if (policy == WebKit::WebNavigationPolicyDownload) {
2949 Send(new ViewHostMsg_DownloadUrl(routing_id_, request.url(), referrer));
2950 } else {
2951 OpenURL(request.url(), referrer, policy);
2952 }
[email protected]3d9689372009-09-10 04:29:172953}
2954
2955WebNavigationPolicy RenderView::decidePolicyForNavigation(
2956 WebFrame* frame, const WebURLRequest& request, WebNavigationType type,
[email protected]65b95cd2009-10-09 05:10:222957 const WebNode&, WebNavigationPolicy default_policy, bool is_redirect) {
[email protected]3d9689372009-09-10 04:29:172958 // Webkit is asking whether to navigate to a new URL.
2959 // This is fine normally, except if we're showing UI from one security
2960 // context and they're trying to navigate to a different context.
2961 const GURL& url = request.url();
2962
2963 // If the browser is interested, then give it a chance to look at top level
[email protected]3a8eecb2010-04-22 23:56:302964 // navigations.
[email protected]8079b362010-05-07 18:37:452965 if (renderer_preferences_.browser_handles_top_level_requests &&
2966 IsNonLocalTopLevelNavigation(url, frame, type)) {
[email protected]61c9f032010-03-31 23:04:192967 GURL referrer(request.httpHeaderField(WebString::fromUTF8("Referer")));
[email protected]a58db8b2010-08-24 01:51:232968 // Reset these counters as the RenderView could be reused for the next
2969 // navigation.
2970 page_id_ = -1;
[email protected]a58db8b2010-08-24 01:51:232971 last_page_id_sent_to_browser_ = -1;
[email protected]61c9f032010-03-31 23:04:192972 OpenURL(url, referrer, default_policy);
2973 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
[email protected]3d9689372009-09-10 04:29:172974 }
2975
2976 // A content initiated navigation may have originated from a link-click,
2977 // script, drag-n-drop operation, etc.
2978 bool is_content_initiated =
2979 NavigationState::FromDataSource(frame->provisionalDataSource())->
2980 is_content_initiated();
[email protected]a6b960ad972010-09-01 19:53:582981 GURL old_url(frame->url());
[email protected]3d9689372009-09-10 04:29:172982
[email protected]6101c342010-12-16 22:44:372983 // Detect when we're crossing a permission-based boundary (e.g. into or out of
2984 // an extension or app origin, leaving a DOMUI page, etc). We only care about
2985 // top-level navigations withing the current tab (as opposed to, for example,
2986 // opening a new window). But we sometimes navigate to about:blank to clear a
2987 // tab, and we want to still allow that.
2988 //
2989 // Note: we do this only for GET requests because we our mechanism for
2990 // switching processes only issues GET requests. In particular, POST
2991 // requests don't work, because this mechanism does not preserve form POST
2992 // data. If it becomes necessary to support process switching for POST
2993 // requests, we will need to send the request's httpBody data up to the
2994 // browser process, and issue a special POST navigation in WebKit (via
2995 // FrameLoader::loadFrameRequest). See ResourceDispatcher and
2996 // WebURLLoaderImpl for examples of how to send the httpBody data.
2997 if (!frame->parent() && is_content_initiated &&
2998 default_policy == WebKit::WebNavigationPolicyCurrentTab &&
2999 request.httpMethod() == "GET" && !url.SchemeIs(chrome::kAboutScheme)) {
3000 bool send_referrer = false;
3001 bool should_fork =
3002 BindingsPolicy::is_dom_ui_enabled(enabled_bindings_) ||
[email protected]3d9689372009-09-10 04:29:173003 frame->isViewSourceModeEnabled() ||
[email protected]6101c342010-12-16 22:44:373004 url.SchemeIs(chrome::kViewSourceScheme);
[email protected]5351dbc2010-08-27 15:22:113005
3006 // If the navigation would cross an app extent boundary, we also need
3007 // to defer to the browser to ensure process isolation.
3008 // TODO(erikkay) This is happening inside of a check to is_content_initiated
3009 // which means that things like the back button won't trigger it. Is that
3010 // OK?
[email protected]88c15e972011-02-05 04:19:533011 // TODO(creis): For hosted apps, we currently only swap processes to enter
3012 // the app and not exit it, since we currently lose context (e.g.,
3013 // window.opener) if the window navigates back. See crbug.com/65953.
[email protected]2a521c52011-01-26 18:45:213014 if (!should_fork &&
[email protected]88c15e972011-02-05 04:19:533015 CrossesExtensionExtents(
[email protected]2a521c52011-01-26 18:45:213016 render_thread_->GetExtensions(),
3017 frame,
3018 url)) {
[email protected]5351dbc2010-08-27 15:22:113019 // Include the referrer in this case since we're going from a hosted web
3020 // page. (the packaged case is handled previously by the extension
3021 // navigation test)
[email protected]6101c342010-12-16 22:44:373022 should_fork = true;
3023 send_referrer = true;
3024 }
3025
3026 if (should_fork) {
[email protected]5351dbc2010-08-27 15:22:113027 GURL referrer(request.httpHeaderField(WebString::fromUTF8("Referer")));
[email protected]6101c342010-12-16 22:44:373028 OpenURL(url, send_referrer ? referrer : GURL(), default_policy);
[email protected]5351dbc2010-08-27 15:22:113029 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
3030 }
[email protected]3d9689372009-09-10 04:29:173031 }
3032
3033 // Detect when a page is "forking" a new tab that can be safely rendered in
3034 // its own process. This is done by sites like Gmail that try to open links
3035 // in new windows without script connections back to the original page. We
3036 // treat such cases as browser navigations (in which we will create a new
3037 // renderer for a cross-site navigation), rather than WebKit navigations.
3038 //
3039 // We use the following heuristic to decide whether to fork a new page in its
3040 // own process:
3041 // The parent page must open a new tab to about:blank, set the new tab's
3042 // window.opener to null, and then redirect the tab to a cross-site URL using
3043 // JavaScript.
[email protected]007a848b2009-10-26 15:55:463044 //
3045 // TODO(creis): Deprecate this logic once we can rely on rel=noreferrer
3046 // (see below).
[email protected]3d9689372009-09-10 04:29:173047 bool is_fork =
3048 // Must start from a tab showing about:blank, which is later redirected.
[email protected]a6b960ad972010-09-01 19:53:583049 old_url == GURL(chrome::kAboutBlankURL) &&
[email protected]3d9689372009-09-10 04:29:173050 // Must be the first real navigation of the tab.
[email protected]48c9cf2d2009-09-16 16:47:523051 historyBackListCount() < 1 &&
3052 historyForwardListCount() < 1 &&
[email protected]3d9689372009-09-10 04:29:173053 // The parent page must have set the child's window.opener to null before
3054 // redirecting to the desired URL.
3055 frame->opener() == NULL &&
3056 // Must be a top-level frame.
3057 frame->parent() == NULL &&
3058 // Must not have issued the request from this page.
3059 is_content_initiated &&
3060 // Must be targeted at the current tab.
3061 default_policy == WebKit::WebNavigationPolicyCurrentTab &&
3062 // Must be a JavaScript navigation, which appears as "other".
3063 type == WebKit::WebNavigationTypeOther;
[email protected]007a848b2009-10-26 15:55:463064
3065 // Recognize if this navigation is from a link with rel=noreferrer and
3066 // target=_blank attributes, in which case the opener will be suppressed. If
3067 // so, it is safe to load cross-site pages in a separate process, so we
3068 // should let the browser handle it.
3069 bool is_noreferrer_and_blank_target =
3070 // Frame should be top level and not yet navigated.
3071 frame->parent() == NULL &&
3072 frame->url().isEmpty() &&
3073 historyBackListCount() < 1 &&
3074 historyForwardListCount() < 1 &&
3075 // Links with rel=noreferrer will have no Referer field, and their
3076 // resulting frame will have its window.opener suppressed.
3077 // TODO(creis): should add a request.httpReferrer() method to help avoid
3078 // typos on the unusual spelling of Referer.
3079 request.httpHeaderField(WebString::fromUTF8("Referer")).isNull() &&
3080 opener_suppressed_ &&
3081 frame->opener() == NULL &&
3082 // Links with target=_blank will have no name.
3083 frame->name().isNull() &&
3084 // Another frame (with a non-empty creator) should have initiated the
3085 // request, targeted at this frame.
3086 !creator_url_.is_empty() &&
3087 is_content_initiated &&
3088 default_policy == WebKit::WebNavigationPolicyCurrentTab &&
3089 type == WebKit::WebNavigationTypeOther;
3090
3091 if (is_fork || is_noreferrer_and_blank_target) {
[email protected]3d9689372009-09-10 04:29:173092 // Open the URL via the browser, not via WebKit.
3093 OpenURL(url, GURL(), default_policy);
3094 return WebKit::WebNavigationPolicyIgnore;
3095 }
3096
3097 return default_policy;
3098}
3099
[email protected]6069da8c2009-10-20 20:33:493100bool RenderView::canHandleRequest(
3101 WebFrame* frame, const WebURLRequest& request) {
3102 // We allow WebKit to think that everything can be handled even though
3103 // browser-side we limit what we load.
[email protected]7b7a7dc2009-10-19 02:23:343104 return true;
3105}
3106
[email protected]6069da8c2009-10-20 20:33:493107WebURLError RenderView::cannotHandleRequestError(
3108 WebFrame* frame, const WebURLRequest& request) {
3109 NOTREACHED(); // Since we said we can handle all requests.
3110 return WebURLError();
3111}
3112
3113WebURLError RenderView::cancelledError(
3114 WebFrame* frame, const WebURLRequest& request) {
3115 WebURLError error;
3116 error.domain = WebString::fromUTF8(net::kErrorDomain);
3117 error.reason = net::ERR_ABORTED;
3118 error.unreachableURL = request.url();
3119 return error;
[email protected]7b7a7dc2009-10-19 02:23:343120}
3121
3122void RenderView::unableToImplementPolicyWithError(
[email protected]6069da8c2009-10-20 20:33:493123 WebFrame*, const WebURLError&) {
3124 NOTREACHED(); // Since we said we can handle all requests.
[email protected]7b7a7dc2009-10-19 02:23:343125}
3126
[email protected]90eeddb2010-05-06 21:06:433127void RenderView::willSendSubmitEvent(WebKit::WebFrame* frame,
3128 const WebKit::WebFormElement& form) {
3129 // Some login forms have onSubmit handlers that put a hash of the password
3130 // into a hidden field and then clear the password. (Issue 28910.)
3131 // This method gets called before any of those handlers run, so save away
3132 // a copy of the password in case it gets lost.
3133 NavigationState* navigation_state =
3134 NavigationState::FromDataSource(frame->dataSource());
3135 navigation_state->set_password_form_data(
3136 PasswordFormDomManager::CreatePasswordForm(form));
3137}
3138
[email protected]979c28b2009-11-07 01:30:483139void RenderView::willSubmitForm(WebFrame* frame, const WebFormElement& form) {
[email protected]3d9689372009-09-10 04:29:173140 NavigationState* navigation_state =
3141 NavigationState::FromDataSource(frame->provisionalDataSource());
3142
3143 if (navigation_state->transition_type() == PageTransition::LINK)
3144 navigation_state->set_transition_type(PageTransition::FORM_SUBMIT);
3145
3146 // Save these to be processed when the ensuing navigation is committed.
[email protected]ce0e250d2009-10-23 21:00:353147 WebSearchableFormData web_searchable_form_data(form);
3148 navigation_state->set_searchable_form_url(web_searchable_form_data.url());
3149 navigation_state->set_searchable_form_encoding(
[email protected]b7910b3a2010-01-13 18:33:213150 web_searchable_form_data.encoding().utf8());
[email protected]90eeddb2010-05-06 21:06:433151 PasswordForm* password_form_data =
3152 PasswordFormDomManager::CreatePasswordForm(form);
3153 navigation_state->set_password_form_data(password_form_data);
3154
3155 // If the password has been cleared, recover it from the form contents already
3156 // stored by willSendSubmitEvent into the dataSource's NavigationState (as
3157 // opposed to the provisionalDataSource's, which is what we're storing into
3158 // now.)
3159 if (password_form_data && password_form_data->password_value.empty()) {
3160 NavigationState* old_navigation_state =
3161 NavigationState::FromDataSource(frame->dataSource());
3162 if (old_navigation_state) {
3163 PasswordForm* old_form_data = old_navigation_state->password_form_data();
3164 if (old_form_data && old_form_data->action == password_form_data->action)
3165 password_form_data->password_value = old_form_data->password_value;
3166 }
3167 }
[email protected]3d9689372009-09-10 04:29:173168
[email protected]b1438212010-04-03 00:30:593169 FormData form_data;
[email protected]b715f7f2010-04-05 22:01:043170 if (FormManager::WebFormElementToFormData(
[email protected]5af80432010-11-01 01:25:223171 form,
3172 FormManager::REQUIRE_AUTOCOMPLETE,
[email protected]78192082011-01-29 05:43:443173 static_cast<FormManager::ExtractMask>(
3174 FormManager::EXTRACT_VALUE | FormManager::EXTRACT_OPTION_TEXT),
[email protected]5af80432010-11-01 01:25:223175 &form_data)) {
[email protected]19d6e1e82011-01-26 05:08:583176 Send(new AutoFillHostMsg_FormSubmitted(routing_id_, form_data));
[email protected]5af80432010-11-01 01:25:223177 }
[email protected]3d9689372009-09-10 04:29:173178}
3179
3180void RenderView::willPerformClientRedirect(
3181 WebFrame* frame, const WebURL& from, const WebURL& to, double interval,
3182 double fire_time) {
3183 // Ignore
3184}
3185
3186void RenderView::didCancelClientRedirect(WebFrame* frame) {
3187 // Ignore
3188}
3189
3190void RenderView::didCompleteClientRedirect(
3191 WebFrame* frame, const WebURL& from) {
3192 if (!frame->parent())
3193 completed_client_redirect_src_ = from;
3194}
3195
3196void RenderView::didCreateDataSource(WebFrame* frame, WebDataSource* ds) {
[email protected]bb461532010-11-26 21:50:233197 // If there are any app-related fetches in progress, they can be cancelled now
3198 // since we have navigated away from the page that created them.
3199 if (!frame->parent()) {
3200 app_icon_fetchers_.clear();
3201 app_definition_fetcher_.reset(NULL);
3202 }
3203
[email protected]3d9689372009-09-10 04:29:173204 // The rest of RenderView assumes that a WebDataSource will always have a
3205 // non-null NavigationState.
[email protected]a7ccc4d2010-01-27 08:14:483206 bool content_initiated = !pending_navigation_state_.get();
3207 NavigationState* state = content_initiated ?
3208 NavigationState::CreateContentInitiated() :
3209 pending_navigation_state_.release();
[email protected]8a3125a712010-08-09 18:58:513210
[email protected]8a3125a712010-08-09 18:58:513211 // NavigationState::referred_by_prefetcher_ is true if we are
3212 // navigating from a page that used prefetching using a link on that
3213 // page. We are early enough in the request process here that we
3214 // can still see the NavigationState of the previous page and set
3215 // this value appropriately.
3216 // TODO(gavinp): catch the important case of navigation in a new
3217 // renderer process.
3218 if (webview()) {
[email protected]e47aec52010-08-12 00:50:303219 if (WebFrame* old_frame = webview()->mainFrame()) {
[email protected]05c8e502010-08-15 15:13:523220 const WebURLRequest& original_request = ds->originalRequest();
[email protected]8a3125a712010-08-09 18:58:513221 const GURL referrer(
3222 original_request.httpHeaderField(WebString::fromUTF8("Referer")));
3223 if (!referrer.is_empty() &&
3224 NavigationState::FromDataSource(
3225 old_frame->dataSource())->was_prefetcher()) {
3226 for (;old_frame;old_frame = old_frame->traverseNext(false)) {
3227 WebDataSource* old_frame_ds = old_frame->dataSource();
3228 if (old_frame_ds && referrer == GURL(old_frame_ds->request().url())) {
3229 state->set_was_referred_by_prefetcher(true);
3230 break;
3231 }
3232 }
3233 }
3234 }
3235 }
3236
[email protected]4c1b6f0b2010-02-07 16:38:183237 if (content_initiated) {
[email protected]05c8e502010-08-15 15:13:523238 const WebURLRequest& request = ds->request();
[email protected]8a3125a712010-08-09 18:58:513239 switch (request.cachePolicy()) {
[email protected]4c1b6f0b2010-02-07 16:38:183240 case WebURLRequest::UseProtocolCachePolicy: // normal load.
3241 state->set_load_type(NavigationState::LINK_LOAD_NORMAL);
3242 break;
3243 case WebURLRequest::ReloadIgnoringCacheData: // reload.
3244 state->set_load_type(NavigationState::LINK_LOAD_RELOAD);
3245 break;
3246 case WebURLRequest::ReturnCacheDataElseLoad: // allow stale data.
3247 state->set_load_type(NavigationState::LINK_LOAD_CACHE_STALE_OK);
3248 break;
3249 case WebURLRequest::ReturnCacheDataDontLoad: // Don't re-post.
3250 state->set_load_type(NavigationState::LINK_LOAD_CACHE_ONLY);
3251 break;
3252 }
3253 }
[email protected]fa7b6b542009-11-03 05:02:303254
[email protected]5792d932011-01-18 20:33:293255 // If this datasource already has a UserScriptIdleScheduler, reuse that one.
3256 // This is for navigations within a page (didNavigateWithinPage). See
3257 // http://code.google.com/p/chromium/issues/detail?id=64093
3258 NavigationState* old_state = NavigationState::FromDataSource(ds);
3259 if (old_state && old_state->user_script_idle_scheduler()) {
3260 state->swap_user_script_idle_scheduler(old_state);
3261 } else {
3262 state->set_user_script_idle_scheduler(
3263 new UserScriptIdleScheduler(this, frame));
3264 }
[email protected]fa7b6b542009-11-03 05:02:303265 ds->setExtraData(state);
[email protected]3d9689372009-09-10 04:29:173266}
3267
3268void RenderView::didStartProvisionalLoad(WebFrame* frame) {
3269 WebDataSource* ds = frame->provisionalDataSource();
3270 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
3271
[email protected]3d9689372009-09-10 04:29:173272 // Update the request time if WebKit has better knowledge of it.
3273 if (navigation_state->request_time().is_null()) {
3274 double event_time = ds->triggeringEventTime();
3275 if (event_time != 0.0)
3276 navigation_state->set_request_time(Time::FromDoubleT(event_time));
3277 }
3278
[email protected]05c8e502010-08-15 15:13:523279 // Start time is only set after request time.
3280 navigation_state->set_start_load_time(Time::Now());
3281
[email protected]3d9689372009-09-10 04:29:173282 bool is_top_most = !frame->parent();
3283 if (is_top_most) {
3284 navigation_gesture_ = frame->isProcessingUserGesture() ?
[email protected]cd448092010-12-06 23:49:133285 NavigationGestureUser : NavigationGestureAuto;
[email protected]3d9689372009-09-10 04:29:173286
3287 // Make sure redirect tracking state is clear for the new load.
3288 completed_client_redirect_src_ = GURL();
3289 } else if (frame->parent()->isLoading()) {
3290 // Take note of AUTO_SUBFRAME loads here, so that we can know how to
[email protected]4fb66842009-12-04 21:41:003291 // load an error page. See didFailProvisionalLoad.
[email protected]3d9689372009-09-10 04:29:173292 navigation_state->set_transition_type(PageTransition::AUTO_SUBFRAME);
3293 }
3294
3295 Send(new ViewHostMsg_DidStartProvisionalLoadForFrame(
[email protected]dabb0d12010-10-05 12:50:073296 routing_id_, frame->identifier(), is_top_most, ds->request().url()));
[email protected]3d9689372009-09-10 04:29:173297}
3298
3299void RenderView::didReceiveServerRedirectForProvisionalLoad(WebFrame* frame) {
3300 if (frame->parent())
3301 return;
3302 // Received a redirect on the main frame.
3303 WebDataSource* data_source = frame->provisionalDataSource();
3304 if (!data_source) {
3305 // Should only be invoked when we have a data source.
3306 NOTREACHED();
3307 return;
3308 }
3309 std::vector<GURL> redirects;
3310 GetRedirectChain(data_source, &redirects);
3311 if (redirects.size() >= 2) {
[email protected]40bd6582009-12-04 23:49:513312 Send(new ViewHostMsg_DidRedirectProvisionalLoad(routing_id_, page_id_,
3313 redirects[redirects.size() - 2], redirects.back()));
[email protected]3d9689372009-09-10 04:29:173314 }
3315}
3316
[email protected]40bd6582009-12-04 23:49:513317void RenderView::didFailProvisionalLoad(WebFrame* frame,
3318 const WebURLError& error) {
[email protected]3d9689372009-09-10 04:29:173319 // Notify the browser that we failed a provisional load with an error.
3320 //
3321 // Note: It is important this notification occur before DidStopLoading so the
3322 // SSL manager can react to the provisional load failure before being
3323 // notified the load stopped.
3324 //
3325 WebDataSource* ds = frame->provisionalDataSource();
3326 DCHECK(ds);
3327
3328 const WebURLRequest& failed_request = ds->request();
3329
3330 bool show_repost_interstitial =
3331 (error.reason == net::ERR_CACHE_MISS &&
3332 EqualsASCII(failed_request.httpMethod(), "POST"));
3333 Send(new ViewHostMsg_DidFailProvisionalLoadWithError(
[email protected]dabb0d12010-10-05 12:50:073334 routing_id_, frame->identifier(), !frame->parent(), error.reason,
3335 error.unreachableURL, show_repost_interstitial));
[email protected]3d9689372009-09-10 04:29:173336
3337 // Don't display an error page if this is simply a cancelled load. Aside
3338 // from being dumb, WebCore doesn't expect it and it will cause a crash.
3339 if (error.reason == net::ERR_ABORTED)
3340 return;
3341
3342 // Make sure we never show errors in view source mode.
3343 frame->enableViewSourceMode(false);
3344
3345 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
3346
3347 // If this is a failed back/forward/reload navigation, then we need to do a
3348 // 'replace' load. This is necessary to avoid messing up session history.
3349 // Otherwise, we do a normal load, which simulates a 'go' navigation as far
3350 // as session history is concerned.
3351 //
3352 // AUTO_SUBFRAME loads should always be treated as loads that do not advance
3353 // the page id.
3354 //
3355 bool replace =
3356 navigation_state->pending_page_id() != -1 ||
3357 navigation_state->transition_type() == PageTransition::AUTO_SUBFRAME;
3358
3359 // If we failed on a browser initiated request, then make sure that our error
3360 // page load is regarded as the same browser initiated request.
3361 if (!navigation_state->is_content_initiated()) {
3362 pending_navigation_state_.reset(NavigationState::CreateBrowserInitiated(
3363 navigation_state->pending_page_id(),
[email protected]3cc72b12010-03-18 23:03:003364 navigation_state->pending_history_list_offset(),
[email protected]3d9689372009-09-10 04:29:173365 navigation_state->transition_type(),
3366 navigation_state->request_time()));
3367 }
3368
3369 // Provide the user with a more helpful error page?
3370 if (MaybeLoadAlternateErrorPage(frame, error, replace))
3371 return;
3372
3373 // Fallback to a local error page.
[email protected]3f853a52010-09-13 19:15:083374 LoadNavigationErrorPage(frame, failed_request, error, std::string(), replace);
[email protected]3d9689372009-09-10 04:29:173375}
3376
3377void RenderView::didReceiveDocumentData(
3378 WebFrame* frame, const char* data, size_t data_len,
3379 bool& prevent_default) {
3380 NavigationState* navigation_state =
3381 NavigationState::FromDataSource(frame->dataSource());
3382 if (!navigation_state->postpone_loading_data())
3383 return;
3384
3385 // We're going to call commitDocumentData ourselves...
3386 prevent_default = true;
3387
[email protected]3f853a52010-09-13 19:15:083388 // Continue buffering the response data for the original error page. If it
3389 // grows too large, then we'll just let it through. For any error other than
3390 // a 404, "too large" means any data at all.
[email protected]3d9689372009-09-10 04:29:173391 navigation_state->append_postponed_data(data, data_len);
[email protected]3f853a52010-09-13 19:15:083392 if (navigation_state->postponed_data().size() >= 512 ||
3393 navigation_state->http_status_code() != 404) {
[email protected]3d9689372009-09-10 04:29:173394 navigation_state->set_postpone_loading_data(false);
3395 frame->commitDocumentData(navigation_state->postponed_data().data(),
3396 navigation_state->postponed_data().size());
3397 navigation_state->clear_postponed_data();
3398 }
3399}
3400
[email protected]40bd6582009-12-04 23:49:513401void RenderView::didCommitProvisionalLoad(WebFrame* frame,
3402 bool is_new_navigation) {
[email protected]3d9689372009-09-10 04:29:173403 NavigationState* navigation_state =
3404 NavigationState::FromDataSource(frame->dataSource());
3405
3406 navigation_state->set_commit_load_time(Time::Now());
3407 if (is_new_navigation) {
[email protected]e15f680732010-11-23 22:30:203408 // When we perform a new navigation, we need to update the last committed
3409 // session history entry with state for the page we are leaving.
[email protected]3d9689372009-09-10 04:29:173410 UpdateSessionHistory(frame);
3411
3412 // We bump our Page ID to correspond with the new session history entry.
3413 page_id_ = next_page_id_++;
3414
[email protected]3ead1322010-11-19 20:01:003415 // Let the phishing classifier decide whether to cancel classification.
3416 if (phishing_delegate_.get())
3417 phishing_delegate_->CommittedLoadInFrame(frame);
3418
[email protected]3cc72b12010-03-18 23:03:003419 // Advance our offset in session history, applying the length limit. There
3420 // is now no forward history.
3421 history_list_offset_++;
3422 if (history_list_offset_ >= chrome::kMaxSessionHistoryEntries)
3423 history_list_offset_ = chrome::kMaxSessionHistoryEntries - 1;
3424 history_list_length_ = history_list_offset_ + 1;
3425
[email protected]f9f4841b2010-03-20 05:41:423426 MessageLoop::current()->PostDelayedTask(
3427 FROM_HERE,
[email protected]e47aec52010-08-12 00:50:303428 page_info_method_factory_.NewRunnableMethod(
3429 &RenderView::CapturePageInfo, page_id_, true),
[email protected]3d9689372009-09-10 04:29:173430 kDelayForForcedCaptureMs);
3431 } else {
3432 // Inspect the navigation_state on this frame to see if the navigation
3433 // corresponds to a session history navigation... Note: |frame| may or
3434 // may not be the toplevel frame, but for the case of capturing session
3435 // history, the first committed frame suffices. We keep track of whether
3436 // we've seen this commit before so that only capture session history once
3437 // per navigation.
3438 //
3439 // Note that we need to check if the page ID changed. In the case of a
3440 // reload, the page ID doesn't change, and UpdateSessionHistory gets the
3441 // previous URL and the current page ID, which would be wrong.
3442 if (navigation_state->pending_page_id() != -1 &&
3443 navigation_state->pending_page_id() != page_id_ &&
3444 !navigation_state->request_committed()) {
3445 // This is a successful session history navigation!
3446 UpdateSessionHistory(frame);
3447 page_id_ = navigation_state->pending_page_id();
[email protected]3cc72b12010-03-18 23:03:003448
3449 history_list_offset_ = navigation_state->pending_history_list_offset();
[email protected]3d9689372009-09-10 04:29:173450 }
3451 }
3452
3453 // Remember that we've already processed this request, so we don't update
3454 // the session history again. We do this regardless of whether this is
3455 // a session history navigation, because if we attempted a session history
3456 // navigation without valid HistoryItem state, WebCore will think it is a
3457 // new navigation.
3458 navigation_state->set_request_committed(true);
3459
3460 UpdateURL(frame);
3461
3462 // If this committed load was initiated by a client redirect, we're
3463 // at the last stop now, so clear it.
3464 completed_client_redirect_src_ = GURL();
3465
3466 // Check whether we have new encoding name.
[email protected]26aa0482009-09-30 16:55:273467 UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
[email protected]3d9689372009-09-10 04:29:173468}
3469
3470void RenderView::didClearWindowObject(WebFrame* frame) {
3471 if (BindingsPolicy::is_dom_automation_enabled(enabled_bindings_))
3472 BindDOMAutomationController(frame);
[email protected]0d7ae862010-10-01 13:52:453473 GURL frame_url = frame->url();
3474 if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_) &&
[email protected]bfa83eb82010-10-06 08:41:253475 (frame_url.SchemeIs(chrome::kChromeUIScheme) ||
[email protected]731ae512010-10-15 18:20:173476 frame_url.SchemeIs(chrome::kGearsScheme) ||
[email protected]bfa83eb82010-10-06 08:41:253477 frame_url.SchemeIs(chrome::kDataScheme))) {
[email protected]c50008512011-02-03 01:17:273478 GetWebUIBindings()->set_message_sender(this);
3479 GetWebUIBindings()->set_routing_id(routing_id_);
3480 GetWebUIBindings()->BindToJavascript(frame, "chrome");
[email protected]3d9689372009-09-10 04:29:173481 }
3482 if (BindingsPolicy::is_external_host_enabled(enabled_bindings_)) {
[email protected]c091c2c2010-09-17 19:05:463483 GetExternalHostBindings()->set_message_sender(this);
3484 GetExternalHostBindings()->set_routing_id(routing_id_);
[email protected]906690b2010-12-03 18:11:253485 GetExternalHostBindings()->BindToJavascript(frame, "externalHost");
[email protected]3d9689372009-09-10 04:29:173486 }
3487}
3488
3489void RenderView::didCreateDocumentElement(WebFrame* frame) {
3490 if (RenderThread::current()) { // Will be NULL during unit tests.
3491 RenderThread::current()->user_script_slave()->InjectScripts(
3492 frame, UserScript::DOCUMENT_START);
3493 }
3494
3495 // Notify the browser about non-blank documents loading in the top frame.
3496 GURL url = frame->url();
[email protected]e0d481582009-09-15 21:06:253497 if (url.is_valid() && url.spec() != chrome::kAboutBlankURL) {
[email protected]26aa0482009-09-30 16:55:273498 if (frame == webview()->mainFrame())
[email protected]3d9689372009-09-10 04:29:173499 Send(new ViewHostMsg_DocumentAvailableInMainFrame(routing_id_));
3500 }
3501}
3502
3503void RenderView::didReceiveTitle(WebFrame* frame, const WebString& title) {
3504 UpdateTitle(frame, title);
3505
3506 // Also check whether we have new encoding name.
[email protected]26aa0482009-09-30 16:55:273507 UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
[email protected]3d9689372009-09-10 04:29:173508}
3509
[email protected]5019ef12010-04-27 17:26:583510void RenderView::didChangeIcons(WebFrame* frame) {
3511 if (!frame->parent()) {
3512 Send(new ViewHostMsg_UpdateFavIconURL(
3513 routing_id_,
3514 page_id_,
3515 frame->favIconURL()));
3516 }
3517}
3518
[email protected]3d9689372009-09-10 04:29:173519void RenderView::didFinishDocumentLoad(WebFrame* frame) {
3520 WebDataSource* ds = frame->dataSource();
3521 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
3522 DCHECK(navigation_state);
3523 navigation_state->set_finish_document_load_time(Time::Now());
3524
[email protected]622474d2010-11-04 09:21:083525 Send(new ViewHostMsg_DocumentLoadedInFrame(routing_id_, frame->identifier()));
[email protected]3d9689372009-09-10 04:29:173526
[email protected]676126f72011-01-15 00:03:513527 FOR_EACH_OBSERVER(
3528 RenderViewObserver, observers_, DidFinishDocumentLoad(frame));
[email protected]3d9689372009-09-10 04:29:173529
3530 // Check whether we have new encoding name.
[email protected]26aa0482009-09-30 16:55:273531 UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
[email protected]3d9689372009-09-10 04:29:173532
3533 if (RenderThread::current()) { // Will be NULL during unit tests.
3534 RenderThread::current()->user_script_slave()->InjectScripts(
3535 frame, UserScript::DOCUMENT_END);
3536 }
[email protected]fa7b6b542009-11-03 05:02:303537
[email protected]41f16632010-10-20 01:21:323538 // InjectScripts() can end up creating a new NavigationState if it triggers a
3539 // fragment navigation, so we need to re-fetch it here.
3540 navigation_state = NavigationState::FromDataSource(ds);
[email protected]fa7b6b542009-11-03 05:02:303541 navigation_state->user_script_idle_scheduler()->DidFinishDocumentLoad();
3542}
3543
3544void RenderView::OnUserScriptIdleTriggered(WebFrame* frame) {
3545 if (RenderThread::current()) { // Will be NULL during unit tests.
3546 RenderThread::current()->user_script_slave()->InjectScripts(
3547 frame, UserScript::DOCUMENT_IDLE);
3548 }
3549
3550 WebFrame* main_frame = webview()->mainFrame();
3551 if (frame == main_frame) {
3552 while (!pending_code_execution_queue_.empty()) {
[email protected]61f5a7b2009-12-22 22:21:203553 linked_ptr<ViewMsg_ExecuteCode_Params>& params =
[email protected]fa7b6b542009-11-03 05:02:303554 pending_code_execution_queue_.front();
[email protected]61f5a7b2009-12-22 22:21:203555 ExecuteCodeImpl(main_frame, *params);
[email protected]fa7b6b542009-11-03 05:02:303556 pending_code_execution_queue_.pop();
3557 }
3558 }
[email protected]3d9689372009-09-10 04:29:173559}
3560
3561void RenderView::didHandleOnloadEvents(WebFrame* frame) {
[email protected]25497492010-09-11 15:15:083562 if (webview()->mainFrame() == frame) {
3563 Send(new ViewHostMsg_DocumentOnLoadCompletedInMainFrame(routing_id_,
3564 page_id_));
3565 }
[email protected]3d9689372009-09-10 04:29:173566}
3567
3568void RenderView::didFailLoad(WebFrame* frame, const WebURLError& error) {
3569 // Ignore
3570}
3571
3572void RenderView::didFinishLoad(WebFrame* frame) {
3573 WebDataSource* ds = frame->dataSource();
3574 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
3575 DCHECK(navigation_state);
3576 navigation_state->set_finish_load_time(Time::Now());
[email protected]fa7b6b542009-11-03 05:02:303577 navigation_state->user_script_idle_scheduler()->DidFinishLoad();
[email protected]4d44a1c2010-04-28 19:20:413578
[email protected]676126f72011-01-15 00:03:513579 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidFinishLoad(frame));
[email protected]fdd94a02010-11-05 08:07:173580
3581 Send(new ViewHostMsg_DidFinishLoad(routing_id_, frame->identifier()));
[email protected]3d9689372009-09-10 04:29:173582}
3583
[email protected]ccbe04e2010-03-17 17:58:433584void RenderView::didNavigateWithinPage(
[email protected]3d9689372009-09-10 04:29:173585 WebFrame* frame, bool is_new_navigation) {
3586 // If this was a reference fragment navigation that we initiated, then we
3587 // could end up having a non-null pending navigation state. We just need to
3588 // update the ExtraData on the datasource so that others who read the
3589 // ExtraData will get the new NavigationState. Similarly, if we did not
3590 // initiate this navigation, then we need to take care to reset any pre-
3591 // existing navigation state to a content-initiated navigation state.
3592 // DidCreateDataSource conveniently takes care of this for us.
3593 didCreateDataSource(frame, frame->dataSource());
3594
[email protected]af15bed2010-08-25 21:12:093595 NavigationState* new_state =
3596 NavigationState::FromDataSource(frame->dataSource());
3597 new_state->set_was_within_same_page(true);
3598
[email protected]3d9689372009-09-10 04:29:173599 didCommitProvisionalLoad(frame, is_new_navigation);
3600
[email protected]26aa0482009-09-30 16:55:273601 UpdateTitle(frame, frame->view()->mainFrame()->dataSource()->pageTitle());
[email protected]3d9689372009-09-10 04:29:173602}
3603
[email protected]476b6f82009-09-10 21:00:593604void RenderView::didUpdateCurrentHistoryItem(WebFrame* frame) {
[email protected]882daa92009-11-05 16:31:313605 StartNavStateSyncTimerIfNecessary();
[email protected]476b6f82009-09-10 21:00:593606}
3607
[email protected]3d9689372009-09-10 04:29:173608void RenderView::assignIdentifierToRequest(
3609 WebFrame* frame, unsigned identifier, const WebURLRequest& request) {
3610 // Ignore
3611}
3612
3613void RenderView::willSendRequest(
3614 WebFrame* frame, unsigned identifier, WebURLRequest& request,
3615 const WebURLResponse& redirect_response) {
[email protected]5e369672009-11-03 23:48:303616 WebFrame* top_frame = frame->top();
3617 if (!top_frame)
3618 top_frame = frame;
[email protected]8a3125a712010-08-09 18:58:513619 WebDataSource* provisional_data_source = top_frame->provisionalDataSource();
3620 WebDataSource* top_data_source = top_frame->dataSource();
3621 WebDataSource* data_source =
3622 provisional_data_source ? provisional_data_source : top_data_source;
[email protected]78d5cfe2011-02-04 08:43:223623
3624 // If the request is for an extension resource, check whether it should be
3625 // allowed. If not allowed, we reset the URL to something invalid to prevent
3626 // the request and cause an error.
3627 GURL request_url(request.url());
3628 if (request_url.SchemeIs(chrome::kExtensionScheme) &&
3629 !ExtensionResourceRequestPolicy::CanRequestResource(
3630 request_url,
3631 GURL(frame->url()),
3632 render_thread_->GetExtensions())) {
3633 request.setURL(WebURL(GURL("chrome-extension://invalid/")));
3634 }
3635
[email protected]5e369672009-11-03 23:48:303636 if (data_source) {
3637 NavigationState* state = NavigationState::FromDataSource(data_source);
3638 if (state && state->is_cache_policy_override_set())
3639 request.setCachePolicy(state->cache_policy_override());
3640 }
[email protected]8a3125a712010-08-09 18:58:513641
3642 if (top_data_source) {
3643 NavigationState* state = NavigationState::FromDataSource(top_data_source);
3644 if (state && request.targetType() == WebURLRequest::TargetIsPrefetch)
3645 state->set_was_prefetcher(true);
3646 }
3647
[email protected]3d9689372009-09-10 04:29:173648 request.setRequestorID(routing_id_);
[email protected]cd448092010-12-06 23:49:133649 request.setHasUserGesture(frame->isProcessingUserGesture());
3650
[email protected]c5bbc2452010-03-08 08:33:503651 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoReferrers))
[email protected]7deade42010-03-05 09:33:133652 request.clearHTTPHeaderField("Referer");
[email protected]fa0a3432010-03-30 16:53:493653
[email protected]85cc78c2010-05-04 18:30:093654 // Temporary metrics, see site_isolation_metrics.h
3655 SiteIsolationMetrics::AddRequest(identifier, request.targetType());
[email protected]3d9689372009-09-10 04:29:173656}
3657
3658void RenderView::didReceiveResponse(
3659 WebFrame* frame, unsigned identifier, const WebURLResponse& response) {
[email protected]fa0a3432010-03-30 16:53:493660
[email protected]85cc78c2010-05-04 18:30:093661 // Temporary metrics, see site_isolation_metrics.h
3662 SiteIsolationMetrics::LogMimeTypeForCrossOriginRequest(frame,
3663 identifier,
3664 response);
[email protected]fa0a3432010-03-30 16:53:493665
[email protected]3d9689372009-09-10 04:29:173666 // Only do this for responses that correspond to a provisional data source
3667 // of the top-most frame. If we have a provisional data source, then we
3668 // can't have any sub-resources yet, so we know that this response must
3669 // correspond to a frame load.
3670 if (!frame->provisionalDataSource() || frame->parent())
3671 return;
3672
3673 // If we are in view source mode, then just let the user see the source of
[email protected]3f853a52010-09-13 19:15:083674 // the server's error page.
[email protected]3d9689372009-09-10 04:29:173675 if (frame->isViewSourceModeEnabled())
3676 return;
3677
[email protected]65041fa2010-05-21 06:56:533678 NavigationState* navigation_state =
3679 NavigationState::FromDataSource(frame->provisionalDataSource());
3680 CHECK(navigation_state);
[email protected]3f853a52010-09-13 19:15:083681 int http_status_code = response.httpStatusCode();
[email protected]65041fa2010-05-21 06:56:533682
[email protected]972ebdff2010-06-10 22:59:073683 // Record page load flags.
3684 navigation_state->set_was_fetched_via_spdy(response.wasFetchedViaSPDY());
3685 navigation_state->set_was_npn_negotiated(response.wasNpnNegotiated());
[email protected]193b0b892010-06-26 03:57:573686 navigation_state->set_was_alternate_protocol_available(
3687 response.wasAlternateProtocolAvailable());
[email protected]972ebdff2010-06-10 22:59:073688 navigation_state->set_was_fetched_via_proxy(response.wasFetchedViaProxy());
[email protected]3f853a52010-09-13 19:15:083689 navigation_state->set_http_status_code(http_status_code);
[email protected]65041fa2010-05-21 06:56:533690
[email protected]f48013be2010-01-14 22:07:453691 // Consider loading an alternate error page for 404 responses.
[email protected]3f853a52010-09-13 19:15:083692 if (http_status_code == 404) {
3693 // Can we even load an alternate error page for this URL?
3694 if (!GetAlternateErrorPageURL(response.url(), HTTP_404).is_valid())
3695 return;
3696 } else if (!LocalizedError::HasStrings(LocalizedError::kHttpErrorDomain,
3697 http_status_code)) {
3698 // If no corresponding error strings for a particular status code, just
3699 // render any received data, regardless of whether or not the status code
3700 // indicates an error.
[email protected]f48013be2010-01-14 22:07:453701 return;
[email protected]3f853a52010-09-13 19:15:083702 }
[email protected]3d9689372009-09-10 04:29:173703
[email protected]3d9689372009-09-10 04:29:173704 navigation_state->set_postpone_loading_data(true);
3705 navigation_state->clear_postponed_data();
3706}
3707
3708void RenderView::didFinishResourceLoad(
3709 WebFrame* frame, unsigned identifier) {
3710 NavigationState* navigation_state =
3711 NavigationState::FromDataSource(frame->dataSource());
3712 if (!navigation_state->postpone_loading_data())
3713 return;
3714
[email protected]3f853a52010-09-13 19:15:083715 // The server returned an error and the content was < 512 bytes (which we
[email protected]3d9689372009-09-10 04:29:173716 // suppressed). Go ahead and fetch the alternate page content.
[email protected]3f853a52010-09-13 19:15:083717 int http_status_code = navigation_state->http_status_code();
3718 if (http_status_code == 404) {
3719 // On 404s, try a remote search page as a fallback.
3720 const GURL& frame_url = frame->url();
[email protected]3d9689372009-09-10 04:29:173721
[email protected]3f853a52010-09-13 19:15:083722 const GURL& error_page_url = GetAlternateErrorPageURL(frame_url, HTTP_404);
3723 DCHECK(error_page_url.is_valid());
[email protected]3d9689372009-09-10 04:29:173724
[email protected]3f853a52010-09-13 19:15:083725 WebURLError original_error;
3726 original_error.unreachableURL = frame_url;
[email protected]3d9689372009-09-10 04:29:173727
[email protected]3f853a52010-09-13 19:15:083728 navigation_state->set_alt_error_page_fetcher(
3729 new AltErrorPageResourceFetcher(
3730 error_page_url, frame, original_error,
3731 NewCallback(this, &RenderView::AltErrorPageFinished)));
3732 } else {
3733 // On other errors, use an internal error page.
3734 WebURLError error;
3735 error.unreachableURL = frame->url();
3736 error.domain = WebString::fromUTF8(LocalizedError::kHttpErrorDomain);
3737 error.reason = http_status_code;
[email protected]3d9689372009-09-10 04:29:173738
[email protected]3f853a52010-09-13 19:15:083739 LoadNavigationErrorPage(frame, frame->dataSource()->request(), error,
3740 std::string(), true);
3741 }
[email protected]3d9689372009-09-10 04:29:173742}
3743
3744void RenderView::didFailResourceLoad(
3745 WebFrame* frame, unsigned identifier, const WebURLError& error) {
3746 // Ignore
3747}
3748
3749void RenderView::didLoadResourceFromMemoryCache(
3750 WebFrame* frame, const WebURLRequest& request,
3751 const WebURLResponse& response) {
3752 // Let the browser know we loaded a resource from the memory cache. This
3753 // message is needed to display the correct SSL indicators.
3754 Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(
3755 routing_id_,
3756 request.url(),
[email protected]91733b62009-09-18 06:21:093757 frame->securityOrigin().toString().utf8(),
3758 frame->top()->securityOrigin().toString().utf8(),
[email protected]3d9689372009-09-10 04:29:173759 response.securityInfo()));
3760}
3761
[email protected]6069da8c2009-10-20 20:33:493762void RenderView::didDisplayInsecureContent(WebFrame* frame) {
[email protected]e3d60e5d2009-09-25 21:08:293763 Send(new ViewHostMsg_DidDisplayInsecureContent(routing_id_));
3764}
3765
[email protected]92771112011-01-20 00:13:023766// We have two didRunInsecureContent's with the same name. That's because
3767// we're in the process of adding an argument and one of them will be correct.
3768// Once the WebKit change is in, the first should be removed.
[email protected]e3d60e5d2009-09-25 21:08:293769void RenderView::didRunInsecureContent(
3770 WebFrame* frame, const WebSecurityOrigin& origin) {
[email protected]92771112011-01-20 00:13:023771 didRunInsecureContent(frame, origin, GURL());
3772}
3773
3774void RenderView::didRunInsecureContent(
3775 WebFrame* frame, const WebSecurityOrigin& origin, const WebURL& target) {
[email protected]e3d60e5d2009-09-25 21:08:293776 Send(new ViewHostMsg_DidRunInsecureContent(
3777 routing_id_,
[email protected]92771112011-01-20 00:13:023778 origin.toString().utf8(),
3779 target));
[email protected]e3d60e5d2009-09-25 21:08:293780}
3781
[email protected]7ea093ba2009-11-03 05:54:593782bool RenderView::allowScript(WebFrame* frame, bool enabled_per_settings) {
[email protected]12bc8472010-04-15 07:29:403783 if (enabled_per_settings &&
3784 AllowContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT))
3785 return true;
[email protected]7ea093ba2009-11-03 05:54:593786
[email protected]12bc8472010-04-15 07:29:403787 if (IsWhitelistedForContentSettings(frame))
3788 return true;
[email protected]7ea093ba2009-11-03 05:54:593789
3790 return false; // Other protocols fall through here.
3791}
3792
[email protected]0a1a45432010-03-31 08:09:453793bool RenderView::allowDatabase(
3794 WebFrame* frame, const WebString& name, const WebString& display_name,
3795 unsigned long estimated_size) {
3796 WebSecurityOrigin origin = frame->securityOrigin();
3797 if (origin.isEmpty())
3798 return false; // Uninitialized document?
3799
3800 bool result;
[email protected]26a9acf2010-12-13 19:35:053801 if (!Send(new DatabaseHostMsg_Allow(routing_id_,
[email protected]0a1a45432010-03-31 08:09:453802 origin.toString().utf8(), name, display_name, estimated_size, &result)))
3803 return false;
[email protected]9fb83e82010-07-02 18:24:553804 Send(new ViewHostMsg_WebDatabaseAccessed(routing_id_,
3805 GURL(origin.toString().utf8()),
3806 name,
3807 display_name,
3808 estimated_size,
3809 !result));
[email protected]0a1a45432010-03-31 08:09:453810 return result;
3811}
[email protected]8934a3b2010-02-25 00:34:003812void RenderView::didNotAllowScript(WebKit::WebFrame* frame) {
[email protected]55126132010-08-19 14:53:283813 DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string());
[email protected]8934a3b2010-02-25 00:34:003814}
3815
[email protected]c21f1d52010-03-04 03:19:433816void RenderView::didNotAllowPlugins(WebKit::WebFrame* frame) {
[email protected]55126132010-08-19 14:53:283817 DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, std::string());
[email protected]c21f1d52010-03-04 03:19:433818}
3819
[email protected]3d9689372009-09-10 04:29:173820void RenderView::didExhaustMemoryAvailableForScript(WebFrame* frame) {
3821 Send(new ViewHostMsg_JSOutOfMemory(routing_id_));
3822}
3823
[email protected]0c882b282009-10-07 17:01:283824void RenderView::didCreateScriptContext(WebFrame* frame) {
3825 EventBindings::HandleContextCreated(frame, false);
3826}
3827
3828void RenderView::didDestroyScriptContext(WebFrame* frame) {
3829 EventBindings::HandleContextDestroyed(frame);
3830}
3831
3832void RenderView::didCreateIsolatedScriptContext(WebFrame* frame) {
3833 EventBindings::HandleContextCreated(frame, true);
3834}
3835
[email protected]af7eb3fb2010-09-23 21:31:063836bool RenderView::allowScriptExtension(WebFrame* frame,
3837 const WebString& extension_name,
3838 int extension_group) {
3839 // NULL in unit tests.
3840 if (!RenderThread::current())
3841 return true;
3842
3843 // Note: we prefer the provisional URL here instead of the document URL
3844 // because we might be currently loading an URL into a blank page.
3845 // See http://code.google.com/p/chromium/issues/detail?id=10924
3846 WebDataSource* ds = frame->provisionalDataSource();
3847 if (!ds)
3848 ds = frame->dataSource();
3849 return RenderThread::current()->AllowScriptExtension(
3850 extension_name.utf8(), ds->request().url(), extension_group);
3851}
3852
[email protected]fc86daa2010-03-30 23:52:533853void RenderView::logCrossFramePropertyAccess(WebFrame* frame,
3854 WebFrame* target,
3855 bool cross_origin,
3856 const WebString& property_name,
3857 unsigned long long event_id) {
[email protected]ab9eabac2010-03-16 16:54:103858 // TODO(johnnyg): track the individual properties and repeat event_ids.
[email protected]a5a65ac2010-11-05 18:14:363859 page_load_histograms_.IncrementCrossFramePropertyAccess(cross_origin);
[email protected]ab9eabac2010-03-16 16:54:103860}
3861
[email protected]3d9689372009-09-10 04:29:173862void RenderView::didChangeContentsSize(WebFrame* frame, const WebSize& size) {
[email protected]d8a179c2010-01-31 00:58:143863 CheckPreferredSize();
3864}
3865
3866void RenderView::CheckPreferredSize() {
[email protected]3d9689372009-09-10 04:29:173867 // We don't always want to send the change messages over IPC, only if we've
[email protected]ab32b16c2009-10-16 14:57:253868 // be put in that mode by getting a |ViewMsg_EnablePreferredSizeChangedMode|
[email protected]3d9689372009-09-10 04:29:173869 // message.
[email protected]705243f2010-05-05 19:58:073870 if (!send_preferred_size_changes_ || !webview())
3871 return;
[email protected]dfca5acf2010-03-22 03:28:433872
[email protected]705243f2010-05-05 19:58:073873 // WebCore likes to tell us things have changed even when they haven't, so
3874 // cache the width and height and only send the IPC message when we're sure
3875 // they're different.
3876 gfx::Size size(webview()->mainFrame()->contentsPreferredWidth(),
3877 webview()->mainFrame()->documentElementScrollHeight());
[email protected]8205d742010-10-22 23:51:533878
3879 // In the presence of zoom, these sizes are still reported as if unzoomed,
3880 // so we need to adjust.
3881 double zoom_factor = WebView::zoomLevelToZoomFactor(webview()->zoomLevel());
3882 size.set_width(static_cast<int>(size.width() * zoom_factor));
3883 size.set_height(static_cast<int>(size.height() * zoom_factor));
3884
[email protected]705243f2010-05-05 19:58:073885 if (size == preferred_size_)
3886 return;
[email protected]c27324b2009-11-19 22:44:293887
[email protected]705243f2010-05-05 19:58:073888 preferred_size_ = size;
3889 Send(new ViewHostMsg_DidContentsPreferredSizeChange(routing_id_,
3890 preferred_size_));
[email protected]3d9689372009-09-10 04:29:173891}
3892
[email protected]143dcd592009-11-06 21:33:493893void RenderView::didChangeScrollOffset(WebFrame* frame) {
3894 StartNavStateSyncTimerIfNecessary();
3895}
3896
[email protected]8922e1f2009-10-03 05:01:263897void RenderView::reportFindInPageMatchCount(int request_id, int count,
3898 bool final_update) {
[email protected]e7c58a32010-08-13 19:47:113899 int active_match_ordinal = -1; // -1 = don't update active match ordinal
3900 if (!count)
3901 active_match_ordinal = 0;
3902
3903 IPC::Message* msg = new ViewHostMsg_Find_Reply(
3904 routing_id_,
3905 request_id,
3906 count,
3907 gfx::Rect(),
3908 active_match_ordinal,
3909 final_update);
3910
[email protected]8922e1f2009-10-03 05:01:263911 // If we have a message that has been queued up, then we should just replace
3912 // it. The ACK from the browser will make sure it gets sent when the browser
3913 // wants it.
3914 if (queued_find_reply_message_.get()) {
[email protected]8922e1f2009-10-03 05:01:263915 queued_find_reply_message_.reset(msg);
3916 } else {
3917 // Send the search result over to the browser process.
[email protected]e7c58a32010-08-13 19:47:113918 Send(msg);
[email protected]8922e1f2009-10-03 05:01:263919 }
3920}
3921
3922void RenderView::reportFindInPageSelection(int request_id,
3923 int active_match_ordinal,
3924 const WebRect& selection_rect) {
3925 // Send the search result over to the browser process.
3926 Send(new ViewHostMsg_Find_Reply(routing_id_,
3927 request_id,
3928 -1,
3929 selection_rect,
3930 active_match_ordinal,
3931 false));
3932}
3933
[email protected]2b06a992010-08-21 05:48:223934void RenderView::openFileSystem(
3935 WebFrame* frame,
3936 WebFileSystem::Type type,
3937 long long size,
[email protected]d275d7a2010-11-03 01:34:493938 bool create,
[email protected]2b06a992010-08-21 05:48:223939 WebFileSystemCallbacks* callbacks) {
[email protected]c5a272d2010-09-27 18:37:083940 DCHECK(callbacks);
[email protected]2b06a992010-08-21 05:48:223941
3942 WebSecurityOrigin origin = frame->securityOrigin();
[email protected]c5a272d2010-09-27 18:37:083943 if (origin.isEmpty()) {
3944 // Uninitialized document?
3945 callbacks->didFail(WebKit::WebFileErrorAbort);
3946 return;
3947 }
[email protected]2b06a992010-08-21 05:48:223948
[email protected]c5a272d2010-09-27 18:37:083949 ChildThread::current()->file_system_dispatcher()->OpenFileSystem(
3950 GURL(origin.toString()), static_cast<fileapi::FileSystemType>(type),
[email protected]d275d7a2010-11-03 01:34:493951 size, create, new WebFileSystemCallbackDispatcher(callbacks));
[email protected]2b06a992010-08-21 05:48:223952}
3953
[email protected]79dbc662009-09-04 05:42:513954// webkit_glue::WebPluginPageDelegate -----------------------------------------
3955
[email protected]191eb3f72010-12-21 06:27:503956webkit::npapi::WebPluginDelegate* RenderView::CreatePluginDelegate(
[email protected]4e0616e2010-05-28 14:55:533957 const FilePath& file_path,
3958 const std::string& mime_type) {
[email protected]f103ab72009-09-02 17:10:593959 if (!PluginChannelHost::IsListening())
3960 return NULL;
3961
[email protected]d2139662009-12-10 03:21:143962 bool use_pepper_host = false;
[email protected]00c39612010-03-06 02:53:283963 bool in_process_plugin = RenderProcess::current()->UseInProcessPlugins();
[email protected]d2139662009-12-10 03:21:143964 // Check for trusted Pepper plugins.
[email protected]26e8d5e2009-10-13 02:47:163965 const char kPepperPrefix[] = "pepper-";
[email protected]4e0616e2010-05-28 14:55:533966 if (StartsWithASCII(mime_type, kPepperPrefix, true)) {
[email protected]d2139662009-12-10 03:21:143967 if (CommandLine::ForCurrentProcess()->
3968 HasSwitch(switches::kInternalPepper)) {
3969 in_process_plugin = true;
3970 use_pepper_host = true;
3971 } else {
3972 // In process Pepper plugins must be explicitly enabled.
3973 return NULL;
3974 }
[email protected]4e0616e2010-05-28 14:55:533975 } else {
3976 FilePath internal_pdf_path;
3977 PathService::Get(chrome::FILE_PDF_PLUGIN, &internal_pdf_path);
3978 if (file_path == internal_pdf_path) {
3979 in_process_plugin = true;
3980 use_pepper_host = true;
3981 }
[email protected]26e8d5e2009-10-13 02:47:163982 }
[email protected]4e0616e2010-05-28 14:55:533983
[email protected]d032f492009-09-29 00:33:463984 if (in_process_plugin) {
[email protected]d2139662009-12-10 03:21:143985 if (use_pepper_host) {
[email protected]00c39612010-03-06 02:53:283986 WebPluginDelegatePepper* pepper_plugin =
[email protected]4e0616e2010-05-28 14:55:533987 WebPluginDelegatePepper::Create(file_path, mime_type, AsWeakPtr());
[email protected]b7d7ed52010-07-20 00:12:333988 if (!pepper_plugin)
3989 return NULL;
3990
[email protected]53900d52010-06-16 04:25:013991 current_oldstyle_pepper_plugins_.insert(pepper_plugin);
[email protected]00c39612010-03-06 02:53:283992 return pepper_plugin;
[email protected]d2139662009-12-10 03:21:143993 } else {
[email protected]6876dff2010-01-15 19:38:093994#if defined(OS_WIN) // In-proc plugins aren't supported on Linux or Mac.
[email protected]191eb3f72010-12-21 06:27:503995 return webkit::npapi::WebPluginDelegateImpl::Create(
[email protected]4e0616e2010-05-28 14:55:533996 file_path, mime_type, gfx::NativeViewFromId(host_window_));
[email protected]6876dff2010-01-15 19:38:093997#else
[email protected]596b2c42010-01-14 20:40:433998 NOTIMPLEMENTED();
3999 return NULL;
[email protected]7b6616f2010-01-14 18:07:554000#endif
[email protected]6876dff2010-01-15 19:38:094001 }
[email protected]f103ab72009-09-02 17:10:594002 }
4003
[email protected]4e0616e2010-05-28 14:55:534004 return new WebPluginDelegateProxy(mime_type, AsWeakPtr());
[email protected]f103ab72009-09-02 17:10:594005}
4006
4007void RenderView::CreatedPluginWindow(gfx::PluginWindowHandle window) {
[email protected]6981f7f2010-03-09 00:53:034008#if defined(USE_X11)
[email protected]f103ab72009-09-02 17:10:594009 RenderThread::current()->Send(new ViewHostMsg_CreatePluginContainer(
4010 routing_id(), window));
4011#endif
4012}
4013
4014void RenderView::WillDestroyPluginWindow(gfx::PluginWindowHandle window) {
[email protected]6981f7f2010-03-09 00:53:034015#if defined(USE_X11)
[email protected]f103ab72009-09-02 17:10:594016 RenderThread::current()->Send(new ViewHostMsg_DestroyPluginContainer(
4017 routing_id(), window));
4018#endif
4019 CleanupWindowInPluginMoves(window);
4020}
4021
[email protected]191eb3f72010-12-21 06:27:504022void RenderView::DidMovePlugin(const webkit::npapi::WebPluginGeometry& move) {
[email protected]f103ab72009-09-02 17:10:594023 SchedulePluginMove(move);
4024}
4025
4026void RenderView::DidStartLoadingForPlugin() {
4027 // TODO(darin): Make is_loading_ be a counter!
[email protected]48c9cf2d2009-09-16 16:47:524028 didStartLoading();
[email protected]f103ab72009-09-02 17:10:594029}
4030
4031void RenderView::DidStopLoadingForPlugin() {
4032 // TODO(darin): Make is_loading_ be a counter!
[email protected]48c9cf2d2009-09-16 16:47:524033 didStopLoading();
[email protected]f103ab72009-09-02 17:10:594034}
4035
4036void RenderView::ShowModalHTMLDialogForPlugin(
4037 const GURL& url,
4038 const gfx::Size& size,
4039 const std::string& json_arguments,
4040 std::string* json_retval) {
[email protected]12636df2009-09-28 22:32:214041 SendAndRunNestedMessageLoop(new ViewHostMsg_ShowModalHTMLDialog(
[email protected]f103ab72009-09-02 17:10:594042 routing_id_, url, size.width(), size.height(), json_arguments,
[email protected]12636df2009-09-28 22:32:214043 json_retval));
[email protected]f103ab72009-09-02 17:10:594044}
4045
[email protected]b921cfd22010-02-25 16:57:514046WebCookieJar* RenderView::GetCookieJar() {
4047 return &cookie_jar_;
4048}
4049
initial.commit09911bf2008-07-26 23:55:294050void RenderView::SyncNavigationState() {
4051 if (!webview())
4052 return;
4053
[email protected]26aa0482009-09-30 16:55:274054 const WebHistoryItem& item = webview()->mainFrame()->currentHistoryItem();
[email protected]ca948a22009-06-25 19:36:174055 if (item.isNull())
initial.commit09911bf2008-07-26 23:55:294056 return;
[email protected]ca948a22009-06-25 19:36:174057
4058 Send(new ViewHostMsg_UpdateState(
4059 routing_id_, page_id_, webkit_glue::HistoryItemToString(item)));
initial.commit09911bf2008-07-26 23:55:294060}
4061
[email protected]b0950a72009-09-29 23:16:174062bool RenderView::DownloadImage(int id, const GURL& image_url, int image_size) {
4063 // Make sure webview was not shut down.
4064 if (!webview())
4065 return false;
4066 // Create an image resource fetcher and assign it with a call back object.
[email protected]bb461532010-11-26 21:50:234067 image_fetchers_.push_back(linked_ptr<ImageResourceFetcher>(
4068 new ImageResourceFetcher(
4069 image_url, webview()->mainFrame(), id, image_size,
4070 NewCallback(this, &RenderView::DidDownloadImage))));
[email protected]b0950a72009-09-29 23:16:174071 return true;
4072}
4073
4074void RenderView::DidDownloadImage(ImageResourceFetcher* fetcher,
initial.commit09911bf2008-07-26 23:55:294075 const SkBitmap& image) {
[email protected]b0950a72009-09-29 23:16:174076 // Notify requester of image download status.
[email protected]51bd36612009-10-20 22:49:474077 Send(new ViewHostMsg_DidDownloadFavIcon(routing_id_,
4078 fetcher->id(),
4079 fetcher->image_url(),
4080 image.isNull(),
4081 image));
[email protected]bb461532010-11-26 21:50:234082
4083 // Remove the image fetcher from our pending list. We're in the callback from
4084 // ImageResourceFetcher, best to delay deletion.
4085 for (ImageResourceFetcherList::iterator iter = image_fetchers_.begin();
4086 iter != image_fetchers_.end(); ++iter) {
4087 if (iter->get() == fetcher) {
4088 iter->release();
4089 image_fetchers_.erase(iter);
4090 break;
4091 }
4092 }
[email protected]b0950a72009-09-29 23:16:174093 MessageLoop::current()->DeleteSoon(FROM_HERE, fetcher);
initial.commit09911bf2008-07-26 23:55:294094}
4095
[email protected]bf5c2ff392009-07-08 16:24:334096void RenderView::OnDownloadFavIcon(int id,
4097 const GURL& image_url,
4098 int image_size) {
[email protected]f11ca0732009-04-11 00:09:344099 bool data_image_failed = false;
4100 if (image_url.SchemeIs("data")) {
4101 SkBitmap data_image = ImageFromDataUrl(image_url);
4102 data_image_failed = data_image.empty();
4103 if (!data_image_failed) {
[email protected]bf5c2ff392009-07-08 16:24:334104 Send(new ViewHostMsg_DidDownloadFavIcon(routing_id_, id, image_url, false,
4105 data_image));
[email protected]f11ca0732009-04-11 00:09:344106 }
4107 }
4108
[email protected]bf5c2ff392009-07-08 16:24:334109 if (data_image_failed ||
[email protected]b0950a72009-09-29 23:16:174110 !DownloadImage(id, image_url, image_size)) {
[email protected]bf5c2ff392009-07-08 16:24:334111 Send(new ViewHostMsg_DidDownloadFavIcon(routing_id_, id, image_url, true,
4112 SkBitmap()));
4113 }
initial.commit09911bf2008-07-26 23:55:294114}
4115
[email protected]f11ca0732009-04-11 00:09:344116SkBitmap RenderView::ImageFromDataUrl(const GURL& url) const {
4117 std::string mime_type, char_set, data;
4118 if (net::DataURL::Parse(url, &mime_type, &char_set, &data) && !data.empty()) {
4119 // Decode the favicon using WebKit's image decoder.
4120 webkit_glue::ImageDecoder decoder(gfx::Size(kFavIconSize, kFavIconSize));
4121 const unsigned char* src_data =
4122 reinterpret_cast<const unsigned char*>(&data[0]);
4123
4124 return decoder.Decode(src_data, data.size());
4125 }
4126 return SkBitmap();
4127}
4128
initial.commit09911bf2008-07-26 23:55:294129void RenderView::OnGetApplicationInfo(int page_id) {
[email protected]38789d82010-11-17 06:03:444130 WebApplicationInfo app_info;
4131 if (page_id == page_id_) {
4132 string16 error;
4133 web_apps::ParseWebAppFromWebDocument(webview()->mainFrame(), &app_info,
4134 &error);
4135 }
initial.commit09911bf2008-07-26 23:55:294136
4137 // Prune out any data URLs in the set of icons. The browser process expects
4138 // any icon with a data URL to have originated from a favicon. We don't want
4139 // to decode arbitrary data URLs in the browser process. See
4140 // http://b/issue?id=1162972
4141 for (size_t i = 0; i < app_info.icons.size(); ++i) {
[email protected]6de74452009-02-25 18:04:594142 if (app_info.icons[i].url.SchemeIs(chrome::kDataScheme)) {
initial.commit09911bf2008-07-26 23:55:294143 app_info.icons.erase(app_info.icons.begin() + i);
4144 --i;
4145 }
4146 }
4147
4148 Send(new ViewHostMsg_DidGetApplicationInfo(routing_id_, page_id, app_info));
4149}
4150
[email protected]7ccddb8c2009-08-04 17:36:554151GURL RenderView::GetAlternateErrorPageURL(const GURL& failed_url,
initial.commit09911bf2008-07-26 23:55:294152 ErrorPageType error_type) {
[email protected]7ccddb8c2009-08-04 17:36:554153 if (failed_url.SchemeIsSecure()) {
initial.commit09911bf2008-07-26 23:55:294154 // If the URL that failed was secure, then the embedding web page was not
4155 // expecting a network attacker to be able to manipulate its contents. As
4156 // we fetch alternate error pages over HTTP, we would be allowing a network
4157 // attacker to manipulate the contents of the response if we tried to use
4158 // the link doctor here.
[email protected]810a52ef2010-01-08 01:22:154159 return GURL();
initial.commit09911bf2008-07-26 23:55:294160 }
4161
4162 // Grab the base URL from the browser process.
4163 if (!alternate_error_page_url_.is_valid())
[email protected]810a52ef2010-01-08 01:22:154164 return GURL();
initial.commit09911bf2008-07-26 23:55:294165
4166 // Strip query params from the failed URL.
4167 GURL::Replacements remove_params;
4168 remove_params.ClearUsername();
4169 remove_params.ClearPassword();
4170 remove_params.ClearQuery();
4171 remove_params.ClearRef();
[email protected]7ccddb8c2009-08-04 17:36:554172 const GURL url_to_send = failed_url.ReplaceComponents(remove_params);
[email protected]6fd28f642010-03-15 17:15:504173 std::string spec_to_send = url_to_send.spec();
4174 // Notify link doctor of the url truncation by sending of "?" at the end.
4175 if (failed_url.has_query())
4176 spec_to_send.append("?");
initial.commit09911bf2008-07-26 23:55:294177
4178 // Construct the query params to send to link doctor.
4179 std::string params(alternate_error_page_url_.query());
4180 params.append("&url=");
[email protected]6fd28f642010-03-15 17:15:504181 params.append(EscapeQueryParamValue(spec_to_send, true));
initial.commit09911bf2008-07-26 23:55:294182 params.append("&sourceid=chrome");
4183 params.append("&error=");
4184 switch (error_type) {
4185 case DNS_ERROR:
4186 params.append("dnserror");
4187 break;
4188
4189 case HTTP_404:
4190 params.append("http404");
4191 break;
4192
[email protected]5df266ac2008-10-15 19:50:134193 case CONNECTION_ERROR:
[email protected]e1f934b2009-01-26 20:41:334194 params.append("connectionfailure");
[email protected]5df266ac2008-10-15 19:50:134195 break;
4196
initial.commit09911bf2008-07-26 23:55:294197 default:
4198 NOTREACHED() << "unknown ErrorPageType";
4199 }
4200
4201 // OK, build the final url to return.
4202 GURL::Replacements link_doctor_params;
4203 link_doctor_params.SetQueryStr(params);
4204 GURL url = alternate_error_page_url_.ReplaceComponents(link_doctor_params);
4205 return url;
4206}
4207
[email protected]c50008512011-02-03 01:17:274208WebUIBindings* RenderView::GetWebUIBindings() {
4209 if (!web_ui_bindings_.get()) {
4210 web_ui_bindings_.reset(new WebUIBindings());
[email protected]c091c2c2010-09-17 19:05:464211 }
[email protected]c50008512011-02-03 01:17:274212 return web_ui_bindings_.get();
[email protected]c091c2c2010-09-17 19:05:464213}
4214
4215ExternalHostBindings* RenderView::GetExternalHostBindings() {
4216 if (!external_host_bindings_.get()) {
4217 external_host_bindings_.reset(new ExternalHostBindings());
4218 }
4219 return external_host_bindings_.get();
4220}
4221
[email protected]0fdbf8c2010-07-08 20:33:014222WebKit::WebPlugin* RenderView::GetWebPluginFromPluginDocument() {
4223 return webview()->mainFrame()->document().to<WebPluginDocument>().plugin();
[email protected]24a7f3c2010-03-25 08:26:494224}
4225
[email protected]6069da8c2009-10-20 20:33:494226void RenderView::OnFind(int request_id, const string16& search_text,
4227 const WebFindOptions& options) {
[email protected]26aa0482009-09-30 16:55:274228 WebFrame* main_frame = webview()->mainFrame();
[email protected]24a7f3c2010-03-25 08:26:494229
4230 if (main_frame->document().isPluginDocument()) {
[email protected]24a7f3c2010-03-25 08:26:494231 if (options.findNext) {
4232 // Just navigate back/forward.
[email protected]0fdbf8c2010-07-08 20:33:014233 GetWebPluginFromPluginDocument()->selectFindResult(options.forward);
[email protected]24a7f3c2010-03-25 08:26:494234 } else {
[email protected]afdbd142010-07-10 08:01:234235 if (GetWebPluginFromPluginDocument()->startFind(
4236 search_text, options.matchCase, request_id)) {
[email protected]24a7f3c2010-03-25 08:26:494237 } else {
[email protected]e7c58a32010-08-13 19:47:114238 // Send "no results".
4239 Send(new ViewHostMsg_Find_Reply(routing_id_,
4240 request_id,
4241 0,
4242 gfx::Rect(),
4243 0,
4244 true));
[email protected]24a7f3c2010-03-25 08:26:494245 }
4246 }
4247 return;
4248 }
4249
[email protected]b4bb2502009-10-01 22:35:274250 WebFrame* frame_after_main = main_frame->traverseNext(true);
[email protected]26aa0482009-09-30 16:55:274251 WebFrame* focused_frame = webview()->focusedFrame();
initial.commit09911bf2008-07-26 23:55:294252 WebFrame* search_frame = focused_frame; // start searching focused frame.
4253
4254 bool multi_frame = (frame_after_main != main_frame);
4255
4256 // If we have multiple frames, we don't want to wrap the search within the
4257 // frame, so we check here if we only have main_frame in the chain.
4258 bool wrap_within_frame = !multi_frame;
4259
[email protected]b3f2b912009-04-09 16:18:524260 WebRect selection_rect;
initial.commit09911bf2008-07-26 23:55:294261 bool result = false;
4262
[email protected]7830da3e2009-11-06 16:27:264263 // If something is selected when we start searching it means we cannot just
4264 // increment the current match ordinal; we need to re-generate it.
4265 WebRange current_selection = focused_frame->selectionRange();
4266
initial.commit09911bf2008-07-26 23:55:294267 do {
[email protected]dd7daa82009-08-10 05:46:454268 result = search_frame->find(
[email protected]7ea066a2009-04-06 20:21:594269 request_id, search_text, options, wrap_within_frame, &selection_rect);
initial.commit09911bf2008-07-26 23:55:294270
4271 if (!result) {
4272 // don't leave text selected as you move to the next frame.
[email protected]a100d76bb2009-08-14 17:50:224273 search_frame->executeCommand(WebString::fromUTF8("Unselect"));
initial.commit09911bf2008-07-26 23:55:294274
4275 // Find the next frame, but skip the invisible ones.
4276 do {
4277 // What is the next frame to search? (we might be going backwards). Note
4278 // that we specify wrap=true so that search_frame never becomes NULL.
[email protected]7ea066a2009-04-06 20:21:594279 search_frame = options.forward ?
[email protected]b4bb2502009-10-01 22:35:274280 search_frame->traverseNext(true) :
4281 search_frame->traversePrevious(true);
[email protected]dd7daa82009-08-10 05:46:454282 } while (!search_frame->hasVisibleContent() &&
4283 search_frame != focused_frame);
initial.commit09911bf2008-07-26 23:55:294284
[email protected]884db412008-11-24 23:46:504285 // Make sure selection doesn't affect the search operation in new frame.
[email protected]a100d76bb2009-08-14 17:50:224286 search_frame->executeCommand(WebString::fromUTF8("Unselect"));
initial.commit09911bf2008-07-26 23:55:294287
4288 // If we have multiple frames and we have wrapped back around to the
4289 // focused frame, we need to search it once more allowing wrap within
4290 // the frame, otherwise it will report 'no match' if the focused frame has
4291 // reported matches, but no frames after the focused_frame contain a
4292 // match for the search word(s).
4293 if (multi_frame && search_frame == focused_frame) {
[email protected]dd7daa82009-08-10 05:46:454294 result = search_frame->find(
[email protected]7ea066a2009-04-06 20:21:594295 request_id, search_text, options, true, // Force wrapping.
4296 &selection_rect);
initial.commit09911bf2008-07-26 23:55:294297 }
4298 }
4299
[email protected]26aa0482009-09-30 16:55:274300 webview()->setFocusedFrame(search_frame);
initial.commit09911bf2008-07-26 23:55:294301 } while (!result && search_frame != focused_frame);
4302
[email protected]7830da3e2009-11-06 16:27:264303 if (options.findNext && current_selection.isNull()) {
[email protected]4f3dc372009-02-24 00:10:294304 // Force the main_frame to report the actual count.
[email protected]dd7daa82009-08-10 05:46:454305 main_frame->increaseMatchCount(0, request_id);
[email protected]4f3dc372009-02-24 00:10:294306 } else {
4307 // If nothing is found, set result to "0 of 0", otherwise, set it to
4308 // "-1 of 1" to indicate that we found at least one item, but we don't know
4309 // yet what is active.
4310 int ordinal = result ? -1 : 0; // -1 here means, we might know more later.
4311 int match_count = result ? 1 : 0; // 1 here means possibly more coming.
initial.commit09911bf2008-07-26 23:55:294312
[email protected]4f3dc372009-02-24 00:10:294313 // If we find no matches then this will be our last status update.
4314 // Otherwise the scoping effort will send more results.
4315 bool final_status_update = !result;
initial.commit09911bf2008-07-26 23:55:294316
[email protected]4f3dc372009-02-24 00:10:294317 // Send the search result over to the browser process.
[email protected]4f999132009-03-31 18:08:404318 Send(new ViewHostMsg_Find_Reply(routing_id_,
[email protected]7ea066a2009-04-06 20:21:594319 request_id,
[email protected]4f3dc372009-02-24 00:10:294320 match_count,
4321 selection_rect,
4322 ordinal,
4323 final_status_update));
initial.commit09911bf2008-07-26 23:55:294324
initial.commit09911bf2008-07-26 23:55:294325 // Scoping effort begins, starting with the mainframe.
4326 search_frame = main_frame;
4327
[email protected]dd7daa82009-08-10 05:46:454328 main_frame->resetMatchCount();
initial.commit09911bf2008-07-26 23:55:294329
4330 do {
4331 // Cancel all old scoping requests before starting a new one.
[email protected]dd7daa82009-08-10 05:46:454332 search_frame->cancelPendingScopingEffort();
initial.commit09911bf2008-07-26 23:55:294333
4334 // We don't start another scoping effort unless at least one match has
4335 // been found.
4336 if (result) {
4337 // Start new scoping request. If the scoping function determines that it
4338 // needs to scope, it will defer until later.
[email protected]dd7daa82009-08-10 05:46:454339 search_frame->scopeStringMatches(request_id,
[email protected]7ea066a2009-04-06 20:21:594340 search_text,
4341 options,
initial.commit09911bf2008-07-26 23:55:294342 true); // reset the tickmarks
4343 }
4344
4345 // Iterate to the next frame. The frame will not necessarily scope, for
4346 // example if it is not visible.
[email protected]b4bb2502009-10-01 22:35:274347 search_frame = search_frame->traverseNext(true);
initial.commit09911bf2008-07-26 23:55:294348 } while (search_frame != main_frame);
4349 }
4350}
4351
[email protected]24a7f3c2010-03-25 08:26:494352void RenderView::OnStopFinding(const ViewMsg_StopFinding_Params& params) {
4353 WebView* view = webview();
4354 if (!view)
4355 return;
4356
4357 WebDocument doc = view->mainFrame()->document();
4358 if (doc.isPluginDocument()) {
[email protected]0fdbf8c2010-07-08 20:33:014359 GetWebPluginFromPluginDocument()->stopFind();
[email protected]24a7f3c2010-03-25 08:26:494360 return;
4361 }
4362
4363 bool clear_selection =
4364 params.action == ViewMsg_StopFinding_Params::kClearSelection;
4365 if (clear_selection)
4366 view->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect"));
4367
4368 WebFrame* frame = view->mainFrame();
4369 while (frame) {
4370 frame->stopFinding(clear_selection);
4371 frame = frame->traverseNext(false);
4372 }
4373
4374 if (params.action == ViewMsg_StopFinding_Params::kActivateSelection) {
4375 WebFrame* focused_frame = view->focusedFrame();
4376 if (focused_frame) {
4377 WebDocument doc = focused_frame->document();
4378 if (!doc.isNull()) {
4379 WebNode node = doc.focusedNode();
4380 if (!node.isNull())
4381 node.simulateClick();
4382 }
4383 }
4384 }
4385}
4386
4387void RenderView::OnFindReplyAck() {
4388 // Check if there is any queued up request waiting to be sent.
4389 if (queued_find_reply_message_.get()) {
4390 // Send the search result over to the browser process.
[email protected]d22d8732010-05-04 19:24:424391 Send(queued_find_reply_message_.release());
[email protected]24a7f3c2010-03-25 08:26:494392 }
4393}
4394
[email protected]8934a3b2010-02-25 00:34:004395bool RenderView::AllowContentType(ContentSettingsType settings_type) {
[email protected]0de80162010-02-03 04:52:354396 // CONTENT_SETTING_ASK is only valid for cookies.
[email protected]8934a3b2010-02-25 00:34:004397 return current_content_settings_.settings[settings_type] !=
4398 CONTENT_SETTING_BLOCK;
4399}
4400
[email protected]55126132010-08-19 14:53:284401void RenderView::DidBlockContentType(ContentSettingsType settings_type,
4402 const std::string& resource_identifier) {
[email protected]8934a3b2010-02-25 00:34:004403 if (!content_blocked_[settings_type]) {
4404 content_blocked_[settings_type] = true;
[email protected]55126132010-08-19 14:53:284405 Send(new ViewHostMsg_ContentBlocked(routing_id_, settings_type,
4406 resource_identifier));
[email protected]0de80162010-02-03 04:52:354407 }
[email protected]0de80162010-02-03 04:52:354408}
4409
[email protected]71b0d5d2010-02-15 05:43:074410void RenderView::ClearBlockedContentSettings() {
4411 for (size_t i = 0; i < arraysize(content_blocked_); ++i)
4412 content_blocked_[i] = false;
4413}
4414
[email protected]0bd753682010-12-16 18:15:524415WebPlugin* RenderView::CreatePepperPlugin(
4416 WebFrame* frame,
4417 const WebPluginParams& params,
4418 const FilePath& path,
4419 webkit::ppapi::PluginModule* pepper_module) {
4420 return new webkit::ppapi::WebPluginImpl(
[email protected]b75b8292010-10-01 07:28:254421 pepper_module, params, pepper_delegate_.AsWeakPtr());
[email protected]aad51d1c2010-08-05 08:38:094422}
[email protected]00152e92010-07-19 11:47:404423
[email protected]191eb3f72010-12-21 06:27:504424WebPlugin* RenderView::CreateNPAPIPlugin(
4425 WebFrame* frame,
4426 const WebPluginParams& params,
4427 const FilePath& path,
4428 const std::string& mime_type) {
4429 return new webkit::npapi::WebPluginImpl(
[email protected]20a793e2010-10-12 06:50:084430 frame, params, path, mime_type, AsWeakPtr());
[email protected]00152e92010-07-19 11:47:404431}
4432
[email protected]3c2826852010-12-16 19:09:144433WebPlugin* RenderView::CreatePluginPlaceholder(
[email protected]57b66d02010-09-30 11:24:514434 WebFrame* frame,
4435 const WebPluginParams& params,
[email protected]191eb3f72010-12-21 06:27:504436 const webkit::npapi::PluginGroup& group,
[email protected]3c2826852010-12-16 19:09:144437 int resource_id,
[email protected]90dba072011-01-20 20:10:204438 int message_id,
4439 bool is_blocked_for_prerendering) {
[email protected]3c2826852010-12-16 19:09:144440 // |blocked_plugin| will delete itself when the WebViewPlugin
4441 // is destroyed.
4442 BlockedPlugin* blocked_plugin =
4443 new BlockedPlugin(this,
4444 frame,
4445 group,
4446 params,
4447 webkit_preferences_,
4448 resource_id,
[email protected]2e34ab3f2010-12-17 05:47:374449 l10n_util::GetStringFUTF16(message_id,
[email protected]90dba072011-01-20 20:10:204450 group.GetGroupName()),
4451 is_blocked_for_prerendering);
[email protected]3c2826852010-12-16 19:09:144452 return blocked_plugin->plugin();
[email protected]57b66d02010-09-30 11:24:514453}
4454
[email protected]40bd6582009-12-04 23:49:514455void RenderView::OnZoom(PageZoom::Function function) {
4456 if (!webview()) // Not sure if this can happen, but no harm in being safe.
4457 return;
4458
[email protected]258d31122010-05-09 10:59:414459 webview()->hidePopups();
[email protected]b03794d2010-03-26 19:57:524460
[email protected]b75b8292010-10-01 07:28:254461 double old_zoom_level = webview()->zoomLevel();
4462 double zoom_level;
4463 if (function == PageZoom::RESET) {
4464 zoom_level = 0;
4465 } else if (static_cast<int>(old_zoom_level) == old_zoom_level) {
4466 // Previous zoom level is a whole number, so just increment/decrement.
4467 zoom_level = old_zoom_level + function;
4468 } else {
4469 // Either the user hit the zoom factor limit and thus the zoom level is now
4470 // not a whole number, or a plugin changed it to a custom value. We want
4471 // to go to the next whole number so that the user can always get back to
4472 // 100% with the keyboard/menu.
4473 if ((old_zoom_level > 1 && function > 0) ||
4474 (old_zoom_level < 1 && function < 0)) {
[email protected]3209e7112010-10-01 23:53:454475 zoom_level = static_cast<int>(old_zoom_level + function);
[email protected]b75b8292010-10-01 07:28:254476 } else {
4477 // We're going towards 100%, so first go to the next whole number.
4478 zoom_level = static_cast<int>(old_zoom_level);
4479 }
4480 }
[email protected]40bd6582009-12-04 23:49:514481
[email protected]b75b8292010-10-01 07:28:254482 webview()->setZoomLevel(false, zoom_level);
4483 zoomLevelChanged();
[email protected]40bd6582009-12-04 23:49:514484}
4485
[email protected]d0b8d092010-10-25 04:05:174486void RenderView::OnSetZoomLevel(double zoom_level) {
4487 // Don't set zoom level for full-page plugin since they don't use the same
4488 // zoom settings.
4489 if (webview()->mainFrame()->document().isPluginDocument())
4490 return;
4491
4492 webview()->hidePopups();
4493 webview()->setZoomLevel(false, zoom_level);
4494 zoomLevelChanged();
4495}
4496
[email protected]9d797f32010-04-23 07:17:544497void RenderView::OnSetContentSettingsForLoadingURL(
4498 const GURL& url,
[email protected]f85f0702010-01-30 09:31:014499 const ContentSettings& content_settings) {
[email protected]9d797f32010-04-23 07:17:544500 host_content_settings_[url] = content_settings;
[email protected]f85f0702010-01-30 09:31:014501}
4502
[email protected]9d797f32010-04-23 07:17:544503void RenderView::OnSetZoomLevelForLoadingURL(const GURL& url,
[email protected]b75b8292010-10-01 07:28:254504 double zoom_level) {
[email protected]9d797f32010-04-23 07:17:544505 host_zoom_levels_[url] = zoom_level;
initial.commit09911bf2008-07-26 23:55:294506}
4507
[email protected]41fc0322009-09-04 22:23:404508void RenderView::OnSetPageEncoding(const std::string& encoding_name) {
[email protected]26aa0482009-09-30 16:55:274509 webview()->setPageEncoding(WebString::fromUTF8(encoding_name));
initial.commit09911bf2008-07-26 23:55:294510}
4511
[email protected]a697f4c2009-09-14 22:30:184512void RenderView::OnResetPageEncodingToDefault() {
[email protected]26aa0482009-09-30 16:55:274513 WebString no_encoding;
4514 webview()->setPageEncoding(no_encoding);
[email protected]a697f4c2009-09-14 22:30:184515}
4516
[email protected]20ad2692009-11-20 18:27:204517bool RenderView::GetAllChildFrames(
4518 WebFrame* parent_frame,
4519 std::vector<WebFrame*>* frames_vector) const {
4520 if (!parent_frame)
4521 return false;
4522 for (WebFrame* child_frame = parent_frame->firstChild(); child_frame;
4523 child_frame = child_frame->nextSibling()) {
4524 frames_vector->push_back(child_frame);
4525 GetAllChildFrames(child_frame, frames_vector);
4526 }
4527 return true;
4528}
4529
[email protected]dd7daa82009-08-10 05:46:454530WebFrame* RenderView::GetChildFrame(const std::wstring& xpath) const {
4531 if (xpath.empty())
[email protected]26aa0482009-09-30 16:55:274532 return webview()->mainFrame();
[email protected]dd7daa82009-08-10 05:46:454533
4534 // xpath string can represent a frame deep down the tree (across multiple
4535 // frame DOMs).
4536 // Example, /html/body/table/tbody/tr/td/iframe\n/frameset/frame[0]
4537 // should break into 2 xpaths
4538 // /html/body/table/tbody/tr/td/iframe & /frameset/frame[0]
4539
[email protected]26aa0482009-09-30 16:55:274540 WebFrame* frame = webview()->mainFrame();
[email protected]dd7daa82009-08-10 05:46:454541
4542 std::wstring xpath_remaining = xpath;
4543 while (!xpath_remaining.empty()) {
4544 std::wstring::size_type delim_pos = xpath_remaining.find_first_of(L'\n');
4545 std::wstring xpath_child;
4546 if (delim_pos != std::wstring::npos) {
4547 xpath_child = xpath_remaining.substr(0, delim_pos);
4548 xpath_remaining.erase(0, delim_pos + 1);
4549 } else {
4550 xpath_remaining.swap(xpath_child);
4551 }
4552 frame = frame->findChildByExpression(WideToUTF16Hack(xpath_child));
initial.commit09911bf2008-07-26 23:55:294553 }
4554
[email protected]dd7daa82009-08-10 05:46:454555 return frame;
initial.commit09911bf2008-07-26 23:55:294556}
4557
[email protected]13a1e4c3c2011-02-03 21:07:094558WebNode RenderView::GetFocusedNode() const {
4559 if (!webview())
4560 return WebNode();
4561 WebFrame* focused_frame = webview()->focusedFrame();
4562 if (focused_frame) {
4563 WebDocument doc = focused_frame->document();
4564 if (!doc.isNull())
4565 return doc.focusedNode();
4566 }
4567
4568 return WebNode();
4569}
4570
[email protected]ce833282010-11-04 15:48:394571void RenderView::SetSuggestions(const std::vector<std::string>& suggestions) {
4572 // Explicitly allow empty vector to be sent to the browser.
4573 Send(new ViewHostMsg_SetSuggestions(routing_id_, page_id_, suggestions));
[email protected]15d9c0c2010-09-10 22:36:264574}
4575
[email protected]882b7b22010-10-05 03:34:534576void RenderView::EvaluateScript(const string16& frame_xpath,
4577 const string16& script,
4578 int id,
4579 bool notify_result) {
4580 v8::Handle<v8::Value> result;
4581 WebFrame* web_frame = GetChildFrame(UTF16ToWideHack(frame_xpath));
4582 if (web_frame)
4583 result = web_frame->executeScriptAndReturnValue(WebScriptSource(script));
4584 if (notify_result) {
[email protected]81f9fe0b2010-12-07 00:35:294585 ListValue list;
4586 if (web_frame) {
4587 v8::HandleScope handle_scope;
4588 v8::Local<v8::Context> context = web_frame->mainWorldScriptContext();
4589 v8::Context::Scope context_scope(context);
4590 list.Set(0, ConvertV8Value(result));
4591 } else {
4592 list.Set(0, Value::CreateNullValue());
4593 }
4594 Send(new ViewHostMsg_ScriptEvalResponse(routing_id_, id, list));
[email protected]882b7b22010-10-05 03:34:534595 }
initial.commit09911bf2008-07-26 23:55:294596}
4597
[email protected]1810e132009-03-24 23:35:484598void RenderView::InsertCSS(const std::wstring& frame_xpath,
[email protected]ffaef0c2009-09-15 17:08:084599 const std::string& css,
4600 const std::string& id) {
[email protected]1810e132009-03-24 23:35:484601 WebFrame* web_frame = GetChildFrame(frame_xpath);
4602 if (!web_frame)
4603 return;
4604
[email protected]ffaef0c2009-09-15 17:08:084605 web_frame->insertStyleText(WebString::fromUTF8(css), WebString::fromUTF8(id));
[email protected]1810e132009-03-24 23:35:484606}
4607
[email protected]00c39612010-03-06 02:53:284608void RenderView::OnPepperPluginDestroy(
4609 WebPluginDelegatePepper* pepper_plugin) {
4610 std::set<WebPluginDelegatePepper*>::iterator found_pepper =
[email protected]53900d52010-06-16 04:25:014611 current_oldstyle_pepper_plugins_.find(pepper_plugin);
4612 if (found_pepper == current_oldstyle_pepper_plugins_.end()) {
[email protected]00c39612010-03-06 02:53:284613 NOTREACHED();
4614 return;
4615 }
[email protected]53900d52010-06-16 04:25:014616 current_oldstyle_pepper_plugins_.erase(found_pepper);
[email protected]cdaf8d02010-03-30 19:52:474617
4618 // The plugin could have been destroyed while it was waiting for a file
4619 // choose callback, so check all pending completion callbacks and NULL them.
4620 for (std::deque< linked_ptr<PendingFileChooser> >::iterator i =
4621 file_chooser_completions_.begin();
4622 i != file_chooser_completions_.end(); /* nothing */) {
4623 if ((*i)->completion == pepper_plugin) {
4624 // We NULL the first one instead of deleting it because the plugin might
4625 // be the one waiting for a file choose callback. If the callback later
4626 // comes, we don't want to send the result to the next callback in line.
4627 if (i == file_chooser_completions_.begin())
4628 (*i)->completion = NULL;
4629 else
4630 i = file_chooser_completions_.erase(i);
4631 } else {
4632 ++i;
4633 }
4634 }
[email protected]00c39612010-03-06 02:53:284635}
4636
[email protected]882b7b22010-10-05 03:34:534637void RenderView::OnScriptEvalRequest(const string16& frame_xpath,
4638 const string16& jscript,
4639 int id,
4640 bool notify_result) {
4641 EvaluateScript(frame_xpath, jscript, id, notify_result);
initial.commit09911bf2008-07-26 23:55:294642}
4643
[email protected]1810e132009-03-24 23:35:484644void RenderView::OnCSSInsertRequest(const std::wstring& frame_xpath,
[email protected]ffaef0c2009-09-15 17:08:084645 const std::string& css,
4646 const std::string& id) {
4647 InsertCSS(frame_xpath, css, id);
[email protected]ae461542009-06-19 19:03:414648
4649 // Notify RenderViewHost that css has been inserted into the frame.
4650 Send(new ViewHostMsg_OnCSSInserted(routing_id_));
[email protected]1810e132009-03-24 23:35:484651}
4652
[email protected]7ea066a2009-04-06 20:21:594653void RenderView::OnAddMessageToConsole(
4654 const string16& frame_xpath,
4655 const string16& message,
4656 const WebConsoleMessage::Level& level) {
4657 WebFrame* web_frame = GetChildFrame(UTF16ToWideHack(frame_xpath));
[email protected]0dea3ea2009-03-31 23:30:594658 if (web_frame)
[email protected]dd7daa82009-08-10 05:46:454659 web_frame->addMessageToConsole(WebConsoleMessage(level, message));
initial.commit09911bf2008-07-26 23:55:294660}
4661
[email protected]81e63782009-02-27 19:35:094662void RenderView::OnAllowBindings(int enabled_bindings_flags) {
4663 enabled_bindings_ |= enabled_bindings_flags;
initial.commit09911bf2008-07-26 23:55:294664}
4665
4666void RenderView::OnSetDOMUIProperty(const std::string& name,
4667 const std::string& value) {
[email protected]81e63782009-02-27 19:35:094668 DCHECK(BindingsPolicy::is_dom_ui_enabled(enabled_bindings_));
[email protected]c50008512011-02-03 01:17:274669 GetWebUIBindings()->SetProperty(name, value);
initial.commit09911bf2008-07-26 23:55:294670}
4671
4672void RenderView::OnReservePageIDRange(int size_of_range) {
4673 next_page_id_ += size_of_range + 1;
4674}
4675
[email protected]e80c73b2009-04-07 23:24:584676void RenderView::OnDragSourceEndedOrMoved(const gfx::Point& client_point,
4677 const gfx::Point& screen_point,
[email protected]1d9f4132009-09-08 17:29:254678 bool ended,
4679 WebDragOperation op) {
[email protected]5f9ae6c2009-07-08 02:38:034680 if (ended) {
[email protected]26aa0482009-09-30 16:55:274681 webview()->dragSourceEndedAt(client_point, screen_point, op);
[email protected]daec5d62010-06-04 09:14:204682 } else {
4683 webview()->dragSourceMovedTo(client_point, screen_point, op);
[email protected]5f9ae6c2009-07-08 02:38:034684 }
initial.commit09911bf2008-07-26 23:55:294685}
4686
4687void RenderView::OnDragSourceSystemDragEnded() {
[email protected]26aa0482009-09-30 16:55:274688 webview()->dragSourceSystemDragEnded();
initial.commit09911bf2008-07-26 23:55:294689}
4690
initial.commit09911bf2008-07-26 23:55:294691void RenderView::OnDragTargetDragEnter(const WebDropData& drop_data,
[email protected]e80c73b2009-04-07 23:24:584692 const gfx::Point& client_point,
[email protected]1d9f4132009-09-08 17:29:254693 const gfx::Point& screen_point,
4694 WebDragOperationsMask ops) {
[email protected]26aa0482009-09-30 16:55:274695 WebDragOperation operation = webview()->dragTargetDragEnter(
[email protected]e80c73b2009-04-07 23:24:584696 drop_data.ToDragData(),
4697 drop_data.identity,
4698 client_point,
[email protected]1d9f4132009-09-08 17:29:254699 screen_point,
4700 ops);
initial.commit09911bf2008-07-26 23:55:294701
[email protected]1d9f4132009-09-08 17:29:254702 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, operation));
initial.commit09911bf2008-07-26 23:55:294703}
4704
[email protected]e80c73b2009-04-07 23:24:584705void RenderView::OnDragTargetDragOver(const gfx::Point& client_point,
[email protected]1d9f4132009-09-08 17:29:254706 const gfx::Point& screen_point,
4707 WebDragOperationsMask ops) {
[email protected]26aa0482009-09-30 16:55:274708 WebDragOperation operation = webview()->dragTargetDragOver(
[email protected]1d9f4132009-09-08 17:29:254709 client_point,
4710 screen_point,
4711 ops);
initial.commit09911bf2008-07-26 23:55:294712
[email protected]1d9f4132009-09-08 17:29:254713 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, operation));
initial.commit09911bf2008-07-26 23:55:294714}
4715
4716void RenderView::OnDragTargetDragLeave() {
[email protected]26aa0482009-09-30 16:55:274717 webview()->dragTargetDragLeave();
initial.commit09911bf2008-07-26 23:55:294718}
4719
[email protected]e80c73b2009-04-07 23:24:584720void RenderView::OnDragTargetDrop(const gfx::Point& client_point,
4721 const gfx::Point& screen_point) {
[email protected]26aa0482009-09-30 16:55:274722 webview()->dragTargetDrop(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:294723}
4724
4725void RenderView::OnUpdateWebPreferences(const WebPreferences& prefs) {
[email protected]2fab253a2009-08-17 23:00:594726 webkit_preferences_ = prefs;
4727 webkit_preferences_.Apply(webview());
initial.commit09911bf2008-07-26 23:55:294728}
4729
4730void RenderView::OnSetAltErrorPageURL(const GURL& url) {
4731 alternate_error_page_url_ = url;
4732}
4733
[email protected]b29aa74b2011-01-31 21:41:084734void RenderView::OnCustomContextMenuAction(
4735 const webkit_glue::CustomContextMenuContext& custom_context,
4736 unsigned action) {
4737 if (custom_context.is_pepper_menu)
4738 pepper_delegate_.OnCustomContextMenuAction(custom_context, action);
4739 else
4740 webview()->performCustomContextMenuAction(action);
[email protected]a0c7153e2009-12-09 14:36:334741}
4742
initial.commit09911bf2008-07-26 23:55:294743void RenderView::OnInstallMissingPlugin() {
4744 // This could happen when the first default plugin is deleted.
[email protected]f103ab72009-09-02 17:10:594745 if (first_default_plugin_)
4746 first_default_plugin_->InstallMissingPlugin();
initial.commit09911bf2008-07-26 23:55:294747}
4748
[email protected]90dba072011-01-20 20:10:204749void RenderView::OnDisplayPrerenderedPage() {
4750 NavigationState* navigation_state = pending_navigation_state_.get();
4751 if (!navigation_state) {
4752 WebDataSource* ds = webview()->mainFrame()->dataSource();
4753 navigation_state = NavigationState::FromDataSource(ds);
4754 }
4755
4756 DCHECK(navigation_state->is_prerendering());
4757 navigation_state->set_is_prerendering(false);
4758}
4759
[email protected]cdaf8d02010-03-30 19:52:474760void RenderView::OnFileChooserResponse(const std::vector<FilePath>& paths) {
[email protected]8029f5672009-03-20 22:33:364761 // This could happen if we navigated to a different page before the user
4762 // closed the chooser.
[email protected]cdaf8d02010-03-30 19:52:474763 if (file_chooser_completions_.empty())
[email protected]8029f5672009-03-20 22:33:364764 return;
4765
[email protected]cdaf8d02010-03-30 19:52:474766 WebVector<WebString> ws_file_names(paths.size());
4767 for (size_t i = 0; i < paths.size(); ++i)
4768 ws_file_names[i] = webkit_glue::FilePathToWebString(paths[i]);
[email protected]a1128322009-10-06 18:38:464769
[email protected]cdaf8d02010-03-30 19:52:474770 if (file_chooser_completions_.front()->completion)
4771 file_chooser_completions_.front()->completion->didChooseFile(ws_file_names);
4772 file_chooser_completions_.pop_front();
4773
4774 // If there are more pending file chooser requests, schedule one now.
4775 if (!file_chooser_completions_.empty()) {
4776 Send(new ViewHostMsg_RunFileChooser(routing_id_,
4777 file_chooser_completions_.front()->params));
4778 }
initial.commit09911bf2008-07-26 23:55:294779}
4780
4781void RenderView::OnEnableViewSourceMode() {
4782 if (!webview())
4783 return;
[email protected]26aa0482009-09-30 16:55:274784 WebFrame* main_frame = webview()->mainFrame();
initial.commit09911bf2008-07-26 23:55:294785 if (!main_frame)
4786 return;
4787
[email protected]dd7daa82009-08-10 05:46:454788 main_frame->enableViewSourceMode(true);
initial.commit09911bf2008-07-26 23:55:294789}
4790
[email protected]770dd8b2010-05-24 18:11:394791void RenderView::OnEnablePreferredSizeChangedMode(int flags) {
4792 DCHECK(flags != kPreferredSizeNothing);
[email protected]9fb325e2010-05-06 18:23:244793 if (send_preferred_size_changes_)
4794 return;
[email protected]9fb325e2010-05-06 18:23:244795 send_preferred_size_changes_ = true;
[email protected]770dd8b2010-05-24 18:11:394796
4797 // WebKit doesn't send a notification of the effective height of the page
4798 // changes, so poll for it.
4799 // TODO: Add a notification for this to WebKit, remove polling. After that's
4800 // done, rename kPreferredSizeHeightThisIsSlow to kPreferredSizeHeight.
4801 // http://crbug.com/44850
4802 if (flags & kPreferredSizeHeightThisIsSlow) {
4803 preferred_size_change_timer_.Start(TimeDelta::FromMilliseconds(10), this,
4804 &RenderView::CheckPreferredSize);
4805 }
[email protected]0666aef2009-05-13 19:48:084806}
4807
[email protected]ce833282010-11-04 15:48:394808void RenderView::OnSearchBoxChange(const string16& value,
[email protected]368ef4c2010-11-08 21:58:464809 bool verbatim,
[email protected]ce833282010-11-04 15:48:394810 int selection_start,
4811 int selection_end) {
4812 search_box_.value = value;
[email protected]368ef4c2010-11-08 21:58:464813 search_box_.verbatim = verbatim;
[email protected]ce833282010-11-04 15:48:394814 search_box_.selection_start = selection_start;
4815 search_box_.selection_end = selection_end;
4816 if (!webview() || !webview()->mainFrame())
4817 return;
4818 extensions_v8::SearchBoxExtension::DispatchChange(webview()->mainFrame());
4819}
4820
4821void RenderView::OnSearchBoxSubmit(const string16& value, bool verbatim) {
4822 search_box_.value = value;
4823 search_box_.verbatim = verbatim;
4824 if (!webview() || !webview()->mainFrame())
4825 return;
4826 extensions_v8::SearchBoxExtension::DispatchSubmit(webview()->mainFrame());
4827}
4828
4829void RenderView::OnSearchBoxCancel() {
4830 search_box_.verbatim = false;
4831 if (!webview() || !webview()->mainFrame())
4832 return;
4833 extensions_v8::SearchBoxExtension::DispatchCancel(webview()->mainFrame());
4834}
4835
4836void RenderView::OnSearchBoxResize(const gfx::Rect& bounds) {
4837 search_box_.x = bounds.x();
4838 search_box_.y = bounds.y();
4839 search_box_.width = bounds.width();
4840 search_box_.height = bounds.height();
4841 if (!webview() || !webview()->mainFrame())
4842 return;
4843 extensions_v8::SearchBoxExtension::DispatchResize(webview()->mainFrame());
4844}
4845
[email protected]57ad7b8c2010-11-18 19:13:494846void RenderView::OnDetermineIfPageSupportsInstant(const string16& value,
[email protected]0d5ab152011-01-14 23:09:044847 bool verbatim,
4848 int selection_start,
4849 int selection_end) {
[email protected]ce833282010-11-04 15:48:394850 search_box_.value = value;
[email protected]57ad7b8c2010-11-18 19:13:494851 search_box_.verbatim = verbatim;
[email protected]0d5ab152011-01-14 23:09:044852 search_box_.selection_start = selection_start;
4853 search_box_.selection_end = selection_end;
[email protected]ce833282010-11-04 15:48:394854 bool result = extensions_v8::SearchBoxExtension::PageSupportsInstant(
4855 webview()->mainFrame());
4856 Send(new ViewHostMsg_InstantSupportDetermined(routing_id_, page_id_, result));
4857}
4858
[email protected]cda45c02010-02-25 19:28:104859void RenderView::OnDisableScrollbarsForSmallWindows(
4860 const gfx::Size& disable_scrollbar_size_limit) {
4861 disable_scrollbars_size_limit_ = disable_scrollbar_size_limit;
4862}
4863
[email protected]80d96fa2009-06-10 22:34:514864void RenderView::OnSetRendererPrefs(const RendererPreferences& renderer_prefs) {
4865 renderer_preferences_ = renderer_prefs;
[email protected]6e282c92009-07-24 01:19:374866 UpdateFontRenderingFromRendererPrefs();
[email protected]0dd6f9b52010-10-14 16:39:134867#if defined(TOOLKIT_USES_GTK)
[email protected]1c83eb42009-09-11 21:08:414868 WebColorName name = WebKit::WebColorWebkitFocusRingColor;
4869 WebKit::setNamedColors(&name, &renderer_prefs.focus_ring_color, 1);
[email protected]39cd64ed2010-02-05 02:18:464870 WebKit::setCaretBlinkInterval(renderer_prefs.caret_blink_interval);
[email protected]8d1b864d12010-10-10 00:04:344871 gfx::NativeThemeLinux::instance()->SetScrollbarColors(
4872 renderer_prefs.thumb_inactive_color,
4873 renderer_prefs.thumb_active_color,
4874 renderer_prefs.track_color);
[email protected]93623c5d2009-12-10 21:40:324875
[email protected]644d77e2010-01-27 01:03:104876 if (webview()) {
[email protected]93623c5d2009-12-10 21:40:324877 webview()->setScrollbarColors(
4878 renderer_prefs.thumb_inactive_color,
4879 renderer_prefs.thumb_active_color,
4880 renderer_prefs.track_color);
[email protected]644d77e2010-01-27 01:03:104881 webview()->setSelectionColors(
4882 renderer_prefs.active_selection_bg_color,
4883 renderer_prefs.active_selection_fg_color,
4884 renderer_prefs.inactive_selection_bg_color,
4885 renderer_prefs.inactive_selection_fg_color);
[email protected]f98d7e3c2010-09-13 22:30:464886 webview()->themeChanged();
[email protected]644d77e2010-01-27 01:03:104887 }
[email protected]7a74e102009-09-03 00:16:564888#endif
[email protected]80d96fa2009-06-10 22:34:514889}
4890
[email protected]952cb702009-10-07 05:50:284891void RenderView::OnMediaPlayerActionAt(const gfx::Point& location,
4892 const WebMediaPlayerAction& action) {
4893 if (webview())
4894 webview()->performMediaPlayerAction(action, location);
[email protected]581b87eb2009-07-23 23:06:564895}
4896
[email protected]7b291f92009-08-14 05:43:534897void RenderView::OnNotifyRendererViewType(ViewType::Type type) {
4898 view_type_ = type;
4899}
4900
4901void RenderView::OnUpdateBrowserWindowId(int window_id) {
4902 browser_window_id_ = window_id;
4903}
4904
[email protected]dea2d372010-09-25 06:41:144905void RenderView::OnEnableAccessibility() {
4906 if (WebAccessibilityCache::accessibilityEnabled())
4907 return;
[email protected]9f4db512010-05-10 20:21:414908
[email protected]dea2d372010-09-25 06:41:144909 WebAccessibilityCache::enableAccessibility();
4910
4911 if (webview()) {
4912 // It's possible that the webview has already loaded a webpage without
4913 // accessibility being enabled. Initialize the browser's cached
4914 // accessibility tree by sending it a 'load complete' notification.
4915 postAccessibilityNotification(
4916 webview()->accessibilityObject(),
4917 WebKit::WebAccessibilityNotificationLoadComplete);
4918 }
[email protected]266eb6f2008-09-30 23:56:504919}
4920
[email protected]aef92842010-05-21 16:54:364921void RenderView::OnSetAccessibilityFocus(int acc_obj_id) {
4922 if (!accessibility_.get())
4923 return;
[email protected]02ea2f312010-09-27 17:03:364924
4925 WebAccessibilityObject obj = accessibility_->getObjectById(acc_obj_id);
4926 WebAccessibilityObject root = webview()->accessibilityObject();
4927 if (!obj.isValid() || !root.isValid())
4928 return;
4929
4930 // By convention, calling SetFocus on the root of the tree should clear the
4931 // current focus. Otherwise set the focus to the new node.
4932 if (accessibility_->addOrGetId(obj) == accessibility_->addOrGetId(root))
4933 webview()->clearFocusedNode();
4934 else
4935 obj.setFocused(true);
[email protected]aef92842010-05-21 16:54:364936}
4937
4938void RenderView::OnAccessibilityDoDefaultAction(int acc_obj_id) {
4939 if (!accessibility_.get())
4940 return;
[email protected]02ea2f312010-09-27 17:03:364941
4942 WebAccessibilityObject obj = accessibility_->getObjectById(acc_obj_id);
4943 if (!obj.isValid())
4944 return;
4945
4946 obj.performDefaultAction();
[email protected]aef92842010-05-21 16:54:364947}
4948
[email protected]9892b472010-09-16 00:23:424949void RenderView::OnAccessibilityNotificationsAck() {
[email protected]54ec7f82010-10-21 22:32:514950 DCHECK(accessibility_ack_pending_);
4951 accessibility_ack_pending_ = false;
4952 SendPendingAccessibilityNotifications();
[email protected]520cb7d72010-08-31 11:54:314953}
4954
initial.commit09911bf2008-07-26 23:55:294955void RenderView::OnGetAllSavableResourceLinksForCurrentPage(
4956 const GURL& page_url) {
4957 // Prepare list to storage all savable resource links.
4958 std::vector<GURL> resources_list;
4959 std::vector<GURL> referrers_list;
4960 std::vector<GURL> frames_list;
4961 webkit_glue::SavableResourcesResult result(&resources_list,
4962 &referrers_list,
4963 &frames_list);
4964
[email protected]dbeb3952009-10-13 18:01:184965 if (!webkit_glue::GetAllSavableResourceLinksForCurrentPage(
4966 webview(),
4967 page_url,
4968 &result,
4969 chrome::kSavableSchemes)) {
initial.commit09911bf2008-07-26 23:55:294970 // If something is wrong when collecting all savable resource links,
4971 // send empty list to embedder(browser) to tell it failed.
4972 referrers_list.clear();
4973 resources_list.clear();
4974 frames_list.clear();
4975 }
4976
4977 // Send result of all savable resource links to embedder.
4978 Send(new ViewHostMsg_SendCurrentPageAllSavableResourceLinks(routing_id_,
4979 resources_list,
4980 referrers_list,
4981 frames_list));
4982}
4983
4984void RenderView::OnGetSerializedHtmlDataForCurrentPageWithLocalLinks(
[email protected]f6b48532009-02-12 01:56:324985 const std::vector<GURL>& links,
[email protected]fde6714d12009-02-18 22:39:314986 const std::vector<FilePath>& local_paths,
4987 const FilePath& local_directory_name) {
[email protected]d9ec5c0f2009-12-23 11:55:074988
4989 // Convert std::vector of GURLs to WebVector<WebURL>
4990 WebVector<WebURL> weburl_links(links);
4991
4992 // Convert std::vector of std::strings to WebVector<WebString>
4993 WebVector<WebString> webstring_paths(local_paths.size());
4994 for (size_t i = 0; i < local_paths.size(); i++)
4995 webstring_paths[i] = webkit_glue::FilePathToWebString(local_paths[i]);
4996
4997 WebPageSerializer::serialize(webview()->mainFrame(),
4998 true, this, weburl_links, webstring_paths,
4999 webkit_glue::FilePathToWebString(
5000 local_directory_name));
initial.commit09911bf2008-07-26 23:55:295001}
5002
[email protected]d9ec5c0f2009-12-23 11:55:075003void RenderView::didSerializeDataForFrame(const WebURL& frame_url,
5004 const WebCString& data,
5005 WebPageSerializerClient::PageSerializationStatus status) {
5006 Send(new ViewHostMsg_SendSerializedHtmlData(
5007 routing_id_,
5008 frame_url,
5009 data.data(),
5010 static_cast<int32>(status)));
initial.commit09911bf2008-07-26 23:55:295011}
5012
[email protected]9b18a84f2010-06-10 15:54:045013void RenderView::OnShouldClose() {
[email protected]26aa0482009-09-30 16:55:275014 bool should_close = webview()->dispatchBeforeUnloadEvent();
[email protected]04b4a6c2008-08-02 00:44:475015 Send(new ViewHostMsg_ShouldClose_ACK(routing_id_, should_close));
initial.commit09911bf2008-07-26 23:55:295016}
5017
[email protected]eb6b87a2009-07-24 15:57:395018void RenderView::OnClosePage(const ViewMsg_ClosePage_Params& params) {
initial.commit09911bf2008-07-26 23:55:295019 // TODO(creis): We'd rather use webview()->Close() here, but that currently
5020 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs
5021 // in the onunload handler from appearing. For now, we're bypassing that and
5022 // calling the FrameLoader's CloseURL method directly. This should be
5023 // revisited to avoid having two ways to close a page. Having a single way
5024 // to close that can run onunload is also useful for fixing
5025 // http://b/issue?id=753080.
[email protected]a5a65ac2010-11-05 18:14:365026 // TODO(davemoore) This code should be removed once willClose() gets
5027 // called when a page is destroyed. page_load_histograms_.Dump() is safe
5028 // to call multiple times for the same frame, but it will simplify things.
5029 page_load_histograms_.Dump(webview()->mainFrame());
5030 page_load_histograms_.ResetCrossFramePropertyAccess();
[email protected]26aa0482009-09-30 16:55:275031 webview()->dispatchUnloadEvent();
initial.commit09911bf2008-07-26 23:55:295032
[email protected]eb6b87a2009-07-24 15:57:395033 // Just echo back the params in the ACK.
5034 Send(new ViewHostMsg_ClosePage_ACK(routing_id_, params));
initial.commit09911bf2008-07-26 23:55:295035}
5036
5037void RenderView::OnThemeChanged() {
[email protected]6c8afae52009-01-22 02:24:575038#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:295039 gfx::NativeTheme::instance()->CloseHandles();
[email protected]f98d7e3c2010-09-13 22:30:465040 if (webview())
5041 webview()->themeChanged();
[email protected]6c8afae52009-01-22 02:24:575042#else // defined(OS_WIN)
5043 // TODO(port): we don't support theming on non-Windows platforms yet
5044 NOTIMPLEMENTED();
5045#endif
initial.commit09911bf2008-07-26 23:55:295046}
5047
[email protected]9b18a84f2010-06-10 15:54:045048void RenderView::OnHandleMessageFromExternalHost(const std::string& message,
5049 const std::string& origin,
5050 const std::string& target) {
[email protected]3ac14a052008-08-15 21:22:155051 if (message.empty())
5052 return;
[email protected]c091c2c2010-09-17 19:05:465053 GetExternalHostBindings()->ForwardMessageFromExternalHost(message, origin,
5054 target);
[email protected]3ac14a052008-08-15 21:22:155055}
5056
[email protected]0aa55312008-10-17 21:53:085057void RenderView::OnDisassociateFromPopupCount() {
5058 if (decrement_shared_popup_at_destruction_)
5059 shared_popup_counter_->data--;
5060 shared_popup_counter_ = new SharedRenderViewCounter(0);
5061 decrement_shared_popup_at_destruction_ = false;
5062}
5063
[email protected]15d79e12009-08-02 19:23:455064bool RenderView::MaybeLoadAlternateErrorPage(WebFrame* frame,
5065 const WebURLError& error,
5066 bool replace) {
5067 // We only show alternate error pages in the main frame. They are
5068 // intended to assist the user when navigating, so there is not much
5069 // value in showing them for failed subframes. Ideally, we would be
5070 // able to use the TYPED transition type for this, but that flag is
5071 // not preserved across page reloads.
[email protected]dd7daa82009-08-10 05:46:455072 if (frame->parent())
[email protected]15d79e12009-08-02 19:23:455073 return false;
5074
5075 // Use the alternate error page service if this is a DNS failure or
[email protected]c53976d52009-08-07 18:58:375076 // connection failure.
[email protected]15d79e12009-08-02 19:23:455077 int ec = error.reason;
5078 if (ec != net::ERR_NAME_NOT_RESOLVED &&
5079 ec != net::ERR_CONNECTION_FAILED &&
5080 ec != net::ERR_CONNECTION_REFUSED &&
5081 ec != net::ERR_ADDRESS_UNREACHABLE &&
[email protected]c53976d52009-08-07 18:58:375082 ec != net::ERR_CONNECTION_TIMED_OUT)
[email protected]15d79e12009-08-02 19:23:455083 return false;
5084
5085 const GURL& error_page_url = GetAlternateErrorPageURL(error.unreachableURL,
[email protected]7ccddb8c2009-08-04 17:36:555086 ec == net::ERR_NAME_NOT_RESOLVED ? DNS_ERROR : CONNECTION_ERROR);
[email protected]15d79e12009-08-02 19:23:455087 if (!error_page_url.is_valid())
5088 return false;
5089
5090 // Load an empty page first so there is an immediate response to the error,
5091 // and then kick off a request for the alternate error page.
[email protected]dd7daa82009-08-10 05:46:455092 frame->loadHTMLString(std::string(),
[email protected]144143c2010-10-28 08:17:365093 GURL(chrome::kUnreachableWebDataURL),
[email protected]15d79e12009-08-02 19:23:455094 error.unreachableURL,
5095 replace);
5096
5097 // Now, create a fetcher for the error page and associate it with the data
5098 // source we just created via the LoadHTMLString call. That way if another
5099 // navigation occurs, the fetcher will get destroyed.
5100 NavigationState* navigation_state =
[email protected]dd7daa82009-08-10 05:46:455101 NavigationState::FromDataSource(frame->provisionalDataSource());
[email protected]15d79e12009-08-02 19:23:455102 navigation_state->set_alt_error_page_fetcher(
5103 new AltErrorPageResourceFetcher(
5104 error_page_url, frame, error,
5105 NewCallback(this, &RenderView::AltErrorPageFinished)));
5106 return true;
5107}
5108
initial.commit09911bf2008-07-26 23:55:295109std::string RenderView::GetAltHTMLForTemplate(
5110 const DictionaryValue& error_strings, int template_resource_id) const {
[email protected]8a16266e2009-09-10 21:08:395111 const base::StringPiece template_html(
initial.commit09911bf2008-07-26 23:55:295112 ResourceBundle::GetSharedInstance().GetRawDataResource(
5113 template_resource_id));
5114
5115 if (template_html.empty()) {
5116 NOTREACHED() << "unable to load template. ID: " << template_resource_id;
5117 return "";
5118 }
[email protected]7cd22a52009-07-14 00:40:255119
initial.commit09911bf2008-07-26 23:55:295120 // "t" is the id of the templates root node.
[email protected]7cd22a52009-07-14 00:40:255121 return jstemplate_builder::GetTemplatesHtml(
initial.commit09911bf2008-07-26 23:55:295122 template_html, &error_strings, "t");
5123}
[email protected]0e79b9e2009-02-13 04:20:485124
[email protected]15d79e12009-08-02 19:23:455125void RenderView::AltErrorPageFinished(WebFrame* frame,
5126 const WebURLError& original_error,
5127 const std::string& html) {
5128 // Here, we replace the blank page we loaded previously.
[email protected]7ccddb8c2009-08-04 17:36:555129
5130 // If we failed to download the alternate error page, fall back to the
5131 // original error page if present. Otherwise, LoadNavigationErrorPage
5132 // will simply display a default error page.
5133 const std::string* html_to_load = &html;
5134 if (html.empty()) {
5135 NavigationState* navigation_state =
[email protected]dd7daa82009-08-10 05:46:455136 NavigationState::FromDataSource(frame->dataSource());
[email protected]7ccddb8c2009-08-04 17:36:555137 html_to_load = &navigation_state->postponed_data();
5138 }
[email protected]3f853a52010-09-13 19:15:085139 LoadNavigationErrorPage(frame, WebURLRequest(), original_error, *html_to_load,
5140 true);
[email protected]15d79e12009-08-02 19:23:455141}
5142
[email protected]30f75e62009-02-25 22:01:005143void RenderView::OnMoveOrResizeStarted() {
5144 if (webview())
[email protected]a72a1fa2010-05-03 22:18:475145 webview()->hidePopups();
[email protected]30f75e62009-02-25 22:01:005146}
5147
[email protected]30f75e62009-02-25 22:01:005148void RenderView::OnResize(const gfx::Size& new_size,
5149 const gfx::Rect& resizer_rect) {
[email protected]cda45c02010-02-25 19:28:105150 if (webview()) {
[email protected]a72a1fa2010-05-03 22:18:475151 webview()->hidePopups();
[email protected]cda45c02010-02-25 19:28:105152 if (send_preferred_size_changes_) {
[email protected]7339cd22010-10-27 00:11:205153 webview()->mainFrame()->setCanHaveScrollbars(
5154 should_display_scrollbars(new_size.width(), new_size.height()));
[email protected]cda45c02010-02-25 19:28:105155 }
5156 }
5157
[email protected]30f75e62009-02-25 22:01:005158 RenderWidget::OnResize(new_size, resizer_rect);
5159}
[email protected]0aa477bd2009-03-23 22:21:435160
[email protected]00c39612010-03-06 02:53:285161void RenderView::DidInitiatePaint() {
[email protected]53900d52010-06-16 04:25:015162 // Notify the pepper plugins that we started painting.
5163 pepper_delegate_.ViewInitiatedPaint();
5164
5165 // Notify any "old-style" pepper plugins that we started painting. This is
5166 // used for internal bookkeeping only, so we know that the set can not change
5167 // under us.
[email protected]00c39612010-03-06 02:53:285168 for (std::set<WebPluginDelegatePepper*>::iterator i =
[email protected]53900d52010-06-16 04:25:015169 current_oldstyle_pepper_plugins_.begin();
5170 i != current_oldstyle_pepper_plugins_.end(); ++i)
[email protected]00c39612010-03-06 02:53:285171 (*i)->RenderViewInitiatedPaint();
5172}
5173
5174void RenderView::DidFlushPaint() {
5175 // Notify any pepper plugins that we painted. This will call into the plugin,
5176 // and we it may ask to close itself as a result. This will, in turn, modify
5177 // our set, possibly invalidating the iterator. So we iterate on a copy that
5178 // won't change out from under us.
[email protected]53900d52010-06-16 04:25:015179 pepper_delegate_.ViewFlushedPaint();
5180
5181 // Notify any old-style pepper plugins that we painted. This will call into
5182 // the plugin, and we it may ask to close itself as a result. This will, in
5183 // turn, modify our set, possibly invalidating the iterator. So we iterate on
5184 // a copy that won't change out from under us.
5185 // This should be deleted when we don't support old Pepper anymore.
5186 std::set<WebPluginDelegatePepper*> plugins = current_oldstyle_pepper_plugins_;
[email protected]00c39612010-03-06 02:53:285187 for (std::set<WebPluginDelegatePepper*>::iterator i = plugins.begin();
5188 i != plugins.end(); ++i) {
5189 // The copy above makes sure our iterator is never invalid if some plugins
5190 // are destroyed. But some plugin may decide to close all of its views in
5191 // response to a paint in one of them, so we need to make sure each one is
5192 // still "current" before using it.
[email protected]53900d52010-06-16 04:25:015193 if (current_oldstyle_pepper_plugins_.find(*i) !=
5194 current_oldstyle_pepper_plugins_.end())
[email protected]00c39612010-03-06 02:53:285195 (*i)->RenderViewFlushedPaint();
5196 }
5197
5198 WebFrame* main_frame = webview()->mainFrame();
5199
5200 // If we have a provisional frame we are between the start and commit stages
5201 // of loading and we don't want to save stats.
5202 if (!main_frame->provisionalDataSource()) {
5203 WebDataSource* ds = main_frame->dataSource();
5204 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
5205 DCHECK(navigation_state);
5206
[email protected]05c8e502010-08-15 15:13:525207 // TODO(jar): The following code should all be inside a method, probably in
5208 // NavigatorState.
[email protected]00c39612010-03-06 02:53:285209 Time now = Time::Now();
5210 if (navigation_state->first_paint_time().is_null()) {
5211 navigation_state->set_first_paint_time(now);
5212 }
5213 if (navigation_state->first_paint_after_load_time().is_null() &&
5214 !navigation_state->finish_load_time().is_null()) {
5215 navigation_state->set_first_paint_after_load_time(now);
5216 }
5217 }
5218}
5219
[email protected]719b36f2010-12-22 20:36:465220webkit::ppapi::PluginInstance* RenderView::GetBitmapForOptimizedPluginPaint(
[email protected]ca4847f2010-09-24 05:39:155221 const gfx::Rect& paint_bounds,
5222 TransportDIB** dib,
5223 gfx::Rect* location,
5224 gfx::Rect* clip) {
5225 return pepper_delegate_.GetBitmapForOptimizedPluginPaint(
5226 paint_bounds, dib, location, clip);
5227}
5228
[email protected]d54169e92011-01-21 09:19:525229gfx::Size RenderView::GetScrollOffset() {
5230 WebKit::WebSize scroll_offset = webview()->mainFrame()->scrollOffset();
5231 return gfx::Size(scroll_offset.width, scroll_offset.height);
5232}
5233
[email protected]05d478752009-04-08 23:38:165234void RenderView::OnClearFocusedNode() {
5235 if (webview())
[email protected]26aa0482009-09-30 16:55:275236 webview()->clearFocusedNode();
[email protected]05d478752009-04-08 23:38:165237}
5238
[email protected]699ab0d2009-04-23 23:19:145239void RenderView::OnSetBackground(const SkBitmap& background) {
5240 if (webview())
[email protected]b4bb2502009-10-01 22:35:275241 webview()->setIsTransparent(!background.empty());
[email protected]699ab0d2009-04-23 23:19:145242
5243 SetBackground(background);
5244}
5245
[email protected]8c66c5a2009-07-22 17:26:345246void RenderView::OnSetActive(bool active) {
5247 if (webview())
[email protected]b4bb2502009-10-01 22:35:275248 webview()->setIsActive(active);
[email protected]d8fd6fa2010-02-01 15:54:265249
5250#if defined(OS_MACOSX)
5251 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5252 for (plugin_it = plugin_delegates_.begin();
5253 plugin_it != plugin_delegates_.end(); ++plugin_it) {
5254 (*plugin_it)->SetWindowFocus(active);
5255 }
5256#endif
[email protected]8c66c5a2009-07-22 17:26:345257}
5258
[email protected]6ce7abc52010-02-02 18:40:145259#if defined(OS_MACOSX)
5260void RenderView::OnSetWindowVisibility(bool visible) {
5261 // Inform plugins that their container has changed visibility.
5262 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5263 for (plugin_it = plugin_delegates_.begin();
5264 plugin_it != plugin_delegates_.end(); ++plugin_it) {
5265 (*plugin_it)->SetContainerVisibility(visible);
5266 }
5267}
[email protected]1e6e3c992010-02-08 15:52:135268
[email protected]4d51d5bf2010-07-26 18:48:265269void RenderView::OnWindowFrameChanged(const gfx::Rect& window_frame,
5270 const gfx::Rect& view_frame) {
[email protected]1e6e3c992010-02-08 15:52:135271 // Inform plugins that their window's frame has changed.
5272 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5273 for (plugin_it = plugin_delegates_.begin();
5274 plugin_it != plugin_delegates_.end(); ++plugin_it) {
5275 (*plugin_it)->WindowFrameChanged(window_frame, view_frame);
5276 }
5277}
[email protected]935d63d2010-10-15 23:31:555278
[email protected]b7f75862011-01-21 21:15:135279void RenderView::OnPluginImeCompositionCompleted(const string16& text,
[email protected]935d63d2010-10-15 23:31:555280 int plugin_id) {
[email protected]b7f75862011-01-21 21:15:135281 // WebPluginDelegateProxy is responsible for figuring out if this event
[email protected]935d63d2010-10-15 23:31:555282 // applies to it or not, so inform all the delegates.
5283 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5284 for (plugin_it = plugin_delegates_.begin();
5285 plugin_it != plugin_delegates_.end(); ++plugin_it) {
[email protected]b7f75862011-01-21 21:15:135286 (*plugin_it)->ImeCompositionCompleted(text, plugin_id);
[email protected]935d63d2010-10-15 23:31:555287 }
5288}
[email protected]6ce7abc52010-02-02 18:40:145289#endif // OS_MACOSX
5290
[email protected]8b8e7c92010-08-19 18:05:565291void RenderView::SendExtensionRequest(
5292 const ViewHostMsg_DomMessage_Params& params) {
5293 Send(new ViewHostMsg_ExtensionRequest(routing_id_, params));
[email protected]309d7a282009-03-24 09:18:275294}
5295
[email protected]c6619182009-05-12 14:59:325296void RenderView::OnExtensionResponse(int request_id,
5297 bool success,
5298 const std::string& response,
5299 const std::string& error) {
[email protected]0f6053962009-07-09 19:26:355300 ExtensionProcessBindings::HandleResponse(
5301 request_id, success, response, error);
[email protected]309d7a282009-03-24 09:18:275302}
[email protected]c20210e62009-04-03 21:39:265303
[email protected]a7ab1b782010-10-21 23:24:165304void RenderView::OnExtensionMessageInvoke(const std::string& extension_id,
5305 const std::string& function_name,
[email protected]d7259472010-03-24 08:40:495306 const ListValue& args,
[email protected]a807bbe2010-04-14 10:51:195307 const GURL& event_url) {
[email protected]d7259472010-03-24 08:40:495308 RendererExtensionBindings::Invoke(
[email protected]a7ab1b782010-10-21 23:24:165309 extension_id, function_name, args, this, event_url);
[email protected]7120f132009-07-20 21:05:375310}
5311
[email protected]9892b472010-09-16 00:23:425312void RenderView::postAccessibilityNotification(
5313 const WebAccessibilityObject& obj,
5314 WebAccessibilityNotification notification) {
[email protected]dea2d372010-09-25 06:41:145315 if (!accessibility_.get() && webview()) {
5316 // Load complete should be our first notification sent.
5317 // TODO(ctguil): Investigate if a different notification is a WebCore bug.
5318 if (notification != WebKit::WebAccessibilityNotificationLoadComplete)
5319 return;
5320
5321 // Create and initialize our accessibility cache
5322 accessibility_.reset(WebAccessibilityCache::create());
5323 accessibility_->initialize(webview());
5324 }
5325
[email protected]a3fa4f92010-09-30 22:19:335326 if (!accessibility_->isCached(obj)) {
5327 // The browser doesn't know about objects that are not in the cache. Send a
5328 // children change for the first accestor that actually is in the cache.
5329 WebAccessibilityObject parent = obj;
5330 while (parent.isValid() && !accessibility_->isCached(parent))
5331 parent = parent.parentObject();
5332
5333 DCHECK(parent.isValid() && accessibility_->isCached(parent));
5334 if (!parent.isValid())
5335 return;
5336 postAccessibilityNotification(
5337 parent, WebKit::WebAccessibilityNotificationChildrenChanged);
5338
5339 // The parent's children change takes care of the child's children change.
5340 if (notification == WebKit::WebAccessibilityNotificationChildrenChanged)
5341 return;
5342 }
5343
[email protected]dea2d372010-09-25 06:41:145344 // Add the accessibility object to our cache and ensure it's valid.
[email protected]54ec7f82010-10-21 22:32:515345 RendererAccessibilityNotification acc_notification;
5346 acc_notification.id = accessibility_->addOrGetId(obj);
5347 if (acc_notification.id < 0)
[email protected]a3018be2010-03-09 04:28:485348 return;
5349
[email protected]54ec7f82010-10-21 22:32:515350 if (!WebAccessibilityNotificationToViewHostMsg(
5351 notification,
5352 &acc_notification.type)) {
5353 return;
5354 }
5355
5356 // Discard duplicate accessibility notifications.
5357 for (uint32 i = 0; i < pending_accessibility_notifications_.size(); i++) {
5358 if (pending_accessibility_notifications_[i].id == acc_notification.id &&
5359 pending_accessibility_notifications_[i].type == acc_notification.type) {
[email protected]9892b472010-09-16 00:23:425360 return;
[email protected]54ec7f82010-10-21 22:32:515361 }
[email protected]9892b472010-09-16 00:23:425362 }
[email protected]54ec7f82010-10-21 22:32:515363 pending_accessibility_notifications_.push_back(acc_notification);
[email protected]a3018be2010-03-09 04:28:485364
[email protected]54ec7f82010-10-21 22:32:515365 if (!accessibility_ack_pending_ && accessibility_method_factory_.empty()) {
5366 // When no accessibility notifications are in-flight post a task to send
5367 // the notifications to the browser. We use PostTask so that we can queue
5368 // up additional notifications.
5369 MessageLoop::current()->PostTask(
5370 FROM_HERE,
5371 accessibility_method_factory_.NewRunnableMethod(
5372 &RenderView::SendPendingAccessibilityNotifications));
[email protected]520cb7d72010-08-31 11:54:315373 }
[email protected]520cb7d72010-08-31 11:54:315374}
5375
[email protected]c7a827e2011-01-21 00:27:015376void RenderView::OnPrint(bool is_preview) {
5377 DCHECK(webview());
5378 if (webview()) {
5379 // If the user has selected text in the currently focused frame we print
5380 // only that frame (this makes print selection work for multiple frames).
5381 if (webview()->focusedFrame()->hasSelection())
5382 Print(webview()->focusedFrame(), false, is_preview);
5383 else
5384 Print(webview()->mainFrame(), false, is_preview);
5385 }
5386}
5387
[email protected]212a49d2010-10-25 18:23:475388void RenderView::Print(WebFrame* frame,
5389 bool script_initiated,
5390 bool is_preview) {
[email protected]0fda7272009-06-26 15:49:335391 DCHECK(frame);
[email protected]521b2482011-01-15 00:10:105392 GetPrintWebViewHelper()->PrintFrame(frame, script_initiated, is_preview);
5393}
5394
5395PrintWebViewHelper* RenderView::GetPrintWebViewHelper() {
5396 if (print_helper_.get() == NULL)
[email protected]0fda7272009-06-26 15:49:335397 print_helper_.reset(new PrintWebViewHelper(this));
[email protected]521b2482011-01-15 00:10:105398 return print_helper_.get();
[email protected]0fda7272009-06-26 15:49:335399}
[email protected]446705872009-09-10 07:22:485400
5401void RenderView::OnSetEditCommandsForNextKeyEvent(
5402 const EditCommands& edit_commands) {
5403 edit_commands_ = edit_commands;
5404}
5405
[email protected]61f5a7b2009-12-22 22:21:205406void RenderView::OnExecuteCode(const ViewMsg_ExecuteCode_Params& params) {
[email protected]26aa0482009-09-30 16:55:275407 WebFrame* main_frame = webview() ? webview()->mainFrame() : NULL;
[email protected]912256b32009-09-18 09:47:355408 if (!main_frame) {
[email protected]61f5a7b2009-12-22 22:21:205409 Send(new ViewMsg_ExecuteCodeFinished(routing_id_, params.request_id,
5410 false));
[email protected]912256b32009-09-18 09:47:355411 return;
5412 }
5413
[email protected]fa7b6b542009-11-03 05:02:305414 WebDataSource* ds = main_frame->dataSource();
5415 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
5416 if (!navigation_state->user_script_idle_scheduler()->has_run()) {
[email protected]61f5a7b2009-12-22 22:21:205417 pending_code_execution_queue_.push(
5418 linked_ptr<ViewMsg_ExecuteCode_Params>(
5419 new ViewMsg_ExecuteCode_Params(params)));
[email protected]fa7b6b542009-11-03 05:02:305420 return;
5421 }
5422
[email protected]61f5a7b2009-12-22 22:21:205423 ExecuteCodeImpl(main_frame, params);
[email protected]fa7b6b542009-11-03 05:02:305424}
5425
5426void RenderView::ExecuteCodeImpl(WebFrame* frame,
[email protected]61f5a7b2009-12-22 22:21:205427 const ViewMsg_ExecuteCode_Params& params) {
[email protected]20ad2692009-11-20 18:27:205428 std::vector<WebFrame*> frame_vector;
5429 frame_vector.push_back(frame);
[email protected]61f5a7b2009-12-22 22:21:205430 if (params.all_frames)
[email protected]20ad2692009-11-20 18:27:205431 GetAllChildFrames(frame, &frame_vector);
5432
5433 for (std::vector<WebFrame*>::iterator frame_it = frame_vector.begin();
5434 frame_it != frame_vector.end(); ++frame_it) {
5435 WebFrame* frame = *frame_it;
[email protected]61f5a7b2009-12-22 22:21:205436 if (params.is_javascript) {
[email protected]2a521c52011-01-26 18:45:215437 const Extension* extension =
5438 render_thread_->GetExtensions()->GetByID(params.extension_id);
[email protected]be7e5cb2010-10-04 12:53:175439
[email protected]1f6228c2010-10-21 03:19:445440 // Since extension info is sent separately from user script info, they can
5441 // be out of sync. We just ignore this situation.
5442 if (!extension)
5443 continue;
5444
[email protected]2a521c52011-01-26 18:45:215445 if (!extension->CanExecuteScriptOnPage(frame->url(), NULL, NULL))
[email protected]61f5a7b2009-12-22 22:21:205446 continue;
5447
[email protected]20ad2692009-11-20 18:27:205448 std::vector<WebScriptSource> sources;
5449 sources.push_back(
[email protected]61f5a7b2009-12-22 22:21:205450 WebScriptSource(WebString::fromUTF8(params.code)));
5451 UserScriptSlave::InsertInitExtensionCode(&sources, params.extension_id);
[email protected]20ad2692009-11-20 18:27:205452 frame->executeScriptInIsolatedWorld(
[email protected]61f5a7b2009-12-22 22:21:205453 UserScriptSlave::GetIsolatedWorldId(params.extension_id),
[email protected]20ad2692009-11-20 18:27:205454 &sources.front(), sources.size(), EXTENSION_GROUP_CONTENT_SCRIPTS);
5455 } else {
[email protected]61f5a7b2009-12-22 22:21:205456 frame->insertStyleText(WebString::fromUTF8(params.code), WebString());
[email protected]20ad2692009-11-20 18:27:205457 }
[email protected]912256b32009-09-18 09:47:355458 }
5459
[email protected]61f5a7b2009-12-22 22:21:205460 Send(new ViewMsg_ExecuteCodeFinished(routing_id_, params.request_id, true));
[email protected]912256b32009-09-18 09:47:355461}
5462
[email protected]60c42a8c72009-10-09 04:08:595463void RenderView::Close() {
5464 // We need to grab a pointer to the doomed WebView before we destroy it.
5465 WebView* doomed = webview();
5466 RenderWidget::Close();
[email protected]625332e02010-12-14 07:48:495467 g_view_map.Get().erase(doomed);
[email protected]60c42a8c72009-10-09 04:08:595468}
5469
[email protected]446705872009-09-10 07:22:485470void RenderView::DidHandleKeyEvent() {
5471 edit_commands_.clear();
5472}
5473
[email protected]6a8ddba52010-09-05 04:38:065474void RenderView::DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {
[email protected]676126f72011-01-15 00:03:515475 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidHandleMouseEvent(event));
[email protected]6a8ddba52010-09-05 04:38:065476}
5477
[email protected]941e4552010-02-01 21:23:435478#if defined(OS_MACOSX)
5479void RenderView::OnWasHidden() {
5480 RenderWidget::OnWasHidden();
5481
5482 // Inform plugins that their container is no longer visible.
5483 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5484 for (plugin_it = plugin_delegates_.begin();
5485 plugin_it != plugin_delegates_.end(); ++plugin_it) {
5486 (*plugin_it)->SetContainerVisibility(false);
5487 }
5488}
5489
5490void RenderView::OnWasRestored(bool needs_repainting) {
5491 RenderWidget::OnWasRestored(needs_repainting);
5492
5493 // Inform plugins that their container is now visible.
5494 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5495 for (plugin_it = plugin_delegates_.begin();
5496 plugin_it != plugin_delegates_.end(); ++plugin_it) {
5497 (*plugin_it)->SetContainerVisibility(true);
5498 }
5499}
[email protected]784ea1ab2010-09-18 00:02:345500#endif // OS_MACOSX
[email protected]1e6e3c992010-02-08 15:52:135501
5502void RenderView::OnSetFocus(bool enable) {
5503 RenderWidget::OnSetFocus(enable);
5504
[email protected]7d3c02c2010-05-05 23:10:315505 if (webview() && webview()->isActive()) {
[email protected]589621b2010-09-23 22:01:075506 // Notify all NPAPI plugins.
[email protected]1e6e3c992010-02-08 15:52:135507 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5508 for (plugin_it = plugin_delegates_.begin();
5509 plugin_it != plugin_delegates_.end(); ++plugin_it) {
[email protected]784ea1ab2010-09-18 00:02:345510#if defined(OS_MACOSX)
[email protected]7d3c02c2010-05-05 23:10:315511 // RenderWidget's call to setFocus can cause the underlying webview's
5512 // activation state to change just like a call to setIsActive.
5513 if (enable)
5514 (*plugin_it)->SetWindowFocus(true);
[email protected]784ea1ab2010-09-18 00:02:345515#endif
[email protected]7d3c02c2010-05-05 23:10:315516 (*plugin_it)->SetContentAreaFocus(enable);
[email protected]1e6e3c992010-02-08 15:52:135517 }
[email protected]589621b2010-09-23 22:01:075518
5519 // Notify all Pepper plugins.
5520 pepper_delegate_.OnSetFocus(enable);
[email protected]1e6e3c992010-02-08 15:52:135521 }
5522}
[email protected]941e4552010-02-01 21:23:435523
[email protected]83dde542009-09-11 20:59:555524void RenderView::EnsureDocumentTag() {
5525 // TODO(darin): There's actually no reason for this to be here. We should
5526 // have the browser side manage the document tag.
5527#if defined(OS_MACOSX)
5528 if (!has_document_tag_) {
5529 // Make the call to get the tag.
5530 Send(new ViewHostMsg_GetDocumentTag(routing_id_, &document_tag_));
5531 has_document_tag_ = true;
5532 }
5533#endif
5534}
[email protected]12636df2009-09-28 22:32:215535
[email protected]43f28f832010-02-03 02:28:485536#if defined(OS_MACOSX)
[email protected]b7f75862011-01-21 21:15:135537void RenderView::PluginFocusChanged(bool focused, int plugin_id) {
5538 IPC::Message* msg = new ViewHostMsg_PluginFocusChanged(routing_id(),
5539 focused, plugin_id);
5540 Send(msg);
5541}
5542
5543void RenderView::StartPluginIme() {
5544 IPC::Message* msg = new ViewHostMsg_StartPluginIme(routing_id());
[email protected]935d63d2010-10-15 23:31:555545 // This message can be sent during event-handling, and needs to be delivered
5546 // within that context.
5547 msg->set_unblock(true);
5548 Send(msg);
5549}
5550
[email protected]ea04a4e12010-04-15 00:58:035551gfx::PluginWindowHandle RenderView::AllocateFakePluginWindowHandle(
[email protected]77e74db2010-08-04 17:46:235552 bool opaque, bool root) {
[email protected]43f28f832010-02-03 02:28:485553 gfx::PluginWindowHandle window = NULL;
5554 Send(new ViewHostMsg_AllocateFakePluginWindowHandle(
[email protected]77e74db2010-08-04 17:46:235555 routing_id(), opaque, root, &window));
[email protected]c36a9b62010-10-14 00:41:115556 if (window) {
5557 fake_plugin_window_handles_.insert(window);
5558 }
[email protected]43f28f832010-02-03 02:28:485559 return window;
5560}
5561
5562void RenderView::DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window) {
[email protected]c36a9b62010-10-14 00:41:115563 if (window && fake_plugin_window_handles_.find(window) !=
5564 fake_plugin_window_handles_.end()) {
[email protected]43f28f832010-02-03 02:28:485565 Send(new ViewHostMsg_DestroyFakePluginWindowHandle(routing_id(), window));
[email protected]c36a9b62010-10-14 00:41:115566 fake_plugin_window_handles_.erase(window);
5567 }
[email protected]43f28f832010-02-03 02:28:485568}
5569
[email protected]44ce0b12010-03-12 16:45:335570void RenderView::AcceleratedSurfaceSetIOSurface(gfx::PluginWindowHandle window,
5571 int32 width,
5572 int32 height,
5573 uint64 io_surface_identifier) {
5574 Send(new ViewHostMsg_AcceleratedSurfaceSetIOSurface(
[email protected]43f28f832010-02-03 02:28:485575 routing_id(), window, width, height, io_surface_identifier));
5576}
5577
[email protected]44ce0b12010-03-12 16:45:335578void RenderView::AcceleratedSurfaceSetTransportDIB(
5579 gfx::PluginWindowHandle window,
5580 int32 width,
5581 int32 height,
5582 TransportDIB::Handle transport_dib) {
5583 Send(new ViewHostMsg_AcceleratedSurfaceSetTransportDIB(
[email protected]1aef98132010-02-23 18:00:075584 routing_id(), window, width, height, transport_dib));
5585}
5586
[email protected]44ce0b12010-03-12 16:45:335587TransportDIB::Handle RenderView::AcceleratedSurfaceAllocTransportDIB(
5588 size_t size) {
[email protected]1aef98132010-02-23 18:00:075589 TransportDIB::Handle dib_handle;
5590 // Assume this is a synchronous RPC.
[email protected]ada848b12010-04-08 22:35:385591 if (Send(new ViewHostMsg_AllocTransportDIB(size, true, &dib_handle)))
[email protected]1aef98132010-02-23 18:00:075592 return dib_handle;
5593 // Return an invalid handle if Send() fails.
5594 return TransportDIB::DefaultHandleValue();
5595}
5596
[email protected]44ce0b12010-03-12 16:45:335597void RenderView::AcceleratedSurfaceFreeTransportDIB(TransportDIB::Id dib_id) {
[email protected]1aef98132010-02-23 18:00:075598 Send(new ViewHostMsg_FreeTransportDIB(dib_id));
5599}
5600
[email protected]44ce0b12010-03-12 16:45:335601void RenderView::AcceleratedSurfaceBuffersSwapped(
[email protected]f35d6672010-10-28 21:39:145602 gfx::PluginWindowHandle window, uint64 surface_id) {
5603 Send(new ViewHostMsg_AcceleratedSurfaceBuffersSwapped(
5604 routing_id(), window, surface_id));
[email protected]43f28f832010-02-03 02:28:485605}
5606#endif
[email protected]58c321d2010-02-19 12:11:285607
[email protected]cdaf8d02010-03-30 19:52:475608bool RenderView::ScheduleFileChooser(
5609 const ViewHostMsg_RunFileChooser_Params& params,
5610 WebFileChooserCompletion* completion) {
5611 static const size_t kMaximumPendingFileChooseRequests = 4;
5612 if (file_chooser_completions_.size() > kMaximumPendingFileChooseRequests) {
5613 // This sanity check prevents too many file choose requests from getting
5614 // queued which could DoS the user. Getting these is most likely a
5615 // programming error (there are many ways to DoS the user so it's not
5616 // considered a "real" security check), either in JS requesting many file
5617 // choosers to pop up, or in a plugin.
5618 //
5619 // TODO(brettw) we might possibly want to require a user gesture to open
5620 // a file picker, which will address this issue in a better way.
5621 return false;
5622 }
5623
5624 file_chooser_completions_.push_back(linked_ptr<PendingFileChooser>(
5625 new PendingFileChooser(params, completion)));
5626 if (file_chooser_completions_.size() == 1) {
5627 // Actually show the browse dialog when this is the first request.
5628 Send(new ViewHostMsg_RunFileChooser(routing_id_, params));
5629 }
5630 return true;
5631}
5632
[email protected]290838a2010-04-27 17:37:015633void RenderView::OnPageTranslated() {
5634 WebFrame* frame = webview()->mainFrame();
5635 if (!frame)
5636 return;
5637
[email protected]676126f72011-01-15 00:03:515638 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameTranslated(frame));
[email protected]290838a2010-04-27 17:37:015639}
5640
[email protected]0ff0ff32010-12-21 19:34:425641WebKit::WebGeolocationClient* RenderView::geolocationClient() {
[email protected]676126f72011-01-15 00:03:515642 if (!geolocation_dispatcher_)
5643 geolocation_dispatcher_ = new GeolocationDispatcher(this);
5644 return geolocation_dispatcher_;
[email protected]7e0c4702010-12-31 14:06:255645}
[email protected]61c9f032010-03-31 23:04:195646
[email protected]638694c2010-08-04 22:24:115647WebKit::WebSpeechInputController* RenderView::speechInputController(
5648 WebKit::WebSpeechInputListener* listener) {
[email protected]676126f72011-01-15 00:03:515649 if (!speech_input_dispatcher_)
5650 speech_input_dispatcher_ = new SpeechInputDispatcher(this, listener);
5651 return speech_input_dispatcher_;
[email protected]638694c2010-08-04 22:24:115652}
5653
[email protected]57ead352010-08-11 14:42:535654WebKit::WebDeviceOrientationClient* RenderView::deviceOrientationClient() {
[email protected]676126f72011-01-15 00:03:515655 if (!device_orientation_dispatcher_)
5656 device_orientation_dispatcher_ = new DeviceOrientationDispatcher(this);
5657 return device_orientation_dispatcher_;
[email protected]57ead352010-08-11 14:42:535658}
5659
[email protected]b75b8292010-10-01 07:28:255660void RenderView::zoomLimitsChanged(double minimum_level, double maximum_level) {
5661 // For now, don't remember plugin zoom values. We don't want to mix them with
5662 // normal web content (i.e. a fixed layout plugin would usually want them
5663 // different).
5664 bool remember = !webview()->mainFrame()->document().isPluginDocument();
5665
[email protected]b75b8292010-10-01 07:28:255666 int minimum_percent = static_cast<int>(
5667 WebView::zoomLevelToZoomFactor(minimum_level) * 100);
5668 int maximum_percent = static_cast<int>(
5669 WebView::zoomLevelToZoomFactor(maximum_level) * 100);
[email protected]b75b8292010-10-01 07:28:255670
5671 Send(new ViewHostMsg_UpdateZoomLimits(
5672 routing_id_, minimum_percent, maximum_percent, remember));
5673}
5674
5675void RenderView::zoomLevelChanged() {
5676 bool remember = !webview()->mainFrame()->document().isPluginDocument();
5677
[email protected]b75b8292010-10-01 07:28:255678 // Tell the browser which url got zoomed so it can update the menu and the
5679 // saved values if necessary
5680 Send(new ViewHostMsg_DidZoomURL(
[email protected]1cc58eb62010-10-01 22:38:415681 routing_id_, webview()->zoomLevel(), remember,
5682 GURL(webview()->mainFrame()->url())));
[email protected]b75b8292010-10-01 07:28:255683}
5684
[email protected]8079b362010-05-07 18:37:455685bool RenderView::IsNonLocalTopLevelNavigation(
[email protected]61c9f032010-03-31 23:04:195686 const GURL& url, WebKit::WebFrame* frame, WebKit::WebNavigationType type) {
[email protected]8079b362010-05-07 18:37:455687 // Must be a top level frame.
[email protected]61c9f032010-03-31 23:04:195688 if (frame->parent() != NULL)
5689 return false;
5690
[email protected]f0a3d0b2010-08-06 22:51:535691 // Navigations initiated within Webkit are not sent out to the external host
5692 // in the following cases.
[email protected]900eb2f12010-08-23 22:36:275693 // 1. The url scheme is not http/https
5694 // 2. There is no opener and this is not the first url being opened by this
5695 // RenderView.
5696 // 3. The origin of the url and the opener is the same in which case the
[email protected]f0a3d0b2010-08-06 22:51:535697 // opener relationship is maintained.
[email protected]f0a3d0b2010-08-06 22:51:535698 // 4. Reloads/form submits/back forward navigations
5699 if (!url.SchemeIs("http") && !url.SchemeIs("https"))
5700 return false;
5701
[email protected]2fc22d12010-12-02 23:08:165702 // Not interested in reloads/form submits/resubmits/back forward navigations.
[email protected]d0ed50d2010-06-22 01:01:325703 if (type != WebKit::WebNavigationTypeReload &&
[email protected]070c49c2010-07-13 22:22:015704 type != WebKit::WebNavigationTypeFormSubmitted &&
[email protected]2fc22d12010-12-02 23:08:165705 type != WebKit::WebNavigationTypeFormResubmitted &&
[email protected]070c49c2010-07-13 22:22:015706 type != WebKit::WebNavigationTypeBackForward) {
[email protected]d0ed50d2010-06-22 01:01:325707 // The opener relationship between the new window and the parent allows the
5708 // new window to script the parent and vice versa. This is not allowed if
5709 // the origins of the two domains are different. This can be treated as a
5710 // top level navigation and routed back to the host.
5711 WebKit::WebFrame* opener = frame->opener();
[email protected]900eb2f12010-08-23 22:36:275712 if (!opener) {
[email protected]fe9eb4f92010-08-27 23:16:475713 // Force link click navigations to always be routed to the host as they
5714 // may update session state on the server.
5715 if (type == WebKit::WebNavigationTypeLinkClicked)
5716 return true;
[email protected]900eb2f12010-08-23 22:36:275717 // If this is the first page being loaded by this RenderView instance then
5718 // it should stay here.
5719 if (page_id_ == -1) {
5720 return false;
5721 } else {
[email protected]d0ed50d2010-06-22 01:01:325722 return true;
[email protected]900eb2f12010-08-23 22:36:275723 }
[email protected]d0ed50d2010-06-22 01:01:325724 }
[email protected]900eb2f12010-08-23 22:36:275725
5726 if (url.GetOrigin() != GURL(opener->url()).GetOrigin())
5727 return true;
[email protected]d0ed50d2010-06-22 01:01:325728 }
[email protected]61c9f032010-03-31 23:04:195729 return false;
5730}
[email protected]2b06a992010-08-21 05:48:225731
[email protected]27a9ef32010-09-10 04:06:245732void RenderView::OnAsyncFileOpened(base::PlatformFileError error_code,
5733 IPC::PlatformFileForTransit file_for_transit,
5734 int message_id) {
5735 pepper_delegate_.OnAsyncFileOpened(
5736 error_code,
5737 IPC::PlatformFileForTransitToPlatformFile(file_for_transit),
5738 message_id);
5739}
[email protected]caf706f2010-10-26 17:54:085740
5741#if defined(OS_MACOSX)
5742void RenderView::OnSelectPopupMenuItem(int selected_index) {
[email protected]68dc3ba2010-12-06 21:43:155743 if (external_popup_menu_ == NULL) {
5744 // Crash reports from the field indicate that we can be notified with a
5745 // NULL external popup menu (we probably get notified twice).
5746 // If you hit this please file a bug against jcivelli and include the page
5747 // and steps to repro.
5748 NOTREACHED();
5749 return;
5750 }
[email protected]caf706f2010-10-26 17:54:085751 external_popup_menu_->DidSelectItem(selected_index);
5752 external_popup_menu_.reset();
5753}
5754#endif
[email protected]bb461532010-11-26 21:50:235755
5756void RenderView::AddErrorToRootConsole(const string16& message) {
5757 if (webview() && webview()->mainFrame()) {
5758 webview()->mainFrame()->addMessageToConsole(
5759 WebConsoleMessage(WebConsoleMessage::LevelError, message));
5760 }
5761}
[email protected]1b4209f2011-01-07 00:25:405762
5763#if defined(ENABLE_FLAPPER_HACKS)
5764void RenderView::OnConnectTcpACK(
5765 int request_id,
5766 IPC::PlatformFileForTransit socket_for_transit,
5767 const PP_Flash_NetAddress& local_addr,
5768 const PP_Flash_NetAddress& remote_addr) {
5769 pepper_delegate_.OnConnectTcpACK(
5770 request_id,
5771 IPC::PlatformFileForTransitToPlatformFile(socket_for_transit),
5772 local_addr,
5773 remote_addr);
5774}
5775#endif
[email protected]a6097f42011-01-10 08:50:515776
5777void RenderView::OnJavaScriptStressTestControl(int cmd, int param) {
5778 if (cmd == kJavaScriptStressTestSetStressRunType) {
5779 v8::Testing::SetStressRunType(static_cast<v8::Testing::StressType>(param));
5780 } else if (cmd == kJavaScriptStressTestPrepareStressRun) {
5781 v8::Testing::PrepareStressRun(param);
5782 }
5783}
[email protected]521b2482011-01-15 00:10:105784
[email protected]b29aa74b2011-01-31 21:41:085785void RenderView::OnContextMenuClosed(
5786 const webkit_glue::CustomContextMenuContext& custom_context) {
5787 if (custom_context.is_pepper_menu)
5788 pepper_delegate_.OnContextMenuClosed(custom_context);
5789 else
5790 context_menu_node_.reset();
[email protected]521b2482011-01-15 00:10:105791}