blob: d73032e5c1578270309278f437baaa5b1b92eb4b [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]46fd1ea42011-02-16 15:59:3334#include "chrome/common/extensions/extension_constants.h"
[email protected]ec7db282011-01-29 01:11:3635#include "chrome/common/extensions/extension_set.h"
[email protected]c5a272d2010-09-27 18:37:0836#include "chrome/common/file_system/file_system_dispatcher.h"
37#include "chrome/common/file_system/webfilesystem_callback_dispatcher.h"
[email protected]bb461532010-11-26 21:50:2338#include "chrome/common/json_value_serializer.h"
initial.commit09911bf2008-07-26 23:55:2939#include "chrome/common/jstemplate_builder.h"
[email protected]97c5c592010-08-03 08:22:2140#include "chrome/common/notification_service.h"
[email protected]630e26b2008-10-14 22:55:1741#include "chrome/common/page_zoom.h"
[email protected]f0557932011-01-25 20:20:5142#include "chrome/common/pepper_messages.h"
[email protected]4e0616e2010-05-28 14:55:5343#include "chrome/common/pepper_plugin_registry.h"
[email protected]e09ba552009-02-05 03:26:2944#include "chrome/common/render_messages.h"
[email protected]a527a022011-02-10 02:32:3645#include "chrome/common/render_messages_params.h"
[email protected]13a1e4c3c2011-02-03 21:07:0946#include "chrome/common/render_view_commands.h"
[email protected]9b6f40e2009-06-11 15:54:2647#include "chrome/common/renderer_preferences.h"
initial.commit09911bf2008-07-26 23:55:2948#include "chrome/common/thumbnail_score.h"
[email protected]6de74452009-02-25 18:04:5949#include "chrome/common/url_constants.h"
[email protected]38789d82010-11-17 06:03:4450#include "chrome/common/web_apps.h"
[email protected]534c66c2010-04-28 22:53:1151#include "chrome/common/window_container_type.h"
initial.commit09911bf2008-07-26 23:55:2952#include "chrome/renderer/about_handler.h"
[email protected]5fb88962009-04-16 19:03:2553#include "chrome/renderer/audio_message_filter.h"
[email protected]78192082011-01-29 05:43:4454#include "chrome/renderer/autofill/autofill_agent.h"
55#include "chrome/renderer/autofill/form_manager.h"
56#include "chrome/renderer/autofill/password_autofill_manager.h"
[email protected]2f979172010-09-16 21:54:0357#include "chrome/renderer/automation/dom_automation_controller.h"
[email protected]00152e92010-07-19 11:47:4058#include "chrome/renderer/blocked_plugin.h"
[email protected]57ead352010-08-11 14:42:5359#include "chrome/renderer/device_orientation_dispatcher.h"
[email protected]e4ac5df2009-03-17 15:33:1160#include "chrome/renderer/devtools_agent.h"
61#include "chrome/renderer/devtools_client.h"
[email protected]912256b32009-09-18 09:47:3562#include "chrome/renderer/extension_groups.h"
[email protected]4026ce1e2010-09-14 19:35:0463#include "chrome/renderer/extensions/bindings_utils.h"
[email protected]f816c012009-06-26 21:48:3264#include "chrome/renderer/extensions/event_bindings.h"
[email protected]0f6053962009-07-09 19:26:3565#include "chrome/renderer/extensions/extension_process_bindings.h"
[email protected]78d5cfe2011-02-04 08:43:2266#include "chrome/renderer/extensions/extension_resource_request_policy.h"
[email protected]7120f132009-07-20 21:05:3767#include "chrome/renderer/extensions/renderer_extension_bindings.h"
[email protected]2f979172010-09-16 21:54:0368#include "chrome/renderer/external_host_bindings.h"
[email protected]caf706f2010-10-26 17:54:0869#include "chrome/renderer/external_popup_menu.h"
[email protected]ffd0abd2010-12-14 17:45:5070#include "chrome/renderer/geolocation_dispatcher.h"
[email protected]3bb08602010-10-07 21:47:1771#include "chrome/renderer/ggl/ggl.h"
[email protected]90109412010-12-15 17:14:2472#include "chrome/renderer/load_progress_tracker.h"
initial.commit09911bf2008-07-26 23:55:2973#include "chrome/renderer/localized_error.h"
[email protected]6f56d482009-02-20 05:02:5674#include "chrome/renderer/media/audio_renderer_impl.h"
[email protected]ee68378a2010-08-10 01:05:4175#include "chrome/renderer/media/ipc_video_decoder.h"
[email protected]ed3fb032009-06-16 19:50:5676#include "chrome/renderer/navigation_state.h"
[email protected]90e908552009-10-05 01:40:1277#include "chrome/renderer/notification_provider.h"
[email protected]cae8c8492011-03-03 11:12:1878#include "chrome/renderer/p2p/socket_dispatcher.h"
[email protected]6a8ddba52010-09-05 04:38:0679#include "chrome/renderer/page_click_tracker.h"
[email protected]a5a65ac2010-11-05 18:14:3680#include "chrome/renderer/page_load_histograms.h"
[email protected]8beff0762009-09-29 02:18:3081#include "chrome/renderer/plugin_channel_host.h"
[email protected]d81c1e52009-06-03 22:09:5082#include "chrome/renderer/print_web_view_helper.h"
[email protected]39008c02009-02-11 23:59:2583#include "chrome/renderer/render_process.h"
[email protected]00c39612010-03-06 02:53:2884#include "chrome/renderer/render_thread.h"
[email protected]676126f72011-01-15 00:03:5185#include "chrome/renderer/render_view_observer.h"
[email protected]4d51d5bf2010-07-26 18:48:2686#include "chrome/renderer/render_view_visitor.h"
[email protected]484955942010-08-19 16:13:1887#include "chrome/renderer/render_widget_fullscreen.h"
[email protected]79c7bed2010-09-14 22:28:3988#include "chrome/renderer/render_widget_fullscreen_pepper.h"
[email protected]035545f2010-04-09 13:10:2189#include "chrome/renderer/renderer_webapplicationcachehost_impl.h"
[email protected]bd92c3a2010-01-13 05:02:3490#include "chrome/renderer/renderer_webstoragenamespace_impl.h"
[email protected]32ca14682011-02-16 19:05:1091#include "chrome/renderer/safe_browsing/malware_dom_details.h"
[email protected]3ead1322010-11-19 20:01:0092#include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h"
[email protected]6c2f73202011-02-14 20:21:5493#include "chrome/renderer/searchbox.h"
[email protected]638694c2010-08-04 22:24:1194#include "chrome/renderer/speech_input_dispatcher.h"
[email protected]5efcef62011-02-22 09:00:1395#include "chrome/renderer/spellchecker/spellcheck_provider.h"
[email protected]85c55dc2009-11-06 03:05:4696#include "chrome/renderer/spellchecker/spellcheck.h"
[email protected]81273622011-02-02 03:56:1397#include "chrome/renderer/translate_helper.h"
[email protected]25e18f82010-10-27 16:38:4398#include "chrome/renderer/user_script_idle_scheduler.h"
[email protected]0938d3c2009-01-09 20:37:3599#include "chrome/renderer/user_script_slave.h"
initial.commit09911bf2008-07-26 23:55:29100#include "chrome/renderer/visitedlink_slave.h"
[email protected]c50008512011-02-03 01:17:27101#include "chrome/renderer/web_ui_bindings.h"
[email protected]5aa6a312010-11-06 00:00:07102#include "chrome/renderer/webgraphicscontext3d_command_buffer_impl.h"
[email protected]d439ba072009-10-17 22:32:29103#include "chrome/renderer/webplugin_delegate_pepper.h"
[email protected]ba4b17f2009-02-11 21:32:29104#include "chrome/renderer/webplugin_delegate_proxy.h"
[email protected]9c00f002009-11-05 22:37:42105#include "chrome/renderer/websharedworker_proxy.h"
[email protected]eb47a132009-03-04 00:39:56106#include "chrome/renderer/webworker_proxy.h"
[email protected]34ac8f32009-02-22 23:03:27107#include "grit/generated_resources.h"
108#include "grit/renderer_resources.h"
[email protected]f8db8132010-12-03 00:27:49109#include "media/base/filter_collection.h"
[email protected]ee68378a2010-08-10 01:05:41110#include "media/base/media_switches.h"
[email protected]f78d1dfc2011-01-15 07:09:27111#include "media/base/message_loop_factory_impl.h"
[email protected]f11ca0732009-04-11 00:09:34112#include "net/base/data_url.h"
initial.commit09911bf2008-07-26 23:55:29113#include "net/base/escape.h"
114#include "net/base/net_errors.h"
[email protected]52c68652010-12-07 17:47:04115#include "net/http/http_util.h"
[email protected]9d9f1bb2011-02-23 22:10:57116#include "ppapi/c/private/ppb_flash_net_connector.h"
[email protected]c399a8a2008-11-22 19:38:00117#include "skia/ext/bitmap_platform_device.h"
[email protected]83c9e6552008-12-03 16:22:10118#include "skia/ext/image_operations.h"
[email protected]8bd0fe62011-01-17 06:44:37119#include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityCache.h"
120#include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObject.h"
121#include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h"
122#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
123#include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h"
124#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
125#include "third_party/WebKit/Source/WebKit/chromium/public/WebDragData.h"
126#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
127#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserParams.h"
128#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystem.h"
129#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystemCallbacks.h"
130#include "third_party/WebKit/Source/WebKit/chromium/public/WebFindOptions.h"
131#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement.h"
132#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h"
133#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
134#include "third_party/WebKit/Source/WebKit/chromium/public/WebGraphicsContext3D.h"
135#include "third_party/WebKit/Source/WebKit/chromium/public/WebHistoryItem.h"
136#include "third_party/WebKit/Source/WebKit/chromium/public/WebImage.h"
137#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h"
[email protected]232a5812011-03-04 22:42:08138#include "third_party/WebKit/Source/WebKit/chromium/public/WebNetworkStateNotifier.h"
[email protected]8bd0fe62011-01-17 06:44:37139#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
140#include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeList.h"
141#include "third_party/WebKit/Source/WebKit/chromium/public/WebPageSerializer.h"
142#include "third_party/WebKit/Source/WebKit/chromium/public/WebPlugin.h"
143#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
144#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginDocument.h"
145#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h"
146#include "third_party/WebKit/Source/WebKit/chromium/public/WebPoint.h"
147#include "third_party/WebKit/Source/WebKit/chromium/public/WebRange.h"
148#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
149#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h"
150#include "third_party/WebKit/Source/WebKit/chromium/public/WebSearchableFormData.h"
151#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
152#include "third_party/WebKit/Source/WebKit/chromium/public/WebSettings.h"
153#include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
154#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageNamespace.h"
155#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
[email protected]5efcef62011-02-22 09:00:13156#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextCheckingCompletion.h"
157#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextCheckingResult.h"
[email protected]8bd0fe62011-01-17 06:44:37158#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
159#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h"
160#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h"
161#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"
162#include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
163#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
164#include "third_party/WebKit/Source/WebKit/chromium/public/WebWindowFeatures.h"
[email protected]6fdd4182010-10-14 23:59:26165#include "third_party/cld/encodings/compact_lang_det/win/cld_unicodetext.h"
166#include "third_party/skia/include/core/SkBitmap.h"
[email protected]9dd7e3d72011-01-20 18:27:06167#include "ui/base/message_box_flags.h"
[email protected]c051a1b2011-01-21 23:30:17168#include "ui/base/l10n/l10n_util.h"
[email protected]42ce29d2011-01-20 23:19:46169#include "ui/base/resource/resource_bundle.h"
[email protected]08397d52011-02-05 01:53:38170#include "ui/gfx/color_utils.h"
171#include "ui/gfx/favicon_size.h"
172#include "ui/gfx/native_widget_types.h"
173#include "ui/gfx/point.h"
174#include "ui/gfx/rect.h"
175#include "ui/gfx/skbitmap_operations.h"
[email protected]882b7b22010-10-05 03:34:53176#include "v8/include/v8.h"
[email protected]a6097f42011-01-10 08:50:51177#include "v8/include/v8-testing.h"
[email protected]80f584d92010-01-21 03:59:04178#include "webkit/appcache/web_application_cache_host_impl.h"
[email protected]25e18f82010-10-27 16:38:43179#include "webkit/glue/alt_error_page_resource_fetcher.h"
[email protected]7a4de7a62010-08-17 18:38:24180#include "webkit/glue/context_menu.h"
initial.commit09911bf2008-07-26 23:55:29181#include "webkit/glue/dom_operations.h"
[email protected]b1438212010-04-03 00:30:59182#include "webkit/glue/form_data.h"
[email protected]95056b582010-02-18 01:29:24183#include "webkit/glue/form_field.h"
[email protected]95056b582010-02-18 01:29:24184#include "webkit/glue/glue_serialize.h"
[email protected]f11ca0732009-04-11 00:09:34185#include "webkit/glue/image_decoder.h"
[email protected]4d51d5bf2010-07-26 18:48:26186#include "webkit/glue/image_resource_fetcher.h"
[email protected]85cc78c2010-05-04 18:30:09187#include "webkit/glue/media/video_renderer_impl.h"
[email protected]4d51d5bf2010-07-26 18:48:26188#include "webkit/glue/password_form_dom_manager.h"
[email protected]bb461532010-11-26 21:50:23189#include "webkit/glue/resource_fetcher.h"
[email protected]85cc78c2010-05-04 18:30:09190#include "webkit/glue/site_isolation_metrics.h"
[email protected]7a4de7a62010-08-17 18:38:24191#include "webkit/glue/webaccessibility.h"
initial.commit09911bf2008-07-26 23:55:29192#include "webkit/glue/webdropdata.h"
[email protected]a6939ca42011-02-18 17:58:07193#include "webkit/glue/webkit_constants.h"
initial.commit09911bf2008-07-26 23:55:29194#include "webkit/glue/webkit_glue.h"
[email protected]add51772009-06-11 18:25:17195#include "webkit/glue/webmediaplayer_impl.h"
[email protected]191eb3f72010-12-21 06:27:50196#include "webkit/plugins/npapi/default_plugin_shared.h"
197#include "webkit/plugins/npapi/plugin_list.h"
198#include "webkit/plugins/npapi/webplugin_delegate.h"
199#include "webkit/plugins/npapi/webplugin_delegate_impl.h"
200#include "webkit/plugins/npapi/webplugin_impl.h"
201#include "webkit/plugins/npapi/webview_plugin.h"
[email protected]0bd753682010-12-16 18:15:52202#include "webkit/plugins/ppapi/ppapi_webplugin_impl.h"
initial.commit09911bf2008-07-26 23:55:29203
[email protected]6c8afae52009-01-22 02:24:57204#if defined(OS_WIN)
205// TODO(port): these files are currently Windows only because they concern:
[email protected]6c8afae52009-01-22 02:24:57206// * theming
[email protected]08397d52011-02-05 01:53:38207#include "ui/gfx/native_theme_win.h"
[email protected]6981f7f2010-03-09 00:53:03208#elif defined(USE_X11)
[email protected]8bd0fe62011-01-17 06:44:37209#include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebRenderTheme.h"
[email protected]08397d52011-02-05 01:53:38210#include "ui/gfx/native_theme_linux.h"
[email protected]78043bdd2010-04-05 18:45:33211#elif defined(OS_MACOSX)
212#include "skia/ext/skia_utils_mac.h"
[email protected]6c8afae52009-01-22 02:24:57213#endif
214
[email protected]c7287a92009-11-04 20:06:15215using WebKit::WebAccessibilityCache;
[email protected]9892b472010-09-16 00:23:42216using WebKit::WebAccessibilityNotification;
[email protected]cc0445f2009-10-13 16:09:08217using WebKit::WebAccessibilityObject;
[email protected]035545f2010-04-09 13:10:21218using WebKit::WebApplicationCacheHost;
219using WebKit::WebApplicationCacheHostClient;
[email protected]6fdd4182010-10-14 23:59:26220using WebKit::WebCString;
[email protected]1c83eb42009-09-11 21:08:41221using WebKit::WebColor;
222using WebKit::WebColorName;
[email protected]0dea3ea2009-03-31 23:30:59223using WebKit::WebConsoleMessage;
[email protected]79e37442009-10-09 18:17:44224using WebKit::WebContextMenuData;
[email protected]b921cfd22010-02-25 16:57:51225using WebKit::WebCookieJar;
[email protected]e6f546c32009-07-01 17:12:55226using WebKit::WebData;
[email protected]726985e22009-06-18 21:09:28227using WebKit::WebDataSource;
[email protected]2661b332009-11-03 18:42:29228using WebKit::WebDevToolsAgent;
[email protected]5bc8fe92010-03-11 18:19:00229using WebKit::WebDocument;
[email protected]e80c73b2009-04-07 23:24:58230using WebKit::WebDragData;
[email protected]1d9f4132009-09-08 17:29:25231using WebKit::WebDragOperation;
232using WebKit::WebDragOperationsMask;
[email protected]79dbc662009-09-04 05:42:51233using WebKit::WebEditingAction;
[email protected]9b66f34bf2010-10-27 20:45:51234using WebKit::WebElement;
[email protected]caf706f2010-10-26 17:54:08235using WebKit::WebExternalPopupMenu;
236using WebKit::WebExternalPopupMenuClient;
[email protected]cdaf8d02010-03-30 19:52:47237using WebKit::WebFileChooserCompletion;
[email protected]2b06a992010-08-21 05:48:22238using WebKit::WebFileSystem;
239using WebKit::WebFileSystemCallbacks;
[email protected]6069da8c2009-10-20 20:33:49240using WebKit::WebFindOptions;
[email protected]b1438212010-04-03 00:30:59241using WebKit::WebFormControlElement;
[email protected]979c28b2009-11-07 01:30:48242using WebKit::WebFormElement;
[email protected]dd7daa82009-08-10 05:46:45243using WebKit::WebFrame;
[email protected]ca948a22009-06-25 19:36:17244using WebKit::WebHistoryItem;
[email protected]c27ae592010-03-18 15:24:41245using WebKit::WebImage;
[email protected]e6efd022010-03-31 09:34:50246using WebKit::WebInputElement;
[email protected]3d9689372009-09-10 04:29:17247using WebKit::WebMediaPlayer;
[email protected]952cb702009-10-07 05:50:28248using WebKit::WebMediaPlayerAction;
[email protected]3d9689372009-09-10 04:29:17249using WebKit::WebMediaPlayerClient;
[email protected]4873c7d2009-07-16 06:36:28250using WebKit::WebNavigationPolicy;
[email protected]726985e22009-06-18 21:09:28251using WebKit::WebNavigationType;
[email protected]232a5812011-03-04 22:42:08252using WebKit::WebNetworkStateNotifier;
[email protected]79dbc662009-09-04 05:42:51253using WebKit::WebNode;
[email protected]d9ec5c0f2009-12-23 11:55:07254using WebKit::WebPageSerializer;
255using WebKit::WebPageSerializerClient;
[email protected]3d9689372009-09-10 04:29:17256using WebKit::WebPlugin;
[email protected]00152e92010-07-19 11:47:40257using WebKit::WebPluginContainer;
[email protected]24a7f3c2010-03-25 08:26:49258using WebKit::WebPluginDocument;
[email protected]aad51d1c2010-08-05 08:38:09259using WebKit::WebPluginParams;
[email protected]48c9cf2d2009-09-16 16:47:52260using WebKit::WebPoint;
[email protected]88efb7ec2009-07-14 16:32:59261using WebKit::WebPopupMenuInfo;
[email protected]79dbc662009-09-04 05:42:51262using WebKit::WebRange;
[email protected]b3f2b912009-04-09 16:18:52263using WebKit::WebRect;
[email protected]4f999132009-03-31 18:08:40264using WebKit::WebScriptSource;
[email protected]ce0e250d2009-10-23 21:00:35265using WebKit::WebSearchableFormData;
[email protected]e3d60e5d2009-09-25 21:08:29266using WebKit::WebSecurityOrigin;
[email protected]2fab253a2009-08-17 23:00:59267using WebKit::WebSettings;
[email protected]9c00f002009-11-05 22:37:42268using WebKit::WebSharedWorker;
[email protected]8649fb32009-06-26 17:51:02269using WebKit::WebSize;
[email protected]bd92c3a2010-01-13 05:02:34270using WebKit::WebStorageNamespace;
[email protected]726985e22009-06-18 21:09:28271using WebKit::WebString;
[email protected]79dbc662009-09-04 05:42:51272using WebKit::WebTextAffinity;
[email protected]5efcef62011-02-22 09:00:13273using WebKit::WebTextCheckingResult;
[email protected]de570ef2009-07-29 18:27:52274using WebKit::WebTextDirection;
[email protected]726985e22009-06-18 21:09:28275using WebKit::WebURL;
276using WebKit::WebURLError;
277using WebKit::WebURLRequest;
278using WebKit::WebURLResponse;
[email protected]4873c7d2009-07-16 06:36:28279using WebKit::WebVector;
[email protected]50ae00ef2009-10-19 05:11:03280using WebKit::WebView;
[email protected]4873c7d2009-07-16 06:36:28281using WebKit::WebWidget;
[email protected]6fdd4182010-10-14 23:59:26282using WebKit::WebWindowFeatures;
[email protected]27ba8532009-04-24 20:22:43283using WebKit::WebWorker;
284using WebKit::WebWorkerClient;
[email protected]6fdd4182010-10-14 23:59:26285using appcache::WebApplicationCacheHostImpl;
[email protected]78192082011-01-29 05:43:44286using autofill::AutoFillAgent;
287using autofill::FormManager;
288using autofill::PasswordAutoFillManager;
[email protected]6fdd4182010-10-14 23:59:26289using base::Time;
290using base::TimeDelta;
291using webkit_glue::AltErrorPageResourceFetcher;
292using webkit_glue::FormData;
293using webkit_glue::FormField;
294using webkit_glue::ImageResourceFetcher;
295using webkit_glue::PasswordForm;
296using webkit_glue::PasswordFormDomManager;
[email protected]bb461532010-11-26 21:50:23297using webkit_glue::ResourceFetcher;
[email protected]6fdd4182010-10-14 23:59:26298using webkit_glue::SiteIsolationMetrics;
299using webkit_glue::WebAccessibility;
[email protected]e1acf6f2008-10-27 20:43:33300
initial.commit09911bf2008-07-26 23:55:29301//-----------------------------------------------------------------------------
302
[email protected]3354d3e2010-06-10 19:53:02303typedef std::map<WebKit::WebView*, RenderView*> ViewMap;
[email protected]625332e02010-12-14 07:48:49304static base::LazyInstance<ViewMap> g_view_map(base::LINKER_INITIALIZED);
[email protected]3354d3e2010-06-10 19:53:02305
initial.commit09911bf2008-07-26 23:55:29306// define to write the time necessary for thumbnail/DOM text retrieval,
307// respectively, into the system debug log
initial.commit09911bf2008-07-26 23:55:29308// #define TIME_TEXT_RETRIEVAL
309
310// maximum number of characters in the document to index, any text beyond this
311// point will be clipped
[email protected]6c8afae52009-01-22 02:24:57312static const size_t kMaxIndexChars = 65535;
initial.commit09911bf2008-07-26 23:55:29313
314// Size of the thumbnails that we'll generate
[email protected]8b4f4892009-09-04 21:52:37315static const int kThumbnailWidth = 212;
316static const int kThumbnailHeight = 132;
initial.commit09911bf2008-07-26 23:55:29317
318// Delay in milliseconds that we'll wait before capturing the page contents
319// and thumbnail.
320static const int kDelayForCaptureMs = 500;
321
322// Typically, we capture the page data once the page is loaded.
323// Sometimes, the page never finishes to load, preventing the page capture
324// To workaround this problem, we always perform a capture after the following
325// delay.
326static const int kDelayForForcedCaptureMs = 6000;
327
[email protected]882daa92009-11-05 16:31:31328// Time, in seconds, we delay before sending content state changes (such as form
329// state and scroll position) to the browser. We delay sending changes to avoid
330// spamming the browser.
331// To avoid having tab/session restore require sending a message to get the
332// current content state during tab closing we use a shorter timeout for the
333// foreground renderer. This means there is a small window of time from which
334// content state is modified and not sent to session restore, but this is
335// better than having to wake up all renderers during shutdown.
336static const int kDelaySecondsForContentStateSyncHidden = 5;
337static const int kDelaySecondsForContentStateSync = 1;
initial.commit09911bf2008-07-26 23:55:29338
[email protected]0aa55312008-10-17 21:53:08339// The maximum number of popups that can be spawned from one page.
340static const int kMaximumNumberOfUnacknowledgedPopups = 25;
341
[email protected]6fdd4182010-10-14 23:59:26342static const char kBackForwardNavigationScheme[] = "history";
[email protected]50b691c2008-10-31 19:08:35343
[email protected]726985e22009-06-18 21:09:28344static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
345 WebVector<WebURL> urls;
346 ds->redirectChain(urls);
347 result->reserve(urls.size());
348 for (size_t i = 0; i < urls.size(); ++i)
349 result->push_back(urls[i]);
350}
351
[email protected]30507922010-01-15 16:48:23352static bool PaintViewIntoCanvas(WebView* view,
353 skia::PlatformCanvas& canvas) {
354 view->layout();
355 const WebSize& size = view->size();
356
357 if (!canvas.initialize(size.width, size.height, true))
358 return false;
359
360 view->paint(webkit_glue::ToWebCanvas(&canvas),
361 WebRect(0, 0, size.width, size.height));
362 // TODO: Add a way to snapshot the whole page, not just the currently
363 // visible part.
364
365 return true;
366}
367
368// Calculates how "boring" a thumbnail is. The boring score is the
369// 0,1 ranged percentage of pixels that are the most common
370// luma. Higher boring scores indicate that a higher percentage of a
371// bitmap are all the same brightness.
372static double CalculateBoringScore(SkBitmap* bitmap) {
373 int histogram[256] = {0};
374 color_utils::BuildLumaHistogram(bitmap, histogram);
375
376 int color_count = *std::max_element(histogram, histogram + 256);
377 int pixel_count = bitmap->width() * bitmap->height();
378 return static_cast<double>(color_count) / pixel_count;
379}
380
[email protected]12bc8472010-04-15 07:29:40381// True if |frame| contains content that is white-listed for content settings.
382static bool IsWhitelistedForContentSettings(WebFrame* frame) {
383 WebSecurityOrigin origin = frame->securityOrigin();
384 if (origin.isEmpty())
385 return false; // Uninitialized document?
386
387 if (EqualsASCII(origin.protocol(), chrome::kChromeUIScheme))
388 return true; // Browser UI elements should still work.
389
390 // If the scheme is ftp: or file:, an empty file name indicates a directory
391 // listing, which requires JavaScript to function properly.
392 GURL frame_url = frame->url();
393 const char* kDirProtocols[] = { "ftp", "file" };
394 for (size_t i = 0; i < arraysize(kDirProtocols); ++i) {
395 if (EqualsASCII(origin.protocol(), kDirProtocols[i])) {
396 return frame_url.SchemeIs(kDirProtocols[i]) &&
397 frame_url.ExtractFileName().empty();
398 }
399 }
400
401 return false;
402}
403
[email protected]3a8eecb2010-04-22 23:56:30404// Returns true if the frame is navigating to an URL either into or out of an
405// extension app's extent.
[email protected]08e94b82010-12-15 22:51:04406// TODO(creis): Temporary workaround for crbug.com/65953: Only return true if
[email protected]88c15e972011-02-05 04:19:53407// we would enter an extension app's extent from a non-app, or if we leave an
408// extension with no web extent. We avoid swapping processes to exit a hosted
409// app with a web extent for now, since we do not yet restore context (such
[email protected]08e94b82010-12-15 22:51:04410// as window.opener) if the window navigates back.
[email protected]88c15e972011-02-05 04:19:53411static bool CrossesExtensionExtents(const ExtensionSet* extensions,
412 WebFrame* frame,
413 const GURL& new_url) {
[email protected]3a8eecb2010-04-22 23:56:30414 // If the URL is still empty, this is a window.open navigation. Check the
415 // opener's URL.
416 GURL old_url(frame->url());
417 if (old_url.is_empty() && frame->opener())
418 old_url = frame->opener()->url();
419
[email protected]88c15e972011-02-05 04:19:53420 bool old_url_is_hosted_app = extensions->GetByURL(old_url) &&
421 !extensions->GetByURL(old_url)->web_extent().is_empty();
[email protected]2a521c52011-01-26 18:45:21422 return !extensions->InSameExtent(old_url, new_url) &&
[email protected]88c15e972011-02-05 04:19:53423 !old_url_is_hosted_app;
[email protected]3a8eecb2010-04-22 23:56:30424}
425
[email protected]3354d3e2010-06-10 19:53:02426// Returns the ISO 639_1 language code of the specified |text|, or 'unknown'
427// if it failed.
[email protected]e5106202010-06-11 21:12:36428static std::string DetermineTextLanguage(const string16& text) {
[email protected]655f97c32010-07-22 21:24:17429 std::string language = chrome::kUnknownLanguageCode;
[email protected]3354d3e2010-06-10 19:53:02430 int num_languages = 0;
[email protected]a95586882010-08-02 18:40:08431 int text_bytes = 0;
[email protected]3354d3e2010-06-10 19:53:02432 bool is_reliable = false;
[email protected]3354d3e2010-06-10 19:53:02433 Language cld_language =
[email protected]e5106202010-06-11 21:12:36434 DetectLanguageOfUnicodeText(NULL, text.c_str(), true, &is_reliable,
[email protected]a95586882010-08-02 18:40:08435 &num_languages, NULL, &text_bytes);
436 // We don't trust the result if the CLD reports that the detection is not
437 // reliable, or if the actual text used to detect the language was less than
438 // 100 bytes (short texts can often lead to wrong results).
439 if (is_reliable && text_bytes >= 100 && cld_language != NUM_LANGUAGES &&
[email protected]3354d3e2010-06-10 19:53:02440 cld_language != UNKNOWN_LANGUAGE && cld_language != TG_UNKNOWN_LANGUAGE) {
441 // We should not use LanguageCode_ISO_639_1 because it does not cover all
442 // the languages CLD can detect. As a result, it'll return the invalid
443 // language code for tradtional Chinese among others.
444 // |LanguageCodeWithDialect| will go through ISO 639-1, ISO-639-2 and
445 // 'other' tables to do the 'right' thing. In addition, it'll return zh-CN
446 // for Simplified Chinese.
447 language = LanguageCodeWithDialects(cld_language);
448 }
449 return language;
450}
451
[email protected]9b66f34bf2010-10-27 20:45:51452// Returns true if the parameter node is a textfield, text area or a content
453// editable div.
454static bool IsEditableNode(const WebNode& node) {
455 bool is_editable_node = false;
456 if (!node.isNull()) {
457 if (node.isContentEditable()) {
458 is_editable_node = true;
459 } else if (node.isElementNode()) {
460 is_editable_node =
461 node.toConst<WebElement>().isTextFormControlElement();
462 }
463 }
464 return is_editable_node;
465}
466
[email protected]54ec7f82010-10-21 22:32:51467static bool WebAccessibilityNotificationToViewHostMsg(
468 WebAccessibilityNotification notification,
469 ViewHostMsg_AccessibilityNotification_Params::NotificationType* type) {
470 switch (notification) {
471 case WebKit::WebAccessibilityNotificationCheckedStateChanged:
472 *type = ViewHostMsg_AccessibilityNotification_Params::
473 NOTIFICATION_TYPE_CHECK_STATE_CHANGED;
474 break;
475 case WebKit::WebAccessibilityNotificationChildrenChanged:
476 *type = ViewHostMsg_AccessibilityNotification_Params::
477 NOTIFICATION_TYPE_CHILDREN_CHANGED;
478 break;
479 case WebKit::WebAccessibilityNotificationFocusedUIElementChanged:
480 *type = ViewHostMsg_AccessibilityNotification_Params::
481 NOTIFICATION_TYPE_FOCUS_CHANGED;
482 break;
483 case WebKit::WebAccessibilityNotificationLoadComplete:
484 *type = ViewHostMsg_AccessibilityNotification_Params::
485 NOTIFICATION_TYPE_LOAD_COMPLETE;
486 break;
487 case WebKit::WebAccessibilityNotificationValueChanged:
488 *type = ViewHostMsg_AccessibilityNotification_Params::
489 NOTIFICATION_TYPE_VALUE_CHANGED;
490 break;
491 case WebKit::WebAccessibilityNotificationSelectedTextChanged:
492 *type = ViewHostMsg_AccessibilityNotification_Params::
493 NOTIFICATION_TYPE_SELECTED_TEXT_CHANGED;
494 break;
495 default:
496 // TODO(ctguil): Support additional webkit notifications.
497 return false;
498 }
499 return true;
500}
501
[email protected]81f9fe0b2010-12-07 00:35:29502// Conversion for the incoming value. The map isn't perfect; v8 has Uint32,
503// and int64 which don't fit as Value::TYPE_INTEGER, so we let them fall into
[email protected]fb534c92011-02-01 01:02:07504// being TYPE_DOUBLEs. Dates are converted to a string (which can then be
505// parsed into a base::Time), as are regexps. Arrays are converted into lists,
[email protected]81f9fe0b2010-12-07 00:35:29506// recursively. We don't deal with binary objects or functions - they become
507// null values.
508static Value* ConvertV8Value(const v8::Handle<v8::Value>& v8value) {
509 if (v8value->IsBoolean()) {
510 return Value::CreateBooleanValue(v8value->BooleanValue());
511 } else if (v8value->IsInt32()) {
512 return Value::CreateIntegerValue(v8value->Int32Value());
513 } else if (v8value->IsNumber()) {
[email protected]fb534c92011-02-01 01:02:07514 return Value::CreateDoubleValue(v8value->NumberValue());
[email protected]81f9fe0b2010-12-07 00:35:29515 } else if (v8value->IsString()) {
516 return Value::CreateStringValue(*v8::String::Utf8Value(v8value));
517 } else if (v8value->IsDate()) {
518 v8::Date* date = v8::Date::Cast(*v8value);
[email protected]fb534c92011-02-01 01:02:07519 return Value::CreateDoubleValue(date->NumberValue() / 1000.0);
[email protected]81f9fe0b2010-12-07 00:35:29520 } else if (v8value->IsRegExp()) {
521 return Value::CreateStringValue(
522 *v8::String::Utf8Value(v8value->ToString()));
523 } else if (v8value->IsArray()) {
524 v8::Array* array = v8::Array::Cast(*v8value);
525 uint32_t length = array->Length();
526 scoped_ptr<ListValue> list(new ListValue);
527 for (uint32_t i = 0 ; i < length ; ++i) {
528 list->Set(i, ConvertV8Value(array->Get(i)));
529 }
530 return list.release();
531 }
532 return Value::CreateNullValue();
533}
534
initial.commit09911bf2008-07-26 23:55:29535///////////////////////////////////////////////////////////////////////////////
536
[email protected]60c42a8c72009-10-09 04:08:59537int32 RenderView::next_page_id_ = 1;
538
[email protected]cdaf8d02010-03-30 19:52:47539struct RenderView::PendingFileChooser {
540 PendingFileChooser(const ViewHostMsg_RunFileChooser_Params& p,
541 WebFileChooserCompletion* c)
542 : params(p),
543 completion(c) {
544 }
545 ViewHostMsg_RunFileChooser_Params params;
546 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback.
547};
548
[email protected]2fab253a2009-08-17 23:00:59549RenderView::RenderView(RenderThreadBase* render_thread,
[email protected]676126f72011-01-15 00:03:51550 gfx::NativeViewId parent_hwnd,
551 int32 opener_id,
552 const RendererPreferences& renderer_prefs,
553 const WebPreferences& webkit_prefs,
554 SharedRenderViewCounter* counter,
555 int32 routing_id,
556 int64 session_storage_namespace_id,
557 const string16& frame_name)
[email protected]3e2b375b2010-04-07 17:03:12558 : RenderWidget(render_thread, WebKit::WebPopupTypeNone),
[email protected]676126f72011-01-15 00:03:51559 webkit_preferences_(webkit_prefs),
[email protected]3354d3e2010-06-10 19:53:02560 send_content_state_immediately_(false),
[email protected]81e63782009-02-27 19:35:09561 enabled_bindings_(0),
[email protected]3354d3e2010-06-10 19:53:02562 send_preferred_size_changes_(false),
563 script_can_close_(true),
[email protected]81a34412009-01-05 19:17:24564 is_loading_(false),
[email protected]e75cb49e2009-01-05 23:13:21565 navigation_gesture_(NavigationGestureUnknown),
[email protected]3354d3e2010-06-10 19:53:02566 opened_by_user_gesture_(true),
567 opener_suppressed_(false),
[email protected]987d51af2011-02-24 17:50:18568 is_prerendering_(false),
[email protected]81a34412009-01-05 19:17:24569 page_id_(-1),
570 last_page_id_sent_to_browser_(-1),
571 last_indexed_page_id_(-1),
[email protected]3cc72b12010-03-18 23:03:00572 history_list_offset_(-1),
573 history_list_length_(0),
[email protected]81a34412009-01-05 19:17:24574 has_unload_listener_(false),
[email protected]83dde542009-09-11 20:59:55575#if defined(OS_MACOSX)
576 has_document_tag_(false),
577#endif
[email protected]98324892009-09-09 21:16:05578 document_tag_(0),
[email protected]3354d3e2010-06-10 19:53:02579 target_url_status_(TARGET_NONE),
580 spelling_panel_visible_(false),
581 view_type_(ViewType::INVALID),
582 browser_window_id_(-1),
[email protected]18ca9a6b2010-06-02 19:05:18583 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)),
[email protected]e47aec52010-08-12 00:50:30584 ALLOW_THIS_IN_INITIALIZER_LIST(page_info_method_factory_(this)),
[email protected]54ec7f82010-10-21 22:32:51585 ALLOW_THIS_IN_INITIALIZER_LIST(accessibility_method_factory_(this)),
[email protected]3354d3e2010-06-10 19:53:02586 ALLOW_THIS_IN_INITIALIZER_LIST(cookie_jar_(this)),
[email protected]676126f72011-01-15 00:03:51587 devtools_client_(NULL),
588 geolocation_dispatcher_(NULL),
589 speech_input_dispatcher_(NULL),
590 device_orientation_dispatcher_(NULL),
[email protected]dec1f292011-02-11 20:20:20591 print_helper_(NULL),
[email protected]6c2f73202011-02-14 20:21:54592 searchbox_(NULL),
[email protected]5efcef62011-02-22 09:00:13593 spellcheck_provider_(NULL),
[email protected]54ec7f82010-10-21 22:32:51594 accessibility_ack_pending_(false),
[email protected]cae8c8492011-03-03 11:12:18595 p2p_socket_dispatcher_(NULL),
[email protected]bb461532010-11-26 21:50:23596 pending_app_icon_requests_(0),
[email protected]5ee0cfd02011-01-18 05:42:22597 session_storage_namespace_id_(session_storage_namespace_id) {
[email protected]8de12d942010-11-17 20:42:44598#if defined(OS_MACOSX)
599 // On Mac, the select popups are rendered by the browser.
600 // Note that we don't do this in RenderMain otherwise this would not be called
601 // in single-process mode.
602 WebKit::WebView::setUseExternalPopupMenus(true);
603#endif
[email protected]676126f72011-01-15 00:03:51604
[email protected]71b0d5d2010-02-15 05:43:07605 ClearBlockedContentSettings();
[email protected]676126f72011-01-15 00:03:51606
607 routing_id_ = routing_id;
608 if (opener_id != MSG_ROUTING_NONE)
609 opener_id_ = opener_id;
610
611 if (counter) {
612 shared_popup_counter_ = counter;
613 shared_popup_counter_->data++;
614 decrement_shared_popup_at_destruction_ = true;
615 } else {
616 shared_popup_counter_ = new SharedRenderViewCounter(0);
617 decrement_shared_popup_at_destruction_ = false;
618 }
619
620 notification_provider_ = new NotificationProvider(this);
621
622 devtools_agent_ = new DevToolsAgent(this);
[email protected]78192082011-01-29 05:43:44623 PasswordAutoFillManager* password_autofill_manager =
624 new PasswordAutoFillManager(this);
625 AutoFillAgent* autofill_agent = new AutoFillAgent(this,
626 password_autofill_manager);
[email protected]676126f72011-01-15 00:03:51627
[email protected]78192082011-01-29 05:43:44628 webwidget_ = WebView::create(this, devtools_agent_, autofill_agent);
[email protected]676126f72011-01-15 00:03:51629 g_view_map.Get().insert(std::make_pair(webview(), this));
630 webkit_preferences_.Apply(webview());
631 webview()->initializeMainFrame(this);
632 if (!frame_name.empty())
633 webview()->mainFrame()->setName(frame_name);
[email protected]1ee59cb2011-02-23 02:45:51634 webview()->settings()->setMinimumTimerInterval(
635 is_hidden() ? webkit_glue::kBackgroundTabTimerInterval :
636 webkit_glue::kForegroundTabTimerInterval);
[email protected]676126f72011-01-15 00:03:51637
638 OnSetRendererPrefs(renderer_prefs);
639
640 render_thread_->AddRoute(routing_id_, this);
641 // Take a reference on behalf of the RenderThread. This will be balanced
642 // when we receive ViewMsg_Close.
643 AddRef();
644
645 // If this is a popup, we must wait for the CreatingNew_ACK message before
646 // completing initialization. Otherwise, we can finish it now.
647 if (opener_id == MSG_ROUTING_NONE) {
648 did_show_ = true;
649 CompleteInit(parent_hwnd);
650 }
651
652 host_window_ = parent_hwnd;
653
654 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
655 if (command_line.HasSwitch(switches::kDomAutomationController))
656 enabled_bindings_ |= BindingsPolicy::DOM_AUTOMATION;
657 if (command_line.HasSwitch(switches::kEnableAccessibility))
658 WebAccessibilityCache::enableAccessibility();
659
660 audio_message_filter_ = new AudioMessageFilter(routing_id_);
661 render_thread_->AddFilter(audio_message_filter_);
662
663 PageClickTracker* page_click_tracker = new PageClickTracker(this);
664 // Note that the order of insertion of the listeners is important.
665 // The password_autocomplete_manager takes the first shot at processing the
666 // notification and can stop the propagation.
[email protected]78192082011-01-29 05:43:44667 page_click_tracker->AddListener(password_autofill_manager);
668 page_click_tracker->AddListener(autofill_agent);
[email protected]81273622011-02-02 03:56:13669 new TranslateHelper(this);
[email protected]dec1f292011-02-11 20:20:20670 print_helper_ = new PrintWebViewHelper(this);
[email protected]6c2f73202011-02-14 20:21:54671 searchbox_ = new SearchBox(this);
[email protected]28685da92011-02-07 21:49:17672
[email protected]5efcef62011-02-22 09:00:13673 RenderThread* current_thread = RenderThread::current();
674 SpellCheck* spellcheck = current_thread ? current_thread->spellchecker() : 0;
675 spellcheck_provider_ = new SpellCheckProvider(this, spellcheck);
676
[email protected]28685da92011-02-07 21:49:17677 if (CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]cae8c8492011-03-03 11:12:18678 switches::kEnableP2PApi)) {
679 p2p_socket_dispatcher_ = new P2PSocketDispatcher(this);
680 }
681
682 if (CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]28685da92011-02-07 21:49:17683 switches::kEnableClientSidePhishingDetection)) {
684 new safe_browsing::PhishingClassifierDelegate(this, NULL);
685 }
[email protected]32ca14682011-02-16 19:05:10686
687 // Observer for Malware DOM details messages.
688 new safe_browsing::MalwareDOMDetails(this);
initial.commit09911bf2008-07-26 23:55:29689}
690
691RenderView::~RenderView() {
[email protected]0aa55312008-10-17 21:53:08692 if (decrement_shared_popup_at_destruction_)
693 shared_popup_counter_->data--;
694
[email protected]a1128322009-10-06 18:38:46695 // If file chooser is still waiting for answer, dispatch empty answer.
[email protected]cdaf8d02010-03-30 19:52:47696 while (!file_chooser_completions_.empty()) {
697 if (file_chooser_completions_.front()->completion) {
698 file_chooser_completions_.front()->completion->didChooseFile(
699 WebVector<WebString>());
700 }
701 file_chooser_completions_.pop_front();
702 }
[email protected]a1128322009-10-06 18:38:46703
[email protected]83dde542009-09-11 20:59:55704#if defined(OS_MACOSX)
[email protected]98324892009-09-09 21:16:05705 // Tell the spellchecker that the document is closed.
[email protected]83dde542009-09-11 20:59:55706 if (has_document_tag_)
707 Send(new ViewHostMsg_DocumentWithTagClosed(routing_id_, document_tag_));
[email protected]c36a9b62010-10-14 00:41:11708
709 // Destroy all fake plugin window handles on the browser side.
710 while (!fake_plugin_window_handles_.empty()) {
711 // Make sure no NULL plugin window handles were inserted into this list.
712 DCHECK(*fake_plugin_window_handles_.begin());
713 // DestroyFakePluginWindowHandle modifies fake_plugin_window_handles_.
714 DestroyFakePluginWindowHandle(*fake_plugin_window_handles_.begin());
715 }
[email protected]83dde542009-09-11 20:59:55716#endif
[email protected]98324892009-09-09 21:16:05717
[email protected]5fb88962009-04-16 19:03:25718 render_thread_->RemoveFilter(audio_message_filter_);
[email protected]60c42a8c72009-10-09 04:08:59719
720#ifndef NDEBUG
721 // Make sure we are no longer referenced by the ViewMap.
[email protected]625332e02010-12-14 07:48:49722 ViewMap* views = g_view_map.Pointer();
[email protected]60c42a8c72009-10-09 04:08:59723 for (ViewMap::iterator it = views->begin(); it != views->end(); ++it)
724 DCHECK_NE(this, it->second) << "Failed to call Close?";
725#endif
[email protected]676126f72011-01-15 00:03:51726
727 FOR_EACH_OBSERVER(RenderViewObserver, observers_, set_render_view(NULL));
728 FOR_EACH_OBSERVER(RenderViewObserver, observers_, OnDestruct());
[email protected]60c42a8c72009-10-09 04:08:59729}
730
731/*static*/
732void RenderView::ForEach(RenderViewVisitor* visitor) {
[email protected]625332e02010-12-14 07:48:49733 ViewMap* views = g_view_map.Pointer();
[email protected]60c42a8c72009-10-09 04:08:59734 for (ViewMap::iterator it = views->begin(); it != views->end(); ++it) {
735 if (!visitor->Visit(it->second))
736 return;
737 }
738}
739
740/*static*/
741RenderView* RenderView::FromWebView(WebView* webview) {
[email protected]625332e02010-12-14 07:48:49742 ViewMap* views = g_view_map.Pointer();
[email protected]60c42a8c72009-10-09 04:08:59743 ViewMap::iterator it = views->find(webview);
744 return it == views->end() ? NULL : it->second;
initial.commit09911bf2008-07-26 23:55:29745}
746
747/*static*/
[email protected]0aa55312008-10-17 21:53:08748RenderView* RenderView::Create(
[email protected]81a34412009-01-05 19:17:24749 RenderThreadBase* render_thread,
[email protected]18bcc3c2009-01-27 21:39:15750 gfx::NativeViewId parent_hwnd,
[email protected]0aa55312008-10-17 21:53:08751 int32 opener_id,
[email protected]80d96fa2009-06-10 22:34:51752 const RendererPreferences& renderer_prefs,
[email protected]0aa55312008-10-17 21:53:08753 const WebPreferences& webkit_prefs,
754 SharedRenderViewCounter* counter,
[email protected]4e6419c2010-01-15 04:50:34755 int32 routing_id,
[email protected]8ab04652010-06-12 02:47:26756 int64 session_storage_namespace_id,
757 const string16& frame_name) {
initial.commit09911bf2008-07-26 23:55:29758 DCHECK(routing_id != MSG_ROUTING_NONE);
[email protected]676126f72011-01-15 00:03:51759 return new RenderView(
760 render_thread,
761 parent_hwnd,
762 opener_id,
763 renderer_prefs,
764 webkit_prefs,
765 counter,
766 routing_id,
767 session_storage_namespace_id,
768 frame_name); // adds reference
initial.commit09911bf2008-07-26 23:55:29769}
770
[email protected]bb461532010-11-26 21:50:23771// static
initial.commit09911bf2008-07-26 23:55:29772void RenderView::SetNextPageID(int32 next_page_id) {
773 // This method should only be called during process startup, and the given
774 // page id had better not exceed our current next page id!
[email protected]4646f292009-05-20 03:49:05775 DCHECK_EQ(next_page_id_, 1);
initial.commit09911bf2008-07-26 23:55:29776 DCHECK(next_page_id >= next_page_id_);
777 next_page_id_ = next_page_id;
778}
779
[email protected]676126f72011-01-15 00:03:51780void RenderView::AddObserver(RenderViewObserver* observer) {
781 observers_.AddObserver(observer);
782}
783
784void RenderView::RemoveObserver(RenderViewObserver* observer) {
785 observer->set_render_view(NULL);
786 observers_.RemoveObserver(observer);
787}
788
[email protected]70eee342010-11-05 01:59:37789bool RenderView::RendererAccessibilityNotification::ShouldIncludeChildren() {
790 typedef ViewHostMsg_AccessibilityNotification_Params params;
[email protected]a527a022011-02-10 02:32:36791 if (type == WebKit::WebAccessibilityNotificationChildrenChanged ||
792 type == WebKit::WebAccessibilityNotificationLoadComplete) {
[email protected]70eee342010-11-05 01:59:37793 return true;
794 }
795 return false;
796}
797
[email protected]8a3125a712010-08-09 18:58:51798WebKit::WebView* RenderView::webview() const {
[email protected]4d51d5bf2010-07-26 18:48:26799 return static_cast<WebKit::WebView*>(webwidget());
800}
801
[email protected]afe3a1672009-11-17 19:04:12802void RenderView::UserMetricsRecordAction(const std::string& action) {
[email protected]15d04ae2010-10-30 01:04:50803 Send(new ViewHostMsg_UserMetricsRecordAction(action));
[email protected]1dbafaf72009-09-23 19:43:56804}
805
[email protected]bb461532010-11-26 21:50:23806bool RenderView::InstallWebApplicationUsingDefinitionFile(WebFrame* frame,
807 string16* error) {
808 // There is an issue of drive-by installs with the below implementation. A web
809 // site could force a user to install an app by timing the dialog to come up
810 // just before the user clicks.
811 //
812 // We do show a success UI that allows users to uninstall, but it seems that
813 // we might still want to put up an infobar before showing the install dialog.
814 //
815 // TODO(aa): Figure out this issue before removing the kEnableCrxlessWebApps
816 // switch.
817 if (!CommandLine::ForCurrentProcess()->HasSwitch(
818 switches::kEnableCrxlessWebApps)) {
819 *error = ASCIIToUTF16("CRX-less web apps aren't enabled.");
820 return false;
821 }
822
823 if (frame != frame->top()) {
824 *error = ASCIIToUTF16("Applications can only be installed from the top "
825 "frame.");
826 return false;
827 }
828
829 if (pending_app_info_.get()) {
830 *error = ASCIIToUTF16("An application install is already in progress.");
831 return false;
832 }
833
834 pending_app_info_.reset(new WebApplicationInfo());
835 if (!web_apps::ParseWebAppFromWebDocument(frame, pending_app_info_.get(),
836 error)) {
837 return false;
838 }
839
840 if (!pending_app_info_->manifest_url.is_valid()) {
841 *error = ASCIIToUTF16("Web application definition not found or invalid.");
842 return false;
843 }
844
845 app_definition_fetcher_.reset(new ResourceFetcher(
846 pending_app_info_->manifest_url, webview()->mainFrame(),
847 NewCallback(this, &RenderView::DidDownloadApplicationDefinition)));
848 return true;
849}
850
[email protected]1a3c3cb2010-12-16 21:03:40851void RenderView::SetReportLoadProgressEnabled(bool enabled) {
852 if (!enabled) {
853 load_progress_tracker_.reset(NULL);
854 return;
855 }
856 if (load_progress_tracker_ == NULL)
857 load_progress_tracker_.reset(new LoadProgressTracker(this));
858}
859
[email protected]bb461532010-11-26 21:50:23860void RenderView::DidDownloadApplicationDefinition(
861 const WebKit::WebURLResponse& response,
862 const std::string& data) {
863 scoped_ptr<WebApplicationInfo> app_info(
864 pending_app_info_.release());
865
866 JSONStringValueSerializer serializer(data);
867 int error_code = 0;
868 std::string error_message;
869 scoped_ptr<Value> result(serializer.Deserialize(&error_code, &error_message));
870 if (!result.get()) {
871 AddErrorToRootConsole(UTF8ToUTF16(error_message));
872 return;
873 }
874
875 string16 error_message_16;
876 if (!web_apps::ParseWebAppFromDefinitionFile(result.get(), app_info.get(),
877 &error_message_16)) {
878 AddErrorToRootConsole(error_message_16);
879 return;
880 }
881
882 if (!app_info->icons.empty()) {
883 pending_app_info_.reset(app_info.release());
884 pending_app_icon_requests_ =
885 static_cast<int>(pending_app_info_->icons.size());
886 for (size_t i = 0; i < pending_app_info_->icons.size(); ++i) {
887 app_icon_fetchers_.push_back(linked_ptr<ImageResourceFetcher>(
888 new ImageResourceFetcher(
889 pending_app_info_->icons[i].url,
890 webview()->mainFrame(),
891 static_cast<int>(i),
892 pending_app_info_->icons[i].width,
893 NewCallback(this, &RenderView::DidDownloadApplicationIcon))));
894 }
895 } else {
896 Send(new ViewHostMsg_InstallApplication(routing_id_, *app_info));
897 }
898}
899
900void RenderView::DidDownloadApplicationIcon(ImageResourceFetcher* fetcher,
901 const SkBitmap& image) {
902 pending_app_info_->icons[fetcher->id()].data = image;
903
904 // Remove the image fetcher from our pending list. We're in the callback from
905 // ImageResourceFetcher, best to delay deletion.
906 for (ImageResourceFetcherList::iterator iter = app_icon_fetchers_.begin();
907 iter != app_icon_fetchers_.end(); ++iter) {
908 if (iter->get() == fetcher) {
909 iter->release();
910 app_icon_fetchers_.erase(iter);
911 break;
912 }
913 }
914
915 // We're in the callback from the ImageResourceFetcher, best to delay
916 // deletion.
917 MessageLoop::current()->DeleteSoon(FROM_HERE, fetcher);
918
919 if (--pending_app_icon_requests_ > 0)
920 return;
921
922 // There is a maximum size of IPC on OS X and Linux that we have run into in
923 // some situations. We're not sure what it is, but our hypothesis is in the
924 // neighborhood of 1 MB.
925 //
926 // To be on the safe side, we give ourselves 128 KB for just the image data.
927 // This should be more than enough for 128, 48, and 16 px 32-bit icons. If we
928 // want to start allowing larger icons (see bug 63406), we'll have to either
929 // experiment mor ewith this and find the real limit, or else come up with
930 // some alternative way to transmit the icon data to the browser process.
931 //
932 // See also: bug 63729.
[email protected]678a7d72011-01-05 20:37:32933 const size_t kMaxIconSize = 1024 * 128;
934 size_t actual_icon_size = 0;
[email protected]bb461532010-11-26 21:50:23935 for (size_t i = 0; i < pending_app_info_->icons.size(); ++i) {
[email protected]678a7d72011-01-05 20:37:32936 size_t current_size = pending_app_info_->icons[i].data.getSize();
937 if (current_size > kMaxIconSize - actual_icon_size) {
938 AddErrorToRootConsole(ASCIIToUTF16(
[email protected]bb461532010-11-26 21:50:23939 "Icons are too large. Maximum total size for app icons is 128 KB."));
[email protected]678a7d72011-01-05 20:37:32940 return;
941 }
942 actual_icon_size += current_size;
[email protected]bb461532010-11-26 21:50:23943 }
944
945 Send(new ViewHostMsg_InstallApplication(routing_id_, *pending_app_info_));
946 pending_app_info_.reset(NULL);
947}
948
[email protected]a3a8fb6d2009-10-22 20:12:51949void RenderView::PluginCrashed(const FilePath& plugin_path) {
950 Send(new ViewHostMsg_CrashedPlugin(routing_id_, plugin_path));
initial.commit09911bf2008-07-26 23:55:29951}
952
[email protected]aad51d1c2010-08-05 08:38:09953WebPlugin* RenderView::CreatePluginNoCheck(WebFrame* frame,
954 const WebPluginParams& params) {
[email protected]191eb3f72010-12-21 06:27:50955 webkit::npapi::WebPluginInfo info;
[email protected]6fdd4182010-10-14 23:59:26956 bool found;
957 ContentSetting setting;
958 std::string mime_type;
959 Send(new ViewHostMsg_GetPluginInfo(
[email protected]c8f73ab2011-01-22 00:05:17960 routing_id_, params.url, frame->top()->url(), params.mimeType.utf8(),
961 &found, &info, &setting, &mime_type));
[email protected]b83ff222011-01-24 17:37:12962 if (!found || !webkit::npapi::IsPluginEnabled(info))
[email protected]aad51d1c2010-08-05 08:38:09963 return NULL;
[email protected]1a78d9f32010-12-08 06:38:45964
[email protected]0bd753682010-12-16 18:15:52965 scoped_refptr<webkit::ppapi::PluginModule> pepper_module(
[email protected]1a78d9f32010-12-08 06:38:45966 pepper_delegate_.CreatePepperPlugin(info.path));
[email protected]aad51d1c2010-08-05 08:38:09967 if (pepper_module)
[email protected]6fdd4182010-10-14 23:59:26968 return CreatePepperPlugin(frame, params, info.path, pepper_module.get());
[email protected]1a78d9f32010-12-08 06:38:45969 return CreateNPAPIPlugin(frame, params, info.path, mime_type);
[email protected]aad51d1c2010-08-05 08:38:09970}
971
[email protected]d8fd6fa2010-02-01 15:54:26972void RenderView::RegisterPluginDelegate(WebPluginDelegateProxy* delegate) {
973 plugin_delegates_.insert(delegate);
[email protected]49232292010-09-03 19:07:30974 // If the renderer is visible, set initial visibility and focus state.
975 if (!is_hidden()) {
[email protected]784ea1ab2010-09-18 00:02:34976#if defined(OS_MACOSX)
[email protected]49232292010-09-03 19:07:30977 delegate->SetContainerVisibility(true);
978 if (webview() && webview()->isActive())
979 delegate->SetWindowFocus(true);
[email protected]784ea1ab2010-09-18 00:02:34980#endif
[email protected]49232292010-09-03 19:07:30981 }
[email protected]784ea1ab2010-09-18 00:02:34982 // Plugins start assuming the content has focus (so that they work in
983 // environments where RenderView isn't hosting them), so we always have to
984 // set the initial state. See webplugin_delegate_impl.h for details.
985 delegate->SetContentAreaFocus(has_focus());
[email protected]d8fd6fa2010-02-01 15:54:26986}
987
988void RenderView::UnregisterPluginDelegate(WebPluginDelegateProxy* delegate) {
989 plugin_delegates_.erase(delegate);
990}
[email protected]d8fd6fa2010-02-01 15:54:26991
[email protected]a95986a82010-12-24 06:19:28992bool RenderView::OnMessageReceived(const IPC::Message& message) {
[email protected]26aa0482009-09-30 16:55:27993 WebFrame* main_frame = webview() ? webview()->mainFrame() : NULL;
[email protected]a9f607e2009-10-23 19:59:27994 if (main_frame)
995 child_process_logging::SetActiveURL(main_frame->url());
[email protected]f8b6b6f2009-03-10 16:48:26996
[email protected]676126f72011-01-15 00:03:51997 ObserverListBase<RenderViewObserver>::Iterator it(observers_);
998 RenderViewObserver* observer;
999 while ((observer = it.GetNext()) != NULL)
1000 if (observer->OnMessageReceived(message))
1001 return true;
[email protected]b2abac72009-02-26 12:39:281002
[email protected]a95986a82010-12-24 06:19:281003 bool handled = true;
initial.commit09911bf2008-07-26 23:55:291004 IPC_BEGIN_MESSAGE_MAP(RenderView, message)
[email protected]9b18a84f2010-06-10 15:54:041005 IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, OnCaptureThumbnail)
1006 IPC_MESSAGE_HANDLER(ViewMsg_CaptureSnapshot, OnCaptureSnapshot)
initial.commit09911bf2008-07-26 23:55:291007 IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
1008 IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
[email protected]1dda4022010-01-28 18:24:561009 IPC_MESSAGE_HANDLER(ViewMsg_ReloadFrame, OnReloadFrame)
initial.commit09911bf2008-07-26 23:55:291010 IPC_MESSAGE_HANDLER(ViewMsg_Undo, OnUndo)
1011 IPC_MESSAGE_HANDLER(ViewMsg_Redo, OnRedo)
1012 IPC_MESSAGE_HANDLER(ViewMsg_Cut, OnCut)
1013 IPC_MESSAGE_HANDLER(ViewMsg_Copy, OnCopy)
[email protected]c0cc3092009-09-12 08:27:271014#if defined(OS_MACOSX)
[email protected]a954bf72009-09-12 07:30:351015 IPC_MESSAGE_HANDLER(ViewMsg_CopyToFindPboard, OnCopyToFindPboard)
[email protected]c0cc3092009-09-12 08:27:271016#endif
initial.commit09911bf2008-07-26 23:55:291017 IPC_MESSAGE_HANDLER(ViewMsg_Paste, OnPaste)
1018 IPC_MESSAGE_HANDLER(ViewMsg_Replace, OnReplace)
[email protected]98324892009-09-09 21:16:051019 IPC_MESSAGE_HANDLER(ViewMsg_ToggleSpellPanel, OnToggleSpellPanel)
1020 IPC_MESSAGE_HANDLER(ViewMsg_AdvanceToNextMisspelling,
1021 OnAdvanceToNextMisspelling)
[email protected]bbbd545c2008-12-15 20:18:041022 IPC_MESSAGE_HANDLER(ViewMsg_ToggleSpellCheck, OnToggleSpellCheck)
initial.commit09911bf2008-07-26 23:55:291023 IPC_MESSAGE_HANDLER(ViewMsg_Delete, OnDelete)
1024 IPC_MESSAGE_HANDLER(ViewMsg_SelectAll, OnSelectAll)
1025 IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
[email protected]4b59ae602009-06-23 20:58:151026 IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand)
initial.commit09911bf2008-07-26 23:55:291027 IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
[email protected]24a7f3c2010-03-25 08:26:491028 IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
1029 IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)
[email protected]630e26b2008-10-14 22:55:171030 IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
[email protected]9d797f32010-04-23 07:17:541031 IPC_MESSAGE_HANDLER(ViewMsg_SetContentSettingsForLoadingURL,
1032 OnSetContentSettingsForLoadingURL)
[email protected]d0b8d092010-10-25 04:05:171033 IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevel, OnSetZoomLevel)
[email protected]9d797f32010-04-23 07:17:541034 IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForLoadingURL,
1035 OnSetZoomLevelForLoadingURL)
initial.commit09911bf2008-07-26 23:55:291036 IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
[email protected]a697f4c2009-09-14 22:30:181037 IPC_MESSAGE_HANDLER(ViewMsg_ResetPageEncodingToDefault,
1038 OnResetPageEncodingToDefault)
[email protected]b2abac72009-02-26 12:39:281039 IPC_MESSAGE_HANDLER(ViewMsg_SetupDevToolsClient, OnSetupDevToolsClient)
[email protected]bf5c2ff392009-07-08 16:24:331040 IPC_MESSAGE_HANDLER(ViewMsg_DownloadFavIcon, OnDownloadFavIcon)
initial.commit09911bf2008-07-26 23:55:291041 IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
[email protected]1810e132009-03-24 23:35:481042 IPC_MESSAGE_HANDLER(ViewMsg_CSSInsertRequest, OnCSSInsertRequest)
initial.commit09911bf2008-07-26 23:55:291043 IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)
initial.commit09911bf2008-07-26 23:55:291044 IPC_MESSAGE_HANDLER(ViewMsg_ReservePageIDRange, OnReservePageIDRange)
initial.commit09911bf2008-07-26 23:55:291045 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragEnter, OnDragTargetDragEnter)
1046 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragOver, OnDragTargetDragOver)
1047 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDragLeave, OnDragTargetDragLeave)
1048 IPC_MESSAGE_HANDLER(ViewMsg_DragTargetDrop, OnDragTargetDrop)
[email protected]18cb2572008-08-21 20:34:451049 IPC_MESSAGE_HANDLER(ViewMsg_AllowBindings, OnAllowBindings)
[email protected]d0980792011-02-13 19:41:401050 IPC_MESSAGE_HANDLER(ViewMsg_SetWebUIProperty, OnSetWebUIProperty)
[email protected]266eb6f2008-09-30 23:56:501051 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceEndedOrMoved,
1052 OnDragSourceEndedOrMoved)
initial.commit09911bf2008-07-26 23:55:291053 IPC_MESSAGE_HANDLER(ViewMsg_DragSourceSystemDragEnded,
1054 OnDragSourceSystemDragEnded)
1055 IPC_MESSAGE_HANDLER(ViewMsg_SetInitialFocus, OnSetInitialFocus)
[email protected]9b66f34bf2010-10-27 20:45:511056 IPC_MESSAGE_HANDLER(ViewMsg_ScrollFocusedEditableNodeIntoView,
1057 OnScrollFocusedEditableNodeIntoView)
initial.commit09911bf2008-07-26 23:55:291058 IPC_MESSAGE_HANDLER(ViewMsg_UpdateTargetURL_ACK, OnUpdateTargetURLAck)
1059 IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
1060 IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)
1061 IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)
[email protected]90dba072011-01-20 20:10:201062 IPC_MESSAGE_HANDLER(ViewMsg_DisplayPrerenderedPage,
1063 OnDisplayPrerenderedPage)
initial.commit09911bf2008-07-26 23:55:291064 IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
1065 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)
initial.commit09911bf2008-07-26 23:55:291066 IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,
1067 OnGetAllSavableResourceLinksForCurrentPage)
[email protected]f09c7182009-03-10 12:54:041068 IPC_MESSAGE_HANDLER(
1069 ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,
1070 OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)
initial.commit09911bf2008-07-26 23:55:291071 IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo)
[email protected]9b18a84f2010-06-10 15:54:041072 IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnShouldClose)
initial.commit09911bf2008-07-26 23:55:291073 IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
1074 IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged)
[email protected]18cb2572008-08-21 20:34:451075 IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost,
[email protected]9b18a84f2010-06-10 15:54:041076 OnHandleMessageFromExternalHost)
[email protected]0aa55312008-10-17 21:53:081077 IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount,
1078 OnDisassociateFromPopupCount)
[email protected]e8345242010-05-06 03:00:401079 IPC_MESSAGE_HANDLER(ViewMsg_AllowScriptToClose,
1080 OnAllowScriptToClose)
[email protected]30f75e62009-02-25 22:01:001081 IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
[email protected]309d7a282009-03-24 09:18:271082 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionResponse, OnExtensionResponse)
[email protected]7120f132009-07-20 21:05:371083 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionMessageInvoke,
1084 OnExtensionMessageInvoke)
[email protected]05d478752009-04-08 23:38:161085 IPC_MESSAGE_HANDLER(ViewMsg_ClearFocusedNode, OnClearFocusedNode)
[email protected]699ab0d2009-04-23 23:19:141086 IPC_MESSAGE_HANDLER(ViewMsg_SetBackground, OnSetBackground)
[email protected]ab32b16c2009-10-16 14:57:251087 IPC_MESSAGE_HANDLER(ViewMsg_EnablePreferredSizeChangedMode,
1088 OnEnablePreferredSizeChangedMode)
[email protected]cda45c02010-02-25 19:28:101089 IPC_MESSAGE_HANDLER(ViewMsg_DisableScrollbarsForSmallWindows,
1090 OnDisableScrollbarsForSmallWindows)
[email protected]80d96fa2009-06-10 22:34:511091 IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
[email protected]7b291f92009-08-14 05:43:531092 IPC_MESSAGE_HANDLER(ViewMsg_UpdateBrowserWindowId,
1093 OnUpdateBrowserWindowId)
1094 IPC_MESSAGE_HANDLER(ViewMsg_NotifyRenderViewType,
1095 OnNotifyRendererViewType)
[email protected]581b87eb2009-07-23 23:06:561096 IPC_MESSAGE_HANDLER(ViewMsg_MediaPlayerActionAt, OnMediaPlayerActionAt)
[email protected]8c66c5a2009-07-22 17:26:341097 IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
[email protected]6ce7abc52010-02-02 18:40:141098#if defined(OS_MACOSX)
1099 IPC_MESSAGE_HANDLER(ViewMsg_SetWindowVisibility, OnSetWindowVisibility)
[email protected]1e6e3c992010-02-08 15:52:131100 IPC_MESSAGE_HANDLER(ViewMsg_WindowFrameChanged, OnWindowFrameChanged)
[email protected]b7f75862011-01-21 21:15:131101 IPC_MESSAGE_HANDLER(ViewMsg_PluginImeCompositionCompleted,
1102 OnPluginImeCompositionCompleted)
[email protected]6ce7abc52010-02-02 18:40:141103#endif
[email protected]446705872009-09-10 07:22:481104 IPC_MESSAGE_HANDLER(ViewMsg_SetEditCommandsForNextKeyEvent,
[email protected]a0c7153e2009-12-09 14:36:331105 OnSetEditCommandsForNextKeyEvent)
[email protected]912256b32009-09-18 09:47:351106 IPC_MESSAGE_HANDLER(ViewMsg_ExecuteCode,
1107 OnExecuteCode)
[email protected]a0c7153e2009-12-09 14:36:331108 IPC_MESSAGE_HANDLER(ViewMsg_CustomContextMenuAction,
1109 OnCustomContextMenuAction)
[email protected]dea2d372010-09-25 06:41:141110 IPC_MESSAGE_HANDLER(ViewMsg_EnableAccessibility, OnEnableAccessibility)
[email protected]aef92842010-05-21 16:54:361111 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityFocus, OnSetAccessibilityFocus)
1112 IPC_MESSAGE_HANDLER(ViewMsg_AccessibilityDoDefaultAction,
1113 OnAccessibilityDoDefaultAction)
[email protected]9892b472010-09-16 00:23:421114 IPC_MESSAGE_HANDLER(ViewMsg_AccessibilityNotifications_ACK,
1115 OnAccessibilityNotificationsAck)
[email protected]27a9ef32010-09-10 04:06:241116 IPC_MESSAGE_HANDLER(ViewMsg_AsyncOpenFile_ACK, OnAsyncFileOpened)
[email protected]caf706f2010-10-26 17:54:081117#if defined(OS_MACOSX)
1118 IPC_MESSAGE_HANDLER(ViewMsg_SelectPopupMenuItem, OnSelectPopupMenuItem)
1119#endif
[email protected]a6097f42011-01-10 08:50:511120 IPC_MESSAGE_HANDLER(ViewMsg_JavaScriptStressTestControl,
1121 OnJavaScriptStressTestControl)
[email protected]521b2482011-01-15 00:10:101122 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed)
[email protected]232a5812011-03-04 22:42:081123 IPC_MESSAGE_HANDLER(ViewMsg_NetworkStateChanged, OnNetworkStateChanged)
[email protected]634a6f92008-12-01 21:39:311124
[email protected]f0557932011-01-25 20:20:511125 // TODO(viettrungluu): Move to a separate message filter.
1126#if defined(ENABLE_FLAPPER_HACKS)
1127 IPC_MESSAGE_HANDLER(PepperMsg_ConnectTcpACK, OnConnectTcpACK)
1128#endif
1129
initial.commit09911bf2008-07-26 23:55:291130 // Have the super handle all other messages.
[email protected]a95986a82010-12-24 06:19:281131 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message))
initial.commit09911bf2008-07-26 23:55:291132 IPC_END_MESSAGE_MAP()
[email protected]a95986a82010-12-24 06:19:281133 return handled;
initial.commit09911bf2008-07-26 23:55:291134}
1135
[email protected]9b18a84f2010-06-10 15:54:041136void RenderView::OnCaptureThumbnail() {
[email protected]26aa0482009-09-30 16:55:271137 WebFrame* main_frame = webview()->mainFrame();
initial.commit09911bf2008-07-26 23:55:291138 if (!main_frame)
1139 return;
1140
1141 // get the URL for this page
[email protected]dd7daa82009-08-10 05:46:451142 GURL url(main_frame->url());
initial.commit09911bf2008-07-26 23:55:291143 if (url.is_empty())
1144 return;
1145
1146 if (size_.IsEmpty())
1147 return; // Don't create an empty thumbnail!
1148
1149 ThumbnailScore score;
1150 SkBitmap thumbnail;
[email protected]8649fb32009-06-26 17:51:021151 if (!CaptureThumbnail(webview(), kThumbnailWidth, kThumbnailHeight,
[email protected]b6e4bec2008-11-12 01:17:151152 &thumbnail, &score))
1153 return;
1154
initial.commit09911bf2008-07-26 23:55:291155 // send the thumbnail message to the browser process
[email protected]674741932009-02-04 23:44:461156 Send(new ViewHostMsg_Thumbnail(routing_id_, url, score, thumbnail));
initial.commit09911bf2008-07-26 23:55:291157}
1158
[email protected]9b18a84f2010-06-10 15:54:041159void RenderView::OnCaptureSnapshot() {
[email protected]30507922010-01-15 16:48:231160 SkBitmap snapshot;
1161 bool error = false;
1162
1163 WebFrame* main_frame = webview()->mainFrame();
1164 if (!main_frame)
1165 error = true;
1166
1167 if (!error && !CaptureSnapshot(webview(), &snapshot))
1168 error = true;
1169
1170 DCHECK(error == snapshot.empty()) <<
1171 "Snapshot should be empty on error, non-empty otherwise.";
1172
1173 // Send the snapshot to the browser process.
1174 Send(new ViewHostMsg_Snapshot(routing_id_, snapshot));
1175}
1176
initial.commit09911bf2008-07-26 23:55:291177void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) {
1178 if (load_id != page_id_)
1179 return; // this capture call is no longer relevant due to navigation
1180 if (load_id == last_indexed_page_id_)
1181 return; // we already indexed this page
1182
1183 if (!webview())
1184 return;
1185
[email protected]26aa0482009-09-30 16:55:271186 WebFrame* main_frame = webview()->mainFrame();
initial.commit09911bf2008-07-26 23:55:291187 if (!main_frame)
1188 return;
1189
1190 // Don't index/capture pages that are in view source mode.
[email protected]dd7daa82009-08-10 05:46:451191 if (main_frame->isViewSourceModeEnabled())
initial.commit09911bf2008-07-26 23:55:291192 return;
1193
1194 // Don't index/capture pages that failed to load. This only checks the top
1195 // level frame so the thumbnail may contain a frame that failed to load.
[email protected]dd7daa82009-08-10 05:46:451196 WebDataSource* ds = main_frame->dataSource();
[email protected]726985e22009-06-18 21:09:281197 if (ds && ds->hasUnreachableURL())
initial.commit09911bf2008-07-26 23:55:291198 return;
1199
1200 if (!preliminary_capture)
1201 last_indexed_page_id_ = load_id;
1202
[email protected]a8a81292010-01-21 00:32:451203 // Get the URL for this page.
[email protected]dd7daa82009-08-10 05:46:451204 GURL url(main_frame->url());
initial.commit09911bf2008-07-26 23:55:291205 if (url.is_empty())
1206 return;
1207
[email protected]a8a81292010-01-21 00:32:451208 // Retrieve the frame's full text.
[email protected]e5106202010-06-11 21:12:361209 string16 contents;
initial.commit09911bf2008-07-26 23:55:291210 CaptureText(main_frame, &contents);
1211 if (contents.size()) {
[email protected]1c57b7b2010-07-12 17:38:101212 WebKit::WebDocument document = main_frame->document();
[email protected]5ddfd63e2010-09-01 15:48:371213 // If the page explicitly specifies a language, use it, otherwise we'll
1214 // determine it based on the text content using the CLD.
1215 std::string language =
1216 TranslateHelper::GetPageLanguageFromMetaTag(&document);
1217 if (language.empty()) {
1218 base::TimeTicks begin_time = base::TimeTicks::Now();
1219 language = DetermineTextLanguage(contents);
1220 UMA_HISTOGRAM_MEDIUM_TIMES("Renderer4.LanguageDetection",
1221 base::TimeTicks::Now() - begin_time);
1222 }
[email protected]a8a81292010-01-21 00:32:451223 // Send the text to the browser for indexing (the browser might decide not
1224 // to index, if the URL is HTTPS for instance) and language discovery.
[email protected]5ddfd63e2010-09-01 15:48:371225 Send(new ViewHostMsg_PageContents(
1226 routing_id_, url, load_id, contents, language,
1227 TranslateHelper::IsPageTranslatable(&document)));
[email protected]5c4266922009-07-10 16:41:271228 }
1229
[email protected]d54169e92011-01-21 09:19:521230 // Generate the thumbnail here if the in-browser thumbnailing isn't
1231 // enabled. TODO(satorux): Remove this and related code once
1232 // crbug.com/65936 is complete.
1233 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1234 switches::kEnableInBrowserThumbnailing)) {
1235 OnCaptureThumbnail();
1236 }
[email protected]3ead1322010-11-19 20:01:001237
[email protected]28685da92011-02-07 21:49:171238 FOR_EACH_OBSERVER(RenderViewObserver, observers_, PageCaptured(contents));
initial.commit09911bf2008-07-26 23:55:291239}
1240
[email protected]e5106202010-06-11 21:12:361241void RenderView::CaptureText(WebFrame* frame, string16* contents) {
initial.commit09911bf2008-07-26 23:55:291242 contents->clear();
1243 if (!frame)
1244 return;
1245
1246#ifdef TIME_TEXT_RETRIEVAL
1247 double begin = time_util::GetHighResolutionTimeNow();
1248#endif
1249
1250 // get the contents of the frame
[email protected]e5106202010-06-11 21:12:361251 *contents = frame->contentAsText(kMaxIndexChars);
initial.commit09911bf2008-07-26 23:55:291252
1253#ifdef TIME_TEXT_RETRIEVAL
1254 double end = time_util::GetHighResolutionTimeNow();
1255 char buf[128];
1256 sprintf_s(buf, "%d chars retrieved for indexing in %gms\n",
1257 contents.size(), (end - begin)*1000);
1258 OutputDebugStringA(buf);
1259#endif
1260
1261 // When the contents are clipped to the maximum, we don't want to have a
1262 // partial word indexed at the end that might have been clipped. Therefore,
1263 // terminate the string at the last space to ensure no words are clipped.
1264 if (contents->size() == kMaxIndexChars) {
[email protected]e5106202010-06-11 21:12:361265 size_t last_space_index = contents->find_last_of(kWhitespaceUTF16);
initial.commit09911bf2008-07-26 23:55:291266 if (last_space_index == std::wstring::npos)
1267 return; // don't index if we got a huge block of text with no spaces
1268 contents->resize(last_space_index);
1269 }
1270}
1271
[email protected]8649fb32009-06-26 17:51:021272bool RenderView::CaptureThumbnail(WebView* view,
initial.commit09911bf2008-07-26 23:55:291273 int w,
1274 int h,
1275 SkBitmap* thumbnail,
1276 ThumbnailScore* score) {
[email protected]30507922010-01-15 16:48:231277 base::TimeTicks beginning_time = base::TimeTicks::Now();
[email protected]b6e4bec2008-11-12 01:17:151278
[email protected]8649fb32009-06-26 17:51:021279 skia::PlatformCanvas canvas;
[email protected]30507922010-01-15 16:48:231280
1281 // Paint |view| into |canvas|.
1282 if (!PaintViewIntoCanvas(view, canvas))
[email protected]8649fb32009-06-26 17:51:021283 return false;
[email protected]8649fb32009-06-26 17:51:021284
1285 skia::BitmapPlatformDevice& device =
1286 static_cast<skia::BitmapPlatformDevice&>(canvas.getTopPlatformDevice());
1287
1288 const SkBitmap& src_bmp = device.accessBitmap(false);
initial.commit09911bf2008-07-26 23:55:291289
[email protected]cab34d6a2009-09-24 01:14:521290 SkRect dest_rect = { 0, 0, SkIntToScalar(w), SkIntToScalar(h) };
initial.commit09911bf2008-07-26 23:55:291291 float dest_aspect = dest_rect.width() / dest_rect.height();
1292
1293 // Get the src rect so that we can preserve the aspect ratio while filling
1294 // the destination.
1295 SkIRect src_rect;
1296 if (src_bmp.width() < dest_rect.width() ||
1297 src_bmp.height() < dest_rect.height()) {
1298 // Source image is smaller: we clip the part of source image within the
1299 // dest rect, and then stretch it to fill the dest rect. We don't respect
1300 // the aspect ratio in this case.
1301 src_rect.set(0, 0, static_cast<S16CPU>(dest_rect.width()),
1302 static_cast<S16CPU>(dest_rect.height()));
1303 score->good_clipping = false;
1304 } else {
1305 float src_aspect = static_cast<float>(src_bmp.width()) / src_bmp.height();
1306 if (src_aspect > dest_aspect) {
1307 // Wider than tall, clip horizontally: we center the smaller thumbnail in
1308 // the wider screen.
1309 S16CPU new_width = static_cast<S16CPU>(src_bmp.height() * dest_aspect);
1310 S16CPU x_offset = (src_bmp.width() - new_width) / 2;
1311 src_rect.set(x_offset, 0, new_width + x_offset, src_bmp.height());
1312 score->good_clipping = false;
1313 } else {
1314 src_rect.set(0, 0, src_bmp.width(),
1315 static_cast<S16CPU>(src_bmp.width() / dest_aspect));
1316 score->good_clipping = true;
1317 }
1318 }
1319
[email protected]26aa0482009-09-30 16:55:271320 score->at_top = (view->mainFrame()->scrollOffset().height == 0);
initial.commit09911bf2008-07-26 23:55:291321
1322 SkBitmap subset;
[email protected]8649fb32009-06-26 17:51:021323 device.accessBitmap(false).extractSubset(&subset, src_rect);
initial.commit09911bf2008-07-26 23:55:291324
[email protected]82afe4b2010-11-12 20:36:221325 // First do a fast downsample by powers of two to get close to the final size.
1326 SkBitmap downsampled_subset =
1327 SkBitmapOperations::DownsampleByTwoUntilSize(subset, w, h);
1328
1329 // Do a high-quality resize from the downscaled size to the final size.
[email protected]465b34b72008-12-12 20:19:141330 *thumbnail = skia::ImageOperations::Resize(
[email protected]82afe4b2010-11-12 20:36:221331 downsampled_subset, skia::ImageOperations::RESIZE_LANCZOS3, w, h);
initial.commit09911bf2008-07-26 23:55:291332
1333 score->boring_score = CalculateBoringScore(thumbnail);
1334
[email protected]30507922010-01-15 16:48:231335 HISTOGRAM_TIMES("Renderer4.Thumbnail",
1336 base::TimeTicks::Now() - beginning_time);
[email protected]82afe4b2010-11-12 20:36:221337
[email protected]b6e4bec2008-11-12 01:17:151338 return true;
initial.commit09911bf2008-07-26 23:55:291339}
1340
[email protected]30507922010-01-15 16:48:231341bool RenderView::CaptureSnapshot(WebView* view, SkBitmap* snapshot) {
1342 base::TimeTicks beginning_time = base::TimeTicks::Now();
initial.commit09911bf2008-07-26 23:55:291343
[email protected]30507922010-01-15 16:48:231344 skia::PlatformCanvas canvas;
1345 if (!PaintViewIntoCanvas(view, canvas))
1346 return false;
1347
1348 skia::BitmapPlatformDevice& device =
1349 static_cast<skia::BitmapPlatformDevice&>(canvas.getTopPlatformDevice());
1350
1351 const SkBitmap& bitmap = device.accessBitmap(false);
1352 if (!bitmap.copyTo(snapshot, SkBitmap::kARGB_8888_Config))
1353 return false;
1354
1355 HISTOGRAM_TIMES("Renderer4.Snapshot",
1356 base::TimeTicks::Now() - beginning_time);
1357 return true;
initial.commit09911bf2008-07-26 23:55:291358}
1359
1360void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {
1361 if (!webview())
1362 return;
1363
[email protected]3cc72b12010-03-18 23:03:001364 history_list_offset_ = params.current_history_list_offset;
1365 history_list_length_ = params.current_history_list_length;
1366
[email protected]a9f607e2009-10-23 19:59:271367 child_process_logging::SetActiveURL(params.url);
[email protected]f8b6b6f2009-03-10 16:48:261368
initial.commit09911bf2008-07-26 23:55:291369 AboutHandler::MaybeHandle(params.url);
1370
[email protected]ecbf10d2010-02-18 13:03:291371 bool is_reload =
1372 params.navigation_type == ViewMsg_Navigate_Params::RELOAD ||
1373 params.navigation_type == ViewMsg_Navigate_Params::RELOAD_IGNORING_CACHE;
initial.commit09911bf2008-07-26 23:55:291374
[email protected]26aa0482009-09-30 16:55:271375 WebFrame* main_frame = webview()->mainFrame();
[email protected]dd7daa82009-08-10 05:46:451376 if (is_reload && main_frame->currentHistoryItem().isNull()) {
initial.commit09911bf2008-07-26 23:55:291377 // We cannot reload if we do not have any history state. This happens, for
1378 // example, when recovering from a crash. Our workaround here is a bit of
1379 // a hack since it means that reload after a crashed tab does not cause an
1380 // end-to-end cache validation.
1381 is_reload = false;
1382 }
1383
[email protected]77f17a82009-05-21 04:42:541384 // A navigation resulting from loading a javascript URL should not be treated
1385 // as a browser initiated event. Instead, we want it to look as if the page
1386 // initiated any load resulting from JS execution.
1387 if (!params.url.SchemeIs(chrome::kJavaScriptScheme)) {
[email protected]5e369672009-11-03 23:48:301388 NavigationState* state = NavigationState::CreateBrowserInitiated(
[email protected]3cc72b12010-03-18 23:03:001389 params.page_id,
1390 params.pending_history_list_offset,
1391 params.transition,
1392 params.request_time);
[email protected]5e369672009-11-03 23:48:301393 if (params.navigation_type == ViewMsg_Navigate_Params::RESTORE) {
1394 // We're doing a load of a page that was restored from the last session.
1395 // By default this prefers the cache over loading (LOAD_PREFERRING_CACHE)
1396 // which can result in stale data for pages that are set to expire. We
1397 // explicitly override that by setting the policy here so that as
1398 // necessary we load from the network.
1399 state->set_cache_policy_override(WebURLRequest::UseProtocolCachePolicy);
1400 }
1401 pending_navigation_state_.reset(state);
[email protected]77f17a82009-05-21 04:42:541402 }
initial.commit09911bf2008-07-26 23:55:291403
[email protected]a7ccc4d2010-01-27 08:14:481404 NavigationState* navigation_state = pending_navigation_state_.get();
1405
[email protected]04d3c6e2009-05-22 17:00:131406 // If we are reloading, then WebKit will use the history state of the current
1407 // page, so we should just ignore any given history state. Otherwise, if we
1408 // have history state, then we need to navigate to it, which corresponds to a
1409 // back/forward navigation event.
[email protected]e6f546c32009-07-01 17:12:551410 if (is_reload) {
[email protected]a7ccc4d2010-01-27 08:14:481411 if (navigation_state)
1412 navigation_state->set_load_type(NavigationState::RELOAD);
[email protected]ecbf10d2010-02-18 13:03:291413 bool ignore_cache = (params.navigation_type ==
1414 ViewMsg_Navigate_Params::RELOAD_IGNORING_CACHE);
1415 main_frame->reload(ignore_cache);
[email protected]e6f546c32009-07-01 17:12:551416 } else if (!params.state.empty()) {
[email protected]04d3c6e2009-05-22 17:00:131417 // We must know the page ID of the page we are navigating back to.
[email protected]f929f2f22009-06-12 16:56:581418 DCHECK_NE(params.page_id, -1);
[email protected]a7ccc4d2010-01-27 08:14:481419 if (navigation_state)
1420 navigation_state->set_load_type(NavigationState::HISTORY_LOAD);
[email protected]dd7daa82009-08-10 05:46:451421 main_frame->loadHistoryItem(
[email protected]ca948a22009-06-25 19:36:171422 webkit_glue::HistoryItemFromString(params.state));
[email protected]04d3c6e2009-05-22 17:00:131423 } else {
1424 // Navigate to the given URL.
[email protected]726985e22009-06-18 21:09:281425 WebURLRequest request(params.url);
initial.commit09911bf2008-07-26 23:55:291426
[email protected]e6f546c32009-07-01 17:12:551427 // A session history navigation should have been accompanied by state.
1428 DCHECK_EQ(params.page_id, -1);
[email protected]04d3c6e2009-05-22 17:00:131429
[email protected]dd7daa82009-08-10 05:46:451430 if (main_frame->isViewSourceModeEnabled())
[email protected]e6f546c32009-07-01 17:12:551431 request.setCachePolicy(WebURLRequest::ReturnCacheDataElseLoad);
[email protected]04d3c6e2009-05-22 17:00:131432
[email protected]726985e22009-06-18 21:09:281433 if (params.referrer.is_valid()) {
1434 request.setHTTPHeaderField(WebString::fromUTF8("Referer"),
1435 WebString::fromUTF8(params.referrer.spec()));
1436 }
[email protected]04d3c6e2009-05-22 17:00:131437
[email protected]52c68652010-12-07 17:47:041438 if (!params.extra_headers.empty()) {
1439 for (net::HttpUtil::HeadersIterator i(params.extra_headers.begin(),
1440 params.extra_headers.end(), "\n");
1441 i.GetNext(); ) {
1442 request.addHTTPHeaderField(WebString::fromUTF8(i.name()),
1443 WebString::fromUTF8(i.values()));
1444 }
1445 }
1446
[email protected]90dba072011-01-20 20:10:201447 if (navigation_state) {
1448 if (params.navigation_type != ViewMsg_Navigate_Params::PRERENDER) {
1449 navigation_state->set_load_type(NavigationState::NORMAL_LOAD);
1450 } else {
1451 navigation_state->set_load_type(NavigationState::PRERENDER_LOAD);
[email protected]987d51af2011-02-24 17:50:181452 is_prerendering_ = true;
[email protected]90dba072011-01-20 20:10:201453 }
1454 }
[email protected]dd7daa82009-08-10 05:46:451455 main_frame->loadRequest(request);
[email protected]c0588052008-10-27 23:01:501456 }
1457
[email protected]77f17a82009-05-21 04:42:541458 // In case LoadRequest failed before DidCreateDataSource was called.
1459 pending_navigation_state_.reset();
initial.commit09911bf2008-07-26 23:55:291460}
1461
1462// Stop loading the current page
1463void RenderView::OnStop() {
1464 if (webview())
[email protected]b4bb2502009-10-01 22:35:271465 webview()->mainFrame()->stopLoading();
initial.commit09911bf2008-07-26 23:55:291466}
1467
[email protected]ecbf10d2010-02-18 13:03:291468// Reload current focused frame.
1469// E.g. called by right-clicking on the frame and picking "reload this frame".
[email protected]1dda4022010-01-28 18:24:561470void RenderView::OnReloadFrame() {
[email protected]ecbf10d2010-02-18 13:03:291471 if (webview() && webview()->focusedFrame()) {
1472 // We always obey the cache (ignore_cache=false) here.
1473 // TODO(evanm): perhaps we could allow shift-clicking the menu item to do
1474 // a cache-ignoring reload of the frame.
1475 webview()->focusedFrame()->reload(false);
1476 }
[email protected]1dda4022010-01-28 18:24:561477}
1478
initial.commit09911bf2008-07-26 23:55:291479void RenderView::OnCopyImageAt(int x, int y) {
[email protected]26aa0482009-09-30 16:55:271480 webview()->copyImageAt(WebPoint(x, y));
initial.commit09911bf2008-07-26 23:55:291481}
1482
[email protected]68b1e922009-06-23 16:00:251483void RenderView::OnExecuteEditCommand(const std::string& name,
1484 const std::string& value) {
[email protected]26aa0482009-09-30 16:55:271485 if (!webview() || !webview()->focusedFrame())
[email protected]68b1e922009-06-23 16:00:251486 return;
1487
[email protected]26aa0482009-09-30 16:55:271488 webview()->focusedFrame()->executeCommand(
[email protected]dd7daa82009-08-10 05:46:451489 WebString::fromUTF8(name), WebString::fromUTF8(value));
[email protected]68b1e922009-06-23 16:00:251490}
1491
[email protected]b2abac72009-02-26 12:39:281492void RenderView::OnSetupDevToolsClient() {
[email protected]676126f72011-01-15 00:03:511493 DCHECK(!devtools_client_);
1494 devtools_client_ = new DevToolsClient(this);
[email protected]b2abac72009-02-26 12:39:281495}
1496
initial.commit09911bf2008-07-26 23:55:291497void RenderView::OnUpdateTargetURLAck() {
1498 // Check if there is a targeturl waiting to be sent.
1499 if (target_url_status_ == TARGET_PENDING) {
1500 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_,
1501 pending_target_url_));
1502 }
1503
1504 target_url_status_ = TARGET_NONE;
1505}
1506
1507void RenderView::OnUndo() {
1508 if (!webview())
1509 return;
1510
[email protected]26aa0482009-09-30 16:55:271511 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Undo"));
[email protected]afe3a1672009-11-17 19:04:121512 UserMetricsRecordAction("Undo");
initial.commit09911bf2008-07-26 23:55:291513}
1514
1515void RenderView::OnRedo() {
1516 if (!webview())
1517 return;
1518
[email protected]26aa0482009-09-30 16:55:271519 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Redo"));
[email protected]afe3a1672009-11-17 19:04:121520 UserMetricsRecordAction("Redo");
initial.commit09911bf2008-07-26 23:55:291521}
1522
1523void RenderView::OnCut() {
1524 if (!webview())
1525 return;
1526
[email protected]26aa0482009-09-30 16:55:271527 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Cut"));
[email protected]afe3a1672009-11-17 19:04:121528 UserMetricsRecordAction("Cut");
initial.commit09911bf2008-07-26 23:55:291529}
1530
1531void RenderView::OnCopy() {
1532 if (!webview())
1533 return;
1534
[email protected]26aa0482009-09-30 16:55:271535 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Copy"));
[email protected]afe3a1672009-11-17 19:04:121536 UserMetricsRecordAction("Copy");
initial.commit09911bf2008-07-26 23:55:291537}
1538
[email protected]c0cc3092009-09-12 08:27:271539#if defined(OS_MACOSX)
[email protected]a954bf72009-09-12 07:30:351540void RenderView::OnCopyToFindPboard() {
1541 if (!webview())
1542 return;
1543
1544 // Since the find pasteboard supports only plain text, this can be simpler
1545 // than the |OnCopy()| case.
[email protected]26aa0482009-09-30 16:55:271546 WebFrame* frame = webview()->focusedFrame();
[email protected]a954bf72009-09-12 07:30:351547 if (frame->hasSelection()) {
1548 string16 selection = frame->selectionAsText();
1549 RenderThread::current()->Send(
1550 new ViewHostMsg_ClipboardFindPboardWriteStringAsync(selection));
1551 }
1552
[email protected]afe3a1672009-11-17 19:04:121553 UserMetricsRecordAction("CopyToFindPboard");
[email protected]a954bf72009-09-12 07:30:351554}
[email protected]c0cc3092009-09-12 08:27:271555#endif
[email protected]a954bf72009-09-12 07:30:351556
initial.commit09911bf2008-07-26 23:55:291557void RenderView::OnPaste() {
1558 if (!webview())
1559 return;
1560
[email protected]26aa0482009-09-30 16:55:271561 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Paste"));
[email protected]afe3a1672009-11-17 19:04:121562 UserMetricsRecordAction("Paste");
initial.commit09911bf2008-07-26 23:55:291563}
1564
[email protected]2a3a7762009-10-19 19:17:321565void RenderView::OnReplace(const string16& text) {
initial.commit09911bf2008-07-26 23:55:291566 if (!webview())
1567 return;
1568
[email protected]1ff7a032010-02-03 02:46:031569 WebFrame* frame = webview()->focusedFrame();
1570 if (!frame->hasSelection())
1571 frame->selectWordAroundCaret();
1572 frame->replaceSelection(text);
initial.commit09911bf2008-07-26 23:55:291573}
1574
[email protected]98324892009-09-09 21:16:051575void RenderView::OnAdvanceToNextMisspelling() {
1576 if (!webview())
1577 return;
[email protected]26aa0482009-09-30 16:55:271578 webview()->focusedFrame()->executeCommand(
[email protected]98324892009-09-09 21:16:051579 WebString::fromUTF8("AdvanceToNextMisspelling"));
1580}
1581
1582void RenderView::OnToggleSpellPanel(bool is_currently_visible) {
1583 if (!webview())
1584 return;
1585 // We need to tell the webView whether the spelling panel is visible or not so
1586 // that it won't need to make ipc calls later.
[email protected]8922e1f2009-10-03 05:01:261587 spelling_panel_visible_ = is_currently_visible;
[email protected]26aa0482009-09-30 16:55:271588 webview()->focusedFrame()->executeCommand(
[email protected]98324892009-09-09 21:16:051589 WebString::fromUTF8("ToggleSpellPanel"));
1590}
1591
[email protected]bbbd545c2008-12-15 20:18:041592void RenderView::OnToggleSpellCheck() {
1593 if (!webview())
1594 return;
1595
[email protected]26aa0482009-09-30 16:55:271596 WebFrame* frame = webview()->focusedFrame();
[email protected]dd7daa82009-08-10 05:46:451597 frame->enableContinuousSpellChecking(
1598 !frame->isContinuousSpellCheckingEnabled());
[email protected]bbbd545c2008-12-15 20:18:041599}
1600
initial.commit09911bf2008-07-26 23:55:291601void RenderView::OnDelete() {
1602 if (!webview())
1603 return;
1604
[email protected]26aa0482009-09-30 16:55:271605 webview()->focusedFrame()->executeCommand(WebString::fromUTF8("Delete"));
[email protected]afe3a1672009-11-17 19:04:121606 UserMetricsRecordAction("DeleteSelection");
initial.commit09911bf2008-07-26 23:55:291607}
1608
1609void RenderView::OnSelectAll() {
1610 if (!webview())
1611 return;
1612
[email protected]26aa0482009-09-30 16:55:271613 webview()->focusedFrame()->executeCommand(
[email protected]a100d76bb2009-08-14 17:50:221614 WebString::fromUTF8("SelectAll"));
[email protected]afe3a1672009-11-17 19:04:121615 UserMetricsRecordAction("SelectAll");
initial.commit09911bf2008-07-26 23:55:291616}
1617
1618void RenderView::OnSetInitialFocus(bool reverse) {
1619 if (!webview())
1620 return;
[email protected]26aa0482009-09-30 16:55:271621 webview()->setInitialFocus(reverse);
initial.commit09911bf2008-07-26 23:55:291622}
1623
[email protected]9b66f34bf2010-10-27 20:45:511624void RenderView::OnScrollFocusedEditableNodeIntoView() {
[email protected]13a1e4c3c2011-02-03 21:07:091625 WebKit::WebNode node = GetFocusedNode();
1626 if (!node.isNull()) {
1627 if (IsEditableNode(node))
1628 // TODO(varunjain): Change webkit API to scroll a particular node into
1629 // view and use that API here instead.
1630 webview()->scrollFocusedNodeIntoView();
[email protected]9b66f34bf2010-10-27 20:45:511631 }
1632}
1633
initial.commit09911bf2008-07-26 23:55:291634///////////////////////////////////////////////////////////////////////////////
1635
[email protected]433819d2010-01-30 20:20:011636void RenderView::SetContentSettings(const ContentSettings& settings) {
1637 current_content_settings_ = settings;
[email protected]f85f0702010-01-30 09:31:011638}
1639
initial.commit09911bf2008-07-26 23:55:291640// Tell the embedding application that the URL of the active page has changed
1641void RenderView::UpdateURL(WebFrame* frame) {
[email protected]dd7daa82009-08-10 05:46:451642 WebDataSource* ds = frame->dataSource();
initial.commit09911bf2008-07-26 23:55:291643 DCHECK(ds);
1644
[email protected]726985e22009-06-18 21:09:281645 const WebURLRequest& request = ds->request();
1646 const WebURLRequest& original_request = ds->originalRequest();
1647 const WebURLResponse& response = ds->response();
initial.commit09911bf2008-07-26 23:55:291648
[email protected]daa8c58e2009-06-15 17:21:101649 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
1650 DCHECK(navigation_state);
initial.commit09911bf2008-07-26 23:55:291651
1652 ViewHostMsg_FrameNavigate_Params params;
[email protected]726985e22009-06-18 21:09:281653 params.http_status_code = response.httpStatusCode();
initial.commit09911bf2008-07-26 23:55:291654 params.is_post = false;
1655 params.page_id = page_id_;
[email protected]dabb0d12010-10-05 12:50:071656 params.frame_id = frame->identifier();
[email protected]6d81b482011-02-22 19:47:191657 params.socket_address.set_host(response.remoteIPAddress().utf8());
1658 params.socket_address.set_port(response.remotePort());
[email protected]b9a7c6d42011-02-25 02:13:031659 params.was_fetched_via_proxy = response.wasFetchedViaProxy();
[email protected]af15bed2010-08-25 21:12:091660 params.was_within_same_page = navigation_state->was_within_same_page();
[email protected]e6f546c32009-07-01 17:12:551661 if (!navigation_state->security_info().empty()) {
initial.commit09911bf2008-07-26 23:55:291662 // SSL state specified in the request takes precedence over the one in the
1663 // response.
1664 // So far this is only intended for error pages that are not expected to be
1665 // over ssl, so we should not get any clash.
[email protected]726985e22009-06-18 21:09:281666 DCHECK(response.securityInfo().isEmpty());
[email protected]e6f546c32009-07-01 17:12:551667 params.security_info = navigation_state->security_info();
initial.commit09911bf2008-07-26 23:55:291668 } else {
[email protected]726985e22009-06-18 21:09:281669 params.security_info = response.securityInfo();
initial.commit09911bf2008-07-26 23:55:291670 }
1671
1672 // Set the URL to be displayed in the browser UI to the user.
[email protected]726985e22009-06-18 21:09:281673 if (ds->hasUnreachableURL()) {
1674 params.url = ds->unreachableURL();
initial.commit09911bf2008-07-26 23:55:291675 } else {
[email protected]726985e22009-06-18 21:09:281676 params.url = request.url();
initial.commit09911bf2008-07-26 23:55:291677 }
1678
[email protected]726985e22009-06-18 21:09:281679 GetRedirectChain(ds, &params.redirects);
[email protected]d94dc1e2010-03-04 09:29:241680 params.should_update_history = !ds->hasUnreachableURL() &&
[email protected]b7df1b72011-02-10 00:08:041681 !response.isMultipartPayload() && (response.httpStatusCode() != 404);
initial.commit09911bf2008-07-26 23:55:291682
[email protected]ce0e250d2009-10-23 21:00:351683 params.searchable_form_url = navigation_state->searchable_form_url();
1684 params.searchable_form_encoding =
1685 navigation_state->searchable_form_encoding();
initial.commit09911bf2008-07-26 23:55:291686
1687 const PasswordForm* password_form_data =
[email protected]daa8c58e2009-06-15 17:21:101688 navigation_state->password_form_data();
initial.commit09911bf2008-07-26 23:55:291689 if (password_form_data)
1690 params.password_form = *password_form_data;
1691
1692 params.gesture = navigation_gesture_;
1693 navigation_gesture_ = NavigationGestureUnknown;
1694
[email protected]0f38dc4552011-02-25 11:24:001695 // Make navigation state a part of the FrameNavigate message so that commited
1696 // entry had it at all times.
1697 const WebHistoryItem& item = frame->currentHistoryItem();
1698 if (!item.isNull()) {
1699 params.content_state = webkit_glue::HistoryItemToString(item);
1700 } else {
1701 params.content_state =
1702 webkit_glue::CreateHistoryStateForURL(GURL(request.url()));
1703 }
1704
[email protected]dd7daa82009-08-10 05:46:451705 if (!frame->parent()) {
initial.commit09911bf2008-07-26 23:55:291706 // Top-level navigation.
1707
[email protected]71b0d5d2010-02-15 05:43:071708 // Clear "block" flags for the new page. This needs to happen before any of
1709 // allowScripts(), allowImages(), allowPlugins() is called for the new page
1710 // so that these functions can correctly detect that a piece of content
1711 // flipped from "not blocked" to "blocked".
1712 ClearBlockedContentSettings();
1713
[email protected]62d2a112010-04-07 00:53:021714 // Set content settings. Default them from the parent window if one exists.
1715 // This makes sure about:blank windows work as expected.
[email protected]f85f0702010-01-30 09:31:011716 HostContentSettings::iterator host_content_settings =
[email protected]9d797f32010-04-23 07:17:541717 host_content_settings_.find(GURL(request.url()));
[email protected]f85f0702010-01-30 09:31:011718 if (host_content_settings != host_content_settings_.end()) {
[email protected]433819d2010-01-30 20:20:011719 SetContentSettings(host_content_settings->second);
[email protected]f85f0702010-01-30 09:31:011720
1721 // These content settings were merely recorded transiently for this load.
1722 // We can erase them now. If at some point we reload this page, the
1723 // browser will send us new, up-to-date content settings.
1724 host_content_settings_.erase(host_content_settings);
[email protected]3a387ae2010-04-08 01:58:401725 } else if (frame->opener()) {
[email protected]8128cdd02010-07-21 20:40:101726 // The opener's view is not guaranteed to be non-null (it could be
1727 // detached from its page but not yet destructed).
1728 if (WebView* opener_view = frame->opener()->view()) {
1729 RenderView* opener = FromWebView(opener_view);
1730 SetContentSettings(opener->current_content_settings_);
1731 }
[email protected]f85f0702010-01-30 09:31:011732 }
1733
[email protected]b75b8292010-10-01 07:28:251734 // Set zoom level, but don't do it for full-page plugin since they don't use
1735 // the same zoom settings.
[email protected]f85f0702010-01-30 09:31:011736 HostZoomLevels::iterator host_zoom =
[email protected]9d797f32010-04-23 07:17:541737 host_zoom_levels_.find(GURL(request.url()));
[email protected]b75b8292010-10-01 07:28:251738 if (webview()->mainFrame()->document().isPluginDocument()) {
1739 // Reset the zoom levels for plugins.
[email protected]b75b8292010-10-01 07:28:251740 webview()->setZoomLevel(false, 0);
[email protected]b75b8292010-10-01 07:28:251741 } else {
1742 if (host_zoom != host_zoom_levels_.end())
[email protected]b75b8292010-10-01 07:28:251743 webview()->setZoomLevel(false, host_zoom->second);
[email protected]b75b8292010-10-01 07:28:251744 }
1745
[email protected]f85f0702010-01-30 09:31:011746 if (host_zoom != host_zoom_levels_.end()) {
[email protected]40bd6582009-12-04 23:49:511747 // This zoom level was merely recorded transiently for this load. We can
1748 // erase it now. If at some point we reload this page, the browser will
1749 // send us a new, up-to-date zoom level.
[email protected]f85f0702010-01-30 09:31:011750 host_zoom_levels_.erase(host_zoom);
[email protected]40bd6582009-12-04 23:49:511751 }
1752
[email protected]b75b8292010-10-01 07:28:251753 // Reset the zoom limits in case a plugin had changed them previously. This
1754 // will also call us back which will cause us to send a message to
1755 // update TabContents.
[email protected]b75b8292010-10-01 07:28:251756 webview()->zoomLimitsChanged(
1757 WebView::zoomFactorToZoomLevel(WebView::minTextSizeMultiplier),
1758 WebView::zoomFactorToZoomLevel(WebView::maxTextSizeMultiplier));
[email protected]b75b8292010-10-01 07:28:251759
initial.commit09911bf2008-07-26 23:55:291760 // Update contents MIME type for main frame.
[email protected]9c5645b2009-08-11 03:37:551761 params.contents_mime_type = ds->response().mimeType().utf8();
initial.commit09911bf2008-07-26 23:55:291762
[email protected]daa8c58e2009-06-15 17:21:101763 params.transition = navigation_state->transition_type();
initial.commit09911bf2008-07-26 23:55:291764 if (!PageTransition::IsMainFrame(params.transition)) {
1765 // If the main frame does a load, it should not be reported as a subframe
1766 // navigation. This can occur in the following case:
1767 // 1. You're on a site with frames.
1768 // 2. You do a subframe navigation. This is stored with transition type
1769 // MANUAL_SUBFRAME.
1770 // 3. You navigate to some non-frame site, say, google.com.
1771 // 4. You navigate back to the page from step 2. Since it was initially
1772 // MANUAL_SUBFRAME, it will be that same transition type here.
1773 // We don't want that, because any navigation that changes the toplevel
1774 // frame should be tracked as a toplevel navigation (this allows us to
1775 // update the URL bar, etc).
1776 params.transition = PageTransition::LINK;
1777 }
1778
initial.commit09911bf2008-07-26 23:55:291779 // If we have a valid consumed client redirect source,
1780 // the page contained a client redirect (meta refresh, document.loc...),
1781 // so we set the referrer and transition to match.
1782 if (completed_client_redirect_src_.is_valid()) {
[email protected]77e09a92008-08-01 18:11:041783 DCHECK(completed_client_redirect_src_ == params.redirects[0]);
initial.commit09911bf2008-07-26 23:55:291784 params.referrer = completed_client_redirect_src_;
1785 params.transition = static_cast<PageTransition::Type>(
1786 params.transition | PageTransition::CLIENT_REDIRECT);
1787 } else {
1788 // Bug 654101: the referrer will be empty on https->http transitions. It
1789 // would be nice if we could get the real referrer from somewhere.
[email protected]726985e22009-06-18 21:09:281790 params.referrer = GURL(
1791 original_request.httpHeaderField(WebString::fromUTF8("Referer")));
initial.commit09911bf2008-07-26 23:55:291792 }
1793
[email protected]726985e22009-06-18 21:09:281794 string16 method = request.httpMethod();
1795 if (EqualsASCII(method, "POST"))
initial.commit09911bf2008-07-26 23:55:291796 params.is_post = true;
1797
[email protected]c2a797d2009-09-21 16:46:321798 // Save some histogram data so we can compute the average memory used per
1799 // page load of the glyphs.
1800 UMA_HISTOGRAM_COUNTS_10000("Memory.GlyphPagesPerLoad",
1801 webkit_glue::GetGlyphPageCount());
1802
[email protected]15cf526b2010-02-12 06:33:491803 // This message needs to be sent before any of allowScripts(),
1804 // allowImages(), allowPlugins() is called for the new page, so that when
1805 // these functions send a ViewHostMsg_ContentBlocked message, it arrives
1806 // after the ViewHostMsg_FrameNavigate message.
initial.commit09911bf2008-07-26 23:55:291807 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
1808 } else {
1809 // Subframe navigation: the type depends on whether this navigation
1810 // generated a new session history entry. When they do generate a session
1811 // history entry, it means the user initiated the navigation and we should
1812 // mark it as such. This test checks if this is the first time UpdateURL
1813 // has been called since WillNavigateToURL was called to initiate the load.
1814 if (page_id_ > last_page_id_sent_to_browser_)
1815 params.transition = PageTransition::MANUAL_SUBFRAME;
1816 else
1817 params.transition = PageTransition::AUTO_SUBFRAME;
1818
initial.commit09911bf2008-07-26 23:55:291819 Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
1820 }
1821
1822 last_page_id_sent_to_browser_ =
1823 std::max(last_page_id_sent_to_browser_, page_id_);
1824
1825 // If we end up reusing this WebRequest (for example, due to a #ref click),
[email protected]daa8c58e2009-06-15 17:21:101826 // we don't want the transition type to persist. Just clear it.
1827 navigation_state->set_transition_type(PageTransition::LINK);
[email protected]266eb6f2008-09-30 23:56:501828
[email protected]af15bed2010-08-25 21:12:091829 // Check if the navigation was within the same page, in which case we don't
1830 // want to clear the accessibility cache.
1831 if (accessibility_.get() && !navigation_state->was_within_same_page()) {
[email protected]17455962010-02-24 01:39:351832 accessibility_.reset();
[email protected]dea2d372010-09-25 06:41:141833 pending_accessibility_notifications_.clear();
[email protected]266eb6f2008-09-30 23:56:501834 }
initial.commit09911bf2008-07-26 23:55:291835}
1836
1837// Tell the embedding application that the title of the active page has changed
[email protected]3d9689372009-09-10 04:29:171838void RenderView::UpdateTitle(WebFrame* frame, const string16& title) {
initial.commit09911bf2008-07-26 23:55:291839 // Ignore all but top level navigations...
[email protected]3d9689372009-09-10 04:29:171840 if (!frame->parent()) {
[email protected]f0af6a72009-05-30 05:25:171841 Send(new ViewHostMsg_UpdateTitle(
[email protected]3d9689372009-09-10 04:29:171842 routing_id_,
1843 page_id_,
1844 UTF16ToWideHack(title.length() > chrome::kMaxTitleChars ?
1845 title.substr(0, chrome::kMaxTitleChars) : title)));
[email protected]f0af6a72009-05-30 05:25:171846 }
initial.commit09911bf2008-07-26 23:55:291847}
1848
1849void RenderView::UpdateEncoding(WebFrame* frame,
[email protected]41fc0322009-09-04 22:23:401850 const std::string& encoding_name) {
initial.commit09911bf2008-07-26 23:55:291851 // Only update main frame's encoding_name.
[email protected]26aa0482009-09-30 16:55:271852 if (webview()->mainFrame() == frame &&
initial.commit09911bf2008-07-26 23:55:291853 last_encoding_name_ != encoding_name) {
[email protected]e38f40152008-09-12 23:08:301854 // Save the encoding name for later comparing.
initial.commit09911bf2008-07-26 23:55:291855 last_encoding_name_ = encoding_name;
1856
[email protected]e38f40152008-09-12 23:08:301857 Send(new ViewHostMsg_UpdateEncoding(routing_id_, last_encoding_name_));
initial.commit09911bf2008-07-26 23:55:291858 }
1859}
1860
[email protected]e15f680732010-11-23 22:30:201861// Sends the last committed session history state to the browser so it will be
1862// saved before we navigate to a new page. This must be called *before* the
1863// page ID has been updated so we know what it was.
initial.commit09911bf2008-07-26 23:55:291864void RenderView::UpdateSessionHistory(WebFrame* frame) {
1865 // If we have a valid page ID at this point, then it corresponds to the page
1866 // we are navigating away from. Otherwise, this is the first navigation, so
1867 // there is no past session history to record.
1868 if (page_id_ == -1)
1869 return;
1870
[email protected]ca948a22009-06-25 19:36:171871 const WebHistoryItem& item =
[email protected]26aa0482009-09-30 16:55:271872 webview()->mainFrame()->previousHistoryItem();
[email protected]ca948a22009-06-25 19:36:171873 if (item.isNull())
initial.commit09911bf2008-07-26 23:55:291874 return;
[email protected]ca948a22009-06-25 19:36:171875
1876 Send(new ViewHostMsg_UpdateState(
1877 routing_id_, page_id_, webkit_glue::HistoryItemToString(item)));
initial.commit09911bf2008-07-26 23:55:291878}
1879
[email protected]3d9689372009-09-10 04:29:171880void RenderView::OpenURL(
1881 const GURL& url, const GURL& referrer, WebNavigationPolicy policy) {
1882 Send(new ViewHostMsg_OpenURL(
1883 routing_id_, url, referrer, NavigationPolicyToDisposition(policy)));
1884}
1885
[email protected]79dbc662009-09-04 05:42:511886// WebViewDelegate ------------------------------------------------------------
initial.commit09911bf2008-07-26 23:55:291887
initial.commit09911bf2008-07-26 23:55:291888void RenderView::LoadNavigationErrorPage(WebFrame* frame,
[email protected]726985e22009-06-18 21:09:281889 const WebURLRequest& failed_request,
1890 const WebURLError& error,
initial.commit09911bf2008-07-26 23:55:291891 const std::string& html,
1892 bool replace) {
[email protected]726985e22009-06-18 21:09:281893 GURL failed_url = error.unreachableURL;
initial.commit09911bf2008-07-26 23:55:291894 std::string alt_html;
[email protected]2a521c52011-01-26 18:45:211895 const Extension* extension = NULL;
initial.commit09911bf2008-07-26 23:55:291896 if (html.empty()) {
1897 // Use a local error page.
1898 int resource_id;
1899 DictionaryValue error_strings;
[email protected]5351dbc2010-08-27 15:22:111900
[email protected]81654282010-10-04 17:08:061901 if (failed_url.is_valid() && !failed_url.SchemeIs(chrome::kExtensionScheme))
[email protected]2a521c52011-01-26 18:45:211902 extension = render_thread_->GetExtensions()->GetByURL(failed_url);
[email protected]5351dbc2010-08-27 15:22:111903 if (extension) {
[email protected]3f853a52010-09-13 19:15:081904 LocalizedError::GetAppErrorStrings(error, failed_url, extension,
1905 &error_strings);
[email protected]5351dbc2010-08-27 15:22:111906
1907 // TODO(erikkay): Should we use a different template for different
1908 // error messages?
1909 resource_id = IDR_ERROR_APP_HTML;
initial.commit09911bf2008-07-26 23:55:291910 } else {
[email protected]3f853a52010-09-13 19:15:081911 if (error.domain == WebString::fromUTF8(net::kErrorDomain) &&
1912 error.reason == net::ERR_CACHE_MISS &&
[email protected]5351dbc2010-08-27 15:22:111913 EqualsASCII(failed_request.httpMethod(), "POST")) {
[email protected]3f853a52010-09-13 19:15:081914 LocalizedError::GetFormRepostStrings(failed_url, &error_strings);
[email protected]5351dbc2010-08-27 15:22:111915 } else {
[email protected]3f853a52010-09-13 19:15:081916 LocalizedError::GetStrings(error, &error_strings);
[email protected]5351dbc2010-08-27 15:22:111917 }
[email protected]75891fe2010-11-20 15:55:181918 resource_id = IDR_NET_ERROR_HTML;
initial.commit09911bf2008-07-26 23:55:291919 }
initial.commit09911bf2008-07-26 23:55:291920
1921 alt_html = GetAltHTMLForTemplate(error_strings, resource_id);
1922 } else {
1923 alt_html = html;
1924 }
1925
[email protected]dd7daa82009-08-10 05:46:451926 frame->loadHTMLString(alt_html,
[email protected]144143c2010-10-28 08:17:361927 GURL(chrome::kUnreachableWebDataURL),
[email protected]e6f546c32009-07-01 17:12:551928 failed_url,
1929 replace);
initial.commit09911bf2008-07-26 23:55:291930}
1931
[email protected]7ccddb8c2009-08-04 17:36:551932void RenderView::BindDOMAutomationController(WebFrame* frame) {
[email protected]2f979172010-09-16 21:54:031933 if (!dom_automation_controller_.get()) {
1934 dom_automation_controller_.reset(new DomAutomationController());
1935 }
1936 dom_automation_controller_->set_message_sender(this);
1937 dom_automation_controller_->set_routing_id(routing_id_);
1938 dom_automation_controller_->BindToJavascript(frame,
[email protected]906690b2010-12-03 18:11:251939 "domAutomationController");
initial.commit09911bf2008-07-26 23:55:291940}
1941
initial.commit09911bf2008-07-26 23:55:291942bool RenderView::RunJavaScriptMessage(int type,
1943 const std::wstring& message,
1944 const std::wstring& default_value,
[email protected]a455d3812009-03-05 20:18:071945 const GURL& frame_url,
initial.commit09911bf2008-07-26 23:55:291946 std::wstring* result) {
1947 bool success = false;
1948 std::wstring result_temp;
1949 if (!result)
1950 result = &result_temp;
initial.commit09911bf2008-07-26 23:55:291951
[email protected]12636df2009-09-28 22:32:211952 SendAndRunNestedMessageLoop(new ViewHostMsg_RunJavaScriptMessage(
1953 routing_id_, message, default_value, frame_url, type, &success, result));
initial.commit09911bf2008-07-26 23:55:291954 return success;
1955}
1956
[email protected]c1f50aa2010-02-18 03:46:571957bool RenderView::SendAndRunNestedMessageLoop(IPC::SyncMessage* message) {
1958 // Before WebKit asks us to show an alert (etc.), it takes care of doing the
1959 // equivalent of WebView::willEnterModalLoop. In the case of showModalDialog
1960 // it is particularly important that we do not call willEnterModalLoop as
1961 // that would defer resource loads for the dialog itself.
1962 if (RenderThread::current()) // Will be NULL during unit tests.
1963 RenderThread::current()->DoNotNotifyWebKitOfModalLoop();
1964
1965 message->EnableMessagePumping(); // Runs a nested message loop.
1966 return Send(message);
1967}
1968
[email protected]2de7e002010-10-11 22:58:201969void RenderView::AddGURLSearchProvider(
1970 const GURL& osd_url,
1971 const ViewHostMsg_PageHasOSDD_Type& provider_type) {
initial.commit09911bf2008-07-26 23:55:291972 if (!osd_url.is_empty())
1973 Send(new ViewHostMsg_PageHasOSDD(routing_id_, page_id_, osd_url,
[email protected]2de7e002010-10-11 22:58:201974 provider_type));
initial.commit09911bf2008-07-26 23:55:291975}
1976
[email protected]e8345242010-05-06 03:00:401977void RenderView::OnAllowScriptToClose(bool script_can_close) {
1978 script_can_close_ = script_can_close;
[email protected]634a6f92008-12-01 21:39:311979}
1980
initial.commit09911bf2008-07-26 23:55:291981uint32 RenderView::GetCPBrowsingContext() {
1982 uint32 context = 0;
1983 Send(new ViewHostMsg_GetCPBrowsingContext(&context));
1984 return context;
1985}
1986
[email protected]2de7e002010-10-11 22:58:201987void RenderView::AddSearchProvider(
1988 const std::string& url,
1989 const ViewHostMsg_PageHasOSDD_Type& provider_type) {
1990 if (provider_type.type ==
1991 ViewHostMsg_PageHasOSDD_Type::EXPLICIT_DEFAULT_PROVIDER &&
1992 !webview()->mainFrame()->isProcessingUserGesture())
1993 return;
1994
1995 AddGURLSearchProvider(GURL(url), provider_type);
initial.commit09911bf2008-07-26 23:55:291996}
1997
[email protected]155f35e2010-07-17 00:30:181998ViewHostMsg_GetSearchProviderInstallState_Params
[email protected]52ded452010-08-23 22:01:251999RenderView::GetSearchProviderInstallState(WebFrame* frame,
2000 const std::string& url) {
[email protected]155f35e2010-07-17 00:30:182001 GURL inquiry_url = GURL(url);
2002 if (inquiry_url.is_empty())
2003 return ViewHostMsg_GetSearchProviderInstallState_Params::Denied();
[email protected]52ded452010-08-23 22:01:252004
[email protected]155f35e2010-07-17 00:30:182005 ViewHostMsg_GetSearchProviderInstallState_Params install;
2006 Send(new ViewHostMsg_GetSearchProviderInstallState(routing_id_,
[email protected]52ded452010-08-23 22:01:252007 frame->url(),
[email protected]155f35e2010-07-17 00:30:182008 inquiry_url,
2009 &install));
2010 return install;
2011}
2012
[email protected]f103ab72009-09-02 17:10:592013void RenderView::OnMissingPluginStatus(
2014 WebPluginDelegateProxy* delegate,
2015 int status) {
[email protected]6c8afae52009-01-22 02:24:572016#if defined(OS_WIN)
[email protected]f103ab72009-09-02 17:10:592017 if (!first_default_plugin_) {
initial.commit09911bf2008-07-26 23:55:292018 // Show the InfoBar for the first available plugin.
[email protected]191eb3f72010-12-21 06:27:502019 if (status == webkit::npapi::default_plugin::MISSING_PLUGIN_AVAILABLE) {
[email protected]f103ab72009-09-02 17:10:592020 first_default_plugin_ = delegate->AsWeakPtr();
initial.commit09911bf2008-07-26 23:55:292021 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
2022 }
2023 } else {
2024 // Closes the InfoBar if user clicks on the plugin (instead of the InfoBar)
2025 // to start the download/install.
[email protected]191eb3f72010-12-21 06:27:502026 if (status ==
2027 webkit::npapi::default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD) {
initial.commit09911bf2008-07-26 23:55:292028 Send(new ViewHostMsg_MissingPluginStatus(routing_id_, status));
2029 }
2030 }
[email protected]6c8afae52009-01-22 02:24:572031#else
[email protected]76c3b312010-05-20 21:38:292032 // TODO(port): Implement the infobar that accompanies the default plugin.
2033 // Linux: http://crbug.com/10952
2034 // Mac: http://crbug.com/17392
[email protected]6c8afae52009-01-22 02:24:572035 NOTIMPLEMENTED();
2036#endif
initial.commit09911bf2008-07-26 23:55:292037}
2038
[email protected]48c9cf2d2009-09-16 16:47:522039// WebKit::WebViewClient ------------------------------------------------------
2040
[email protected]844acf372011-01-14 10:49:272041WebView* RenderView::createView(
2042 WebFrame* creator,
2043 const WebURLRequest& request,
2044 const WebWindowFeatures& features,
2045 const WebString& frame_name) {
[email protected]48c9cf2d2009-09-16 16:47:522046 // Check to make sure we aren't overloading on popups.
2047 if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups)
2048 return NULL;
2049
2050 // This window can't be closed from a window.close() call until we receive a
2051 // message from the Browser process explicitly allowing it.
[email protected]e8345242010-05-06 03:00:402052 script_can_close_ = false;
[email protected]48c9cf2d2009-09-16 16:47:522053
[email protected]8ab04652010-06-12 02:47:262054 ViewHostMsg_CreateWindow_Params params;
2055 params.opener_id = routing_id_;
2056 params.user_gesture = creator->isProcessingUserGesture();
2057 params.window_container_type = WindowFeaturesToContainerType(features);
2058 params.session_storage_namespace_id = session_storage_namespace_id_;
2059 params.frame_name = frame_name;
[email protected]41e65502011-01-21 09:29:112060 params.opener_frame_id = creator->identifier();
2061 params.opener_url = creator->url();
2062 params.opener_security_origin = creator->securityOrigin().toString().utf8();
2063 if (!request.isNull())
2064 params.target_url = request.url();
[email protected]8ab04652010-06-12 02:47:262065
[email protected]48c9cf2d2009-09-16 16:47:522066 int32 routing_id = MSG_ROUTING_NONE;
[email protected]4e6419c2010-01-15 04:50:342067 int64 cloned_session_storage_namespace_id;
[email protected]8ab04652010-06-12 02:47:262068 bool opener_suppressed = creator->willSuppressOpenerInNewFrame();
[email protected]48c9cf2d2009-09-16 16:47:522069
[email protected]48c9cf2d2009-09-16 16:47:522070 render_thread_->Send(
[email protected]8ab04652010-06-12 02:47:262071 new ViewHostMsg_CreateWindow(params,
2072 &routing_id,
2073 &cloned_session_storage_namespace_id));
[email protected]12636df2009-09-28 22:32:212074 if (routing_id == MSG_ROUTING_NONE)
[email protected]48c9cf2d2009-09-16 16:47:522075 return NULL;
[email protected]48c9cf2d2009-09-16 16:47:522076
[email protected]48c9cf2d2009-09-16 16:47:522077 RenderView* view = RenderView::Create(render_thread_,
[email protected]659f73fa2009-10-13 13:43:422078 0,
[email protected]12636df2009-09-28 22:32:212079 routing_id_,
[email protected]48c9cf2d2009-09-16 16:47:522080 renderer_preferences_,
2081 webkit_preferences_,
[email protected]12636df2009-09-28 22:32:212082 shared_popup_counter_,
[email protected]4e6419c2010-01-15 04:50:342083 routing_id,
[email protected]8ab04652010-06-12 02:47:262084 cloned_session_storage_namespace_id,
2085 frame_name);
2086 view->opened_by_user_gesture_ = params.user_gesture;
[email protected]48c9cf2d2009-09-16 16:47:522087
[email protected]007a848b2009-10-26 15:55:462088 // Record whether the creator frame is trying to suppress the opener field.
2089 view->opener_suppressed_ = opener_suppressed;
2090
[email protected]48c9cf2d2009-09-16 16:47:522091 // Record the security origin of the creator.
[email protected]91733b62009-09-18 06:21:092092 GURL creator_url(creator->securityOrigin().toString().utf8());
[email protected]48c9cf2d2009-09-16 16:47:522093 if (!creator_url.is_valid() || !creator_url.IsStandard())
2094 creator_url = GURL();
2095 view->creator_url_ = creator_url;
2096
2097 // Copy over the alternate error page URL so we can have alt error pages in
2098 // the new render view (we don't need the browser to send the URL back down).
2099 view->alternate_error_page_url_ = alternate_error_page_url_;
2100
2101 return view->webview();
2102}
2103
[email protected]3e2b375b2010-04-07 17:03:122104WebWidget* RenderView::createPopupMenu(WebKit::WebPopupType popup_type) {
[email protected]48c9cf2d2009-09-16 16:47:522105 RenderWidget* widget = RenderWidget::Create(routing_id_,
2106 render_thread_,
[email protected]3e2b375b2010-04-07 17:03:122107 popup_type);
[email protected]48c9cf2d2009-09-16 16:47:522108 return widget->webwidget();
2109}
2110
2111WebWidget* RenderView::createPopupMenu(const WebPopupMenuInfo& info) {
[email protected]8de12d942010-11-17 20:42:442112 // TODO(jcivelli): Remove this deprecated method when its been removed from
2113 // the WebViewClient interface. It's been replaced by
2114 // createExternalPopupMenu.
2115 NOTREACHED();
2116 return NULL;
[email protected]48c9cf2d2009-09-16 16:47:522117}
2118
[email protected]caf706f2010-10-26 17:54:082119WebExternalPopupMenu* RenderView::createExternalPopupMenu(
2120 const WebPopupMenuInfo& popup_menu_info,
2121 WebExternalPopupMenuClient* popup_menu_client) {
2122 DCHECK(!external_popup_menu_.get());
2123 external_popup_menu_.reset(
2124 new ExternalPopupMenu(this, popup_menu_info, popup_menu_client));
2125 return external_popup_menu_.get();
2126}
2127
[email protected]0bd753682010-12-16 18:15:522128webkit::ppapi::FullscreenContainer*
2129RenderView::CreatePepperFullscreenContainer(
2130 webkit::ppapi::PluginInstance* plugin) {
[email protected]79c7bed2010-09-14 22:28:392131 RenderWidgetFullscreenPepper* widget =
2132 RenderWidgetFullscreenPepper::Create(routing_id_, render_thread_, plugin);
2133 widget->show(WebKit::WebNavigationPolicyIgnore);
[email protected]92abcb832011-01-06 20:39:562134 return widget;
[email protected]79c7bed2010-09-14 22:28:392135}
2136
[email protected]68c50e52010-05-12 11:14:392137WebStorageNamespace* RenderView::createSessionStorageNamespace(unsigned quota) {
[email protected]bd92c3a2010-01-13 05:02:342138 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess))
[email protected]68c50e52010-05-12 11:14:392139 return WebStorageNamespace::createSessionStorageNamespace(quota);
[email protected]59afea12010-01-20 04:48:292140 CHECK(session_storage_namespace_id_ != kInvalidSessionStorageNamespaceId);
2141 return new RendererWebStorageNamespaceImpl(DOM_STORAGE_SESSION,
2142 session_storage_namespace_id_);
[email protected]bd92c3a2010-01-13 05:02:342143}
2144
[email protected]48c9cf2d2009-09-16 16:47:522145void RenderView::didAddMessageToConsole(
2146 const WebConsoleMessage& message, const WebString& source_name,
2147 unsigned source_line) {
2148 Send(new ViewHostMsg_AddMessageToConsole(routing_id_,
2149 UTF16ToWideHack(message.text),
2150 static_cast<int32>(source_line),
2151 UTF16ToWideHack(source_name)));
2152}
2153
2154void RenderView::printPage(WebFrame* frame) {
[email protected]71a14262009-09-22 20:02:582155 DCHECK(frame);
[email protected]212a49d2010-10-25 18:23:472156 if (CommandLine::ForCurrentProcess()->HasSwitch(
2157 switches::kEnablePrintPreview)) {
[email protected]dec1f292011-02-11 20:20:202158 print_helper_->PrintFrame(frame, true, true);
[email protected]212a49d2010-10-25 18:23:472159 } else {
[email protected]dec1f292011-02-11 20:20:202160 print_helper_->PrintFrame(frame, true, false);
[email protected]212a49d2010-10-25 18:23:472161 }
[email protected]48c9cf2d2009-09-16 16:47:522162}
2163
[email protected]3354d3e2010-06-10 19:53:022164WebKit::WebNotificationPresenter* RenderView::notificationPresenter() {
[email protected]676126f72011-01-15 00:03:512165 return notification_provider_;
[email protected]3354d3e2010-06-10 19:53:022166}
2167
[email protected]48c9cf2d2009-09-16 16:47:522168void RenderView::didStartLoading() {
2169 if (is_loading_) {
2170 DLOG(WARNING) << "didStartLoading called while loading";
2171 return;
2172 }
2173
2174 is_loading_ = true;
2175 // Clear the pointer so that we can assign it only when there is an unknown
2176 // plugin on a page.
2177 first_default_plugin_.reset();
2178
2179 Send(new ViewHostMsg_DidStartLoading(routing_id_));
2180}
2181
2182void RenderView::didStopLoading() {
2183 if (!is_loading_) {
2184 DLOG(WARNING) << "DidStopLoading called while not loading";
2185 return;
2186 }
2187
2188 is_loading_ = false;
2189
2190 // NOTE: For now we're doing the safest thing, and sending out notification
2191 // when done loading. This currently isn't an issue as the favicon is only
2192 // displayed when done loading. Ideally we would send notification when
2193 // finished parsing the head, but webkit doesn't support that yet.
2194 // The feed discovery code would also benefit from access to the head.
[email protected]26aa0482009-09-30 16:55:272195 GURL favicon_url(webview()->mainFrame()->favIconURL());
[email protected]48c9cf2d2009-09-16 16:47:522196 if (!favicon_url.is_empty())
2197 Send(new ViewHostMsg_UpdateFavIconURL(routing_id_, page_id_, favicon_url));
2198
[email protected]26aa0482009-09-30 16:55:272199 AddGURLSearchProvider(webview()->mainFrame()->openSearchDescriptionURL(),
[email protected]2de7e002010-10-11 22:58:202200 ViewHostMsg_PageHasOSDD_Type::Autodetected());
[email protected]48c9cf2d2009-09-16 16:47:522201
2202 Send(new ViewHostMsg_DidStopLoading(routing_id_));
2203
[email protected]90109412010-12-15 17:14:242204 if (load_progress_tracker_ != NULL)
2205 load_progress_tracker_->DidStopLoading();
2206
[email protected]f9f4841b2010-03-20 05:41:422207 MessageLoop::current()->PostDelayedTask(
2208 FROM_HERE,
[email protected]e47aec52010-08-12 00:50:302209 page_info_method_factory_.NewRunnableMethod(
2210 &RenderView::CapturePageInfo, page_id_, false),
[email protected]5ddfd63e2010-09-01 15:48:372211 send_content_state_immediately_ ? 0 : kDelayForCaptureMs);
[email protected]48c9cf2d2009-09-16 16:47:522212}
2213
[email protected]90109412010-12-15 17:14:242214void RenderView::didChangeLoadProgress(WebFrame* frame, double load_progress) {
2215 if (load_progress_tracker_ != NULL)
2216 load_progress_tracker_->DidChangeLoadProgress(frame, load_progress);
2217}
2218
[email protected]f55039a2010-02-17 14:12:062219bool RenderView::isSmartInsertDeleteEnabled() {
2220#if defined(OS_MACOSX)
2221 return true;
2222#else
2223 return false;
2224#endif
2225}
2226
[email protected]04fc9482009-09-18 22:13:032227bool RenderView::isSelectTrailingWhitespaceEnabled() {
2228#if defined(OS_WIN)
2229 return true;
2230#else
2231 return false;
2232#endif
2233}
2234
[email protected]04fc9482009-09-18 22:13:032235void RenderView::didChangeSelection(bool is_empty_selection) {
[email protected]0ff0ff32010-12-21 19:34:422236#if defined(OS_POSIX)
[email protected]04fc9482009-09-18 22:13:032237 if (!handling_input_event_)
2238 return;
2239 // TODO(estade): investigate incremental updates to the selection so that we
2240 // don't send the entire selection over IPC every time.
2241 if (!is_empty_selection) {
2242 // Sometimes we get repeated didChangeSelection calls from webkit when
2243 // the selection hasn't actually changed. We don't want to report these
2244 // because it will cause us to continually claim the X clipboard.
2245 const std::string& this_selection =
[email protected]26aa0482009-09-30 16:55:272246 webview()->focusedFrame()->selectionAsText().utf8();
[email protected]04fc9482009-09-18 22:13:032247 if (this_selection == last_selection_)
2248 return;
2249
2250 Send(new ViewHostMsg_SelectionChanged(routing_id_,
2251 this_selection));
2252 last_selection_ = this_selection;
2253 } else {
2254 last_selection_.clear();
[email protected]eef99c22010-08-17 05:55:162255 Send(new ViewHostMsg_SelectionChanged(routing_id_,
2256 last_selection_));
[email protected]04fc9482009-09-18 22:13:032257 }
[email protected]0ff0ff32010-12-21 19:34:422258#endif // defined(OS_POSIX)
[email protected]04fc9482009-09-18 22:13:032259}
2260
2261void RenderView::didExecuteCommand(const WebString& command_name) {
[email protected]afe3a1672009-11-17 19:04:122262 const std::string& name = UTF16ToUTF8(command_name);
2263 if (StartsWithASCII(name, "Move", true) ||
2264 StartsWithASCII(name, "Insert", true) ||
2265 StartsWithASCII(name, "Delete", true))
[email protected]04fc9482009-09-18 22:13:032266 return;
2267 UserMetricsRecordAction(name);
2268}
2269
[email protected]54ec7f82010-10-21 22:32:512270void RenderView::SendPendingAccessibilityNotifications() {
2271 if (!accessibility_.get())
2272 return;
2273
2274 if (pending_accessibility_notifications_.empty())
2275 return;
2276
2277 // Send all pending accessibility notifications.
2278 std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications;
2279 for (size_t i = 0; i < pending_accessibility_notifications_.size(); i++) {
2280 RendererAccessibilityNotification& notification =
2281 pending_accessibility_notifications_[i];
2282 WebAccessibilityObject obj = accessibility_->getObjectById(notification.id);
2283 if (!obj.isValid())
2284 continue;
2285
2286 ViewHostMsg_AccessibilityNotification_Params param;
[email protected]a527a022011-02-10 02:32:362287 WebAccessibilityNotificationToViewHostMsg(
2288 pending_accessibility_notifications_[i].type, &param.notification_type);
[email protected]70eee342010-11-05 01:59:372289 param.acc_obj = WebAccessibility(
2290 obj, accessibility_.get(), notification.ShouldIncludeChildren());
[email protected]54ec7f82010-10-21 22:32:512291 notifications.push_back(param);
2292 }
2293 pending_accessibility_notifications_.clear();
2294 Send(new ViewHostMsg_AccessibilityNotifications(routing_id_, notifications));
2295 accessibility_ack_pending_ = true;
2296}
2297
[email protected]b2528b72009-09-24 06:57:102298bool RenderView::handleCurrentKeyboardEvent() {
2299 if (edit_commands_.empty())
2300 return false;
2301
[email protected]26aa0482009-09-30 16:55:272302 WebFrame* frame = webview()->focusedFrame();
[email protected]b2528b72009-09-24 06:57:102303 if (!frame)
2304 return false;
2305
2306 EditCommands::iterator it = edit_commands_.begin();
2307 EditCommands::iterator end = edit_commands_.end();
2308
[email protected]507b33ea2009-09-29 03:56:512309 bool did_execute_command = false;
[email protected]b2528b72009-09-24 06:57:102310 for (; it != end; ++it) {
[email protected]e6e15012009-09-30 14:59:332311 // In gtk and cocoa, it's possible to bind multiple edit commands to one
2312 // key (but it's the exception). Once one edit command is not executed, it
2313 // seems safest to not execute the rest.
[email protected]b2528b72009-09-24 06:57:102314 if (!frame->executeCommand(WebString::fromUTF8(it->name),
2315 WebString::fromUTF8(it->value)))
2316 break;
[email protected]507b33ea2009-09-29 03:56:512317 did_execute_command = true;
[email protected]b2528b72009-09-24 06:57:102318 }
2319
[email protected]507b33ea2009-09-29 03:56:512320 return did_execute_command;
[email protected]b2528b72009-09-24 06:57:102321}
2322
[email protected]2a3a7762009-10-19 19:17:322323void RenderView::spellCheck(const WebString& text,
2324 int& misspelled_offset,
2325 int& misspelled_length) {
[email protected]1dbafaf72009-09-23 19:43:562326 EnsureDocumentTag();
[email protected]85c55dc2009-11-06 03:05:462327
[email protected]85c55dc2009-11-06 03:05:462328 string16 word(text);
[email protected]cb6037d2009-11-16 22:55:172329 RenderThread* thread = RenderThread::current();
2330 // Will be NULL during unit tests.
2331 if (thread) {
[email protected]c27324b2009-11-19 22:44:292332 thread->spellchecker()->SpellCheckWord(
[email protected]cb6037d2009-11-16 22:55:172333 word.c_str(), word.size(), document_tag_,
2334 &misspelled_offset, &misspelled_length, NULL);
2335 }
[email protected]1dbafaf72009-09-23 19:43:562336}
2337
[email protected]5efcef62011-02-22 09:00:132338void RenderView::requestCheckingOfText(
2339 const WebString& text,
2340 WebKit::WebTextCheckingCompletion* completion) {
2341 spellcheck_provider_->RequestTextChecking(text, document_tag_, completion);
2342}
2343
[email protected]1dbafaf72009-09-23 19:43:562344WebString RenderView::autoCorrectWord(const WebKit::WebString& word) {
[email protected]2a3a7762009-10-19 19:17:322345 string16 autocorrect_word;
[email protected]1dbafaf72009-09-23 19:43:562346 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]b86c8c12009-10-05 22:01:262347 if (command_line.HasSwitch(switches::kExperimentalSpellcheckerFeatures)) {
[email protected]1dbafaf72009-09-23 19:43:562348 EnsureDocumentTag();
[email protected]cb6037d2009-11-16 22:55:172349 RenderThread* thread = RenderThread::current();
2350 // Will be NULL during unit tests.
2351 if (thread) {
2352 autocorrect_word =
[email protected]c27324b2009-11-19 22:44:292353 thread->spellchecker()->GetAutoCorrectionWord(
[email protected]cb6037d2009-11-16 22:55:172354 word, document_tag_);
2355 }
[email protected]1dbafaf72009-09-23 19:43:562356 }
[email protected]2a3a7762009-10-19 19:17:322357 return autocorrect_word;
[email protected]1dbafaf72009-09-23 19:43:562358}
2359
[email protected]c49085c72009-10-02 16:28:562360void RenderView::showSpellingUI(bool show) {
2361 Send(new ViewHostMsg_ShowSpellingPanel(routing_id_, show));
2362}
2363
[email protected]8922e1f2009-10-03 05:01:262364bool RenderView::isShowingSpellingUI() {
2365 return spelling_panel_visible_;
2366}
2367
[email protected]1dbafaf72009-09-23 19:43:562368void RenderView::updateSpellingUIWithMisspelledWord(const WebString& word) {
[email protected]2a3a7762009-10-19 19:17:322369 Send(new ViewHostMsg_UpdateSpellingPanelWithMisspelledWord(routing_id_,
2370 word));
[email protected]1dbafaf72009-09-23 19:43:562371}
2372
[email protected]13a1e4c3c2011-02-03 21:07:092373void RenderView::continuousSpellCheckingEnabledStateChanged() {
2374 UpdateToggleSpellCheckCommandState();
2375}
2376
[email protected]a1128322009-10-06 18:38:462377bool RenderView::runFileChooser(
[email protected]01178b52010-01-15 06:59:352378 const WebKit::WebFileChooserParams& params,
[email protected]cdaf8d02010-03-30 19:52:472379 WebFileChooserCompletion* chooser_completion) {
[email protected]7ef03e02010-10-23 11:58:352380 // Do not open the file dialog in a hidden RenderView.
2381 if (is_hidden())
2382 return false;
[email protected]cdaf8d02010-03-30 19:52:472383 ViewHostMsg_RunFileChooser_Params ipc_params;
[email protected]b5977a0c2010-08-24 19:46:262384 if (params.directory)
2385 ipc_params.mode = ViewHostMsg_RunFileChooser_Params::OpenFolder;
2386 else if (params.multiSelect)
2387 ipc_params.mode = ViewHostMsg_RunFileChooser_Params::OpenMultiple;
2388 else
2389 ipc_params.mode = ViewHostMsg_RunFileChooser_Params::Open;
[email protected]cdaf8d02010-03-30 19:52:472390 ipc_params.title = params.title;
2391 ipc_params.default_file_name =
2392 webkit_glue::WebStringToFilePath(params.initialValue);
[email protected]099949132010-09-08 20:24:592393 ipc_params.accept_types = params.acceptTypes;
[email protected]cdaf8d02010-03-30 19:52:472394
2395 return ScheduleFileChooser(ipc_params, chooser_completion);
[email protected]a1128322009-10-06 18:38:462396}
2397
[email protected]48c9cf2d2009-09-16 16:47:522398void RenderView::runModalAlertDialog(
2399 WebFrame* frame, const WebString& message) {
[email protected]9dd7e3d72011-01-20 18:27:062400 RunJavaScriptMessage(ui::MessageBoxFlags::kIsJavascriptAlert,
[email protected]48c9cf2d2009-09-16 16:47:522401 UTF16ToWideHack(message),
2402 std::wstring(),
2403 frame->url(),
2404 NULL);
2405}
2406
2407bool RenderView::runModalConfirmDialog(
2408 WebFrame* frame, const WebString& message) {
[email protected]9dd7e3d72011-01-20 18:27:062409 return RunJavaScriptMessage(ui::MessageBoxFlags::kIsJavascriptConfirm,
[email protected]48c9cf2d2009-09-16 16:47:522410 UTF16ToWideHack(message),
2411 std::wstring(),
2412 frame->url(),
2413 NULL);
2414}
2415
2416bool RenderView::runModalPromptDialog(
2417 WebFrame* frame, const WebString& message, const WebString& default_value,
2418 WebString* actual_value) {
2419 std::wstring result;
[email protected]9dd7e3d72011-01-20 18:27:062420 bool ok = RunJavaScriptMessage(ui::MessageBoxFlags::kIsJavascriptPrompt,
[email protected]48c9cf2d2009-09-16 16:47:522421 UTF16ToWideHack(message),
2422 UTF16ToWideHack(default_value),
2423 frame->url(),
2424 &result);
2425 if (ok)
2426 actual_value->assign(WideToUTF16Hack(result));
2427 return ok;
2428}
2429
2430bool RenderView::runModalBeforeUnloadDialog(
2431 WebFrame* frame, const WebString& message) {
2432 bool success = false;
2433 // This is an ignored return value, but is included so we can accept the same
2434 // response as RunJavaScriptMessage.
2435 std::wstring ignored_result;
[email protected]12636df2009-09-28 22:32:212436 SendAndRunNestedMessageLoop(new ViewHostMsg_RunBeforeUnloadConfirm(
[email protected]48c9cf2d2009-09-16 16:47:522437 routing_id_, frame->url(), UTF16ToWideHack(message), &success,
[email protected]12636df2009-09-28 22:32:212438 &ignored_result));
[email protected]48c9cf2d2009-09-16 16:47:522439 return success;
2440}
2441
[email protected]79e37442009-10-09 18:17:442442void RenderView::showContextMenu(
2443 WebFrame* frame, const WebContextMenuData& data) {
[email protected]c27324b2009-11-19 22:44:292444 ContextMenuParams params = ContextMenuParams(data);
2445 if (!params.misspelled_word.empty() && RenderThread::current()) {
2446 int misspelled_offset, misspelled_length;
[email protected]c76a36a2010-01-26 22:44:042447 bool spelled_right = RenderThread::current()->spellchecker()->
2448 SpellCheckWord(
2449 params.misspelled_word.c_str(), params.misspelled_word.size(),
2450 document_tag_,
2451 &misspelled_offset, &misspelled_length,
2452 &params.dictionary_suggestions);
2453 if (spelled_right)
[email protected]c27324b2009-11-19 22:44:292454 params.misspelled_word.clear();
2455 }
[email protected]216932c2010-08-26 21:44:272456 // Serializing a GURL longer than chrome::kMaxURLChars will fail, so don't do
2457 // it. We replace it with an empty GURL so the appropriate items are disabled
2458 // in the context menu.
2459 // TODO(jcivelli): http://crbug.com/45160 This prevents us from saving large
2460 // data encoded images. We should have a way to save them.
2461 if (params.src_url.spec().size() > chrome::kMaxURLChars)
2462 params.src_url = GURL();
[email protected]521b2482011-01-15 00:10:102463 context_menu_node_ = data.node;
[email protected]c27324b2009-11-19 22:44:292464 Send(new ViewHostMsg_ContextMenu(routing_id_, params));
[email protected]79e37442009-10-09 18:17:442465}
2466
[email protected]52f139e2c2010-06-11 16:56:092467bool RenderView::supportsFullscreen() {
2468 return CommandLine::ForCurrentProcess()->HasSwitch(
2469 switches::kEnableVideoFullscreen);
2470}
2471
2472void RenderView::enterFullscreenForNode(const WebKit::WebNode& node) {
2473 NOTIMPLEMENTED();
2474}
2475
2476void RenderView::exitFullscreenForNode(const WebKit::WebNode& node) {
2477 NOTIMPLEMENTED();
2478}
2479
[email protected]48c9cf2d2009-09-16 16:47:522480void RenderView::setStatusText(const WebString& text) {
2481}
2482
[email protected]163f8242009-10-30 20:19:552483void RenderView::UpdateTargetURL(const GURL& url, const GURL& fallback_url) {
[email protected]aa6b90b32010-04-26 15:49:582484 GURL latest_url = url.is_empty() ? fallback_url : url;
[email protected]48c9cf2d2009-09-16 16:47:522485 if (latest_url == target_url_)
2486 return;
[email protected]163f8242009-10-30 20:19:552487
[email protected]48c9cf2d2009-09-16 16:47:522488 // Tell the browser to display a destination link.
2489 if (target_url_status_ == TARGET_INFLIGHT ||
2490 target_url_status_ == TARGET_PENDING) {
2491 // If we have a request in-flight, save the URL to be sent when we
2492 // receive an ACK to the in-flight request. We can happily overwrite
2493 // any existing pending sends.
2494 pending_target_url_ = latest_url;
2495 target_url_status_ = TARGET_PENDING;
2496 } else {
2497 Send(new ViewHostMsg_UpdateTargetURL(routing_id_, page_id_, latest_url));
2498 target_url_ = latest_url;
2499 target_url_status_ = TARGET_INFLIGHT;
2500 }
2501}
2502
[email protected]13a1e4c3c2011-02-03 21:07:092503void RenderView::UpdateToggleSpellCheckCommandState() {
2504 bool is_enabled = false;
2505 WebKit::WebNode node = GetFocusedNode();
2506 if (!node.isNull())
2507 is_enabled = IsEditableNode(node);
2508
2509 RenderViewCommandCheckedState checked_state =
2510 RENDER_VIEW_COMMAND_CHECKED_STATE_UNCHECKED;
2511 if (is_enabled && webview()) {
2512 WebFrame* frame = webview()->focusedFrame();
2513 if (frame->isContinuousSpellCheckingEnabled())
2514 checked_state = RENDER_VIEW_COMMAND_CHECKED_STATE_CHECKED;
2515 }
2516
2517 Send(new ViewHostMsg_CommandStateChanged(
2518 routing_id_,
2519 RENDER_VIEW_COMMAND_TOGGLE_SPELL_CHECK,
2520 is_enabled,
2521 checked_state));
2522}
2523
[email protected]882daa92009-11-05 16:31:312524void RenderView::StartNavStateSyncTimerIfNecessary() {
2525 int delay;
2526 if (send_content_state_immediately_)
2527 delay = 0;
2528 else if (is_hidden())
2529 delay = kDelaySecondsForContentStateSyncHidden;
2530 else
2531 delay = kDelaySecondsForContentStateSync;
2532
2533 if (nav_state_sync_timer_.IsRunning()) {
2534 // The timer is already running. If the delay of the timer maches the amount
2535 // we want to delay by, then return. Otherwise stop the timer so that it
2536 // gets started with the right delay.
2537 if (nav_state_sync_timer_.GetCurrentDelay().InSeconds() == delay)
2538 return;
2539 nav_state_sync_timer_.Stop();
2540 }
2541
2542 nav_state_sync_timer_.Start(
2543 TimeDelta::FromSeconds(delay), this, &RenderView::SyncNavigationState);
2544}
2545
[email protected]163f8242009-10-30 20:19:552546void RenderView::setMouseOverURL(const WebURL& url) {
2547 mouse_over_url_ = GURL(url);
2548 UpdateTargetURL(mouse_over_url_, focus_url_);
2549}
2550
2551void RenderView::setKeyboardFocusURL(const WebURL& url) {
2552 focus_url_ = GURL(url);
2553 UpdateTargetURL(focus_url_, mouse_over_url_);
2554}
2555
[email protected]48c9cf2d2009-09-16 16:47:522556void RenderView::setToolTipText(const WebString& text, WebTextDirection hint) {
2557 Send(new ViewHostMsg_SetTooltipText(routing_id_, UTF16ToWideHack(text),
2558 hint));
2559}
2560
[email protected]c27ae592010-03-18 15:24:412561void RenderView::startDragging(const WebDragData& data,
2562 WebDragOperationsMask mask,
2563 const WebImage& image,
2564 const WebPoint& imageOffset) {
2565#if WEBKIT_USING_SKIA
2566 SkBitmap bitmap(image.getSkBitmap());
2567#elif WEBKIT_USING_CG
[email protected]78043bdd2010-04-05 18:45:332568 SkBitmap bitmap = gfx::CGImageToSkBitmap(image.getCGImageRef());
[email protected]c27ae592010-03-18 15:24:412569#endif
2570
[email protected]48c9cf2d2009-09-16 16:47:522571 Send(new ViewHostMsg_StartDragging(routing_id_,
2572 WebDropData(data),
[email protected]c27ae592010-03-18 15:24:412573 mask,
2574 bitmap,
2575 imageOffset));
[email protected]48c9cf2d2009-09-16 16:47:522576}
2577
[email protected]28b92df2009-09-25 17:35:452578bool RenderView::acceptsLoadDrops() {
2579 return renderer_preferences_.can_accept_load_drops;
2580}
2581
[email protected]48c9cf2d2009-09-16 16:47:522582void RenderView::focusNext() {
2583 Send(new ViewHostMsg_TakeFocus(routing_id_, false));
2584}
2585
2586void RenderView::focusPrevious() {
2587 Send(new ViewHostMsg_TakeFocus(routing_id_, true));
2588}
2589
[email protected]08e9e132010-06-01 16:58:492590void RenderView::focusedNodeChanged(const WebNode& node) {
[email protected]9b66f34bf2010-10-27 20:45:512591 Send(new ViewHostMsg_FocusedNodeChanged(routing_id_, IsEditableNode(node)));
[email protected]a4b103b2010-10-05 18:46:072592
2593 if (WebAccessibilityCache::accessibilityEnabled() && node.isNull()) {
2594 // TODO(ctguil): Make WebKit send this notification.
2595 // When focus is cleared notify accessibility that the document is focused.
2596 postAccessibilityNotification(
2597 webview()->accessibilityObject(),
2598 WebKit::WebAccessibilityNotificationFocusedUIElementChanged);
2599 }
[email protected]13a1e4c3c2011-02-03 21:07:092600
2601 UpdateToggleSpellCheckCommandState();
[email protected]08e9e132010-06-01 16:58:492602}
2603
[email protected]48c9cf2d2009-09-16 16:47:522604void RenderView::navigateBackForwardSoon(int offset) {
[email protected]48c9cf2d2009-09-16 16:47:522605 Send(new ViewHostMsg_GoToEntryAtOffset(routing_id_, offset));
2606}
2607
2608int RenderView::historyBackListCount() {
[email protected]3cc72b12010-03-18 23:03:002609 return history_list_offset_ < 0 ? 0 : history_list_offset_;
[email protected]48c9cf2d2009-09-16 16:47:522610}
2611
2612int RenderView::historyForwardListCount() {
[email protected]3cc72b12010-03-18 23:03:002613 return history_list_length_ - historyBackListCount() - 1;
[email protected]48c9cf2d2009-09-16 16:47:522614}
2615
[email protected]c4e98902010-06-01 10:20:142616void RenderView::didUpdateInspectorSetting(const WebString& key,
2617 const WebString& value) {
2618 Send(new ViewHostMsg_UpdateInspectorSetting(routing_id_,
2619 key.utf8(),
2620 value.utf8()));
[email protected]8922e1f2009-10-03 05:01:262621}
2622
[email protected]79dbc662009-09-04 05:42:512623// WebKit::WebWidgetClient ----------------------------------------------------
2624
[email protected]ea42e7782010-08-23 23:58:122625void RenderView::didFocus() {
2626 // TODO(jcivelli): when https://bugs.webkit.org/show_bug.cgi?id=33389 is fixed
2627 // we won't have to test for user gesture anymore and we can
2628 // move that code back to render_widget.cc
2629 if (webview() && webview()->mainFrame() &&
2630 webview()->mainFrame()->isProcessingUserGesture()) {
2631 Send(new ViewHostMsg_Focus(routing_id_));
2632 }
2633}
2634
2635void RenderView::didBlur() {
2636 // TODO(jcivelli): see TODO above in didFocus().
2637 if (webview() && webview()->mainFrame() &&
2638 webview()->mainFrame()->isProcessingUserGesture()) {
2639 Send(new ViewHostMsg_Blur(routing_id_));
2640 }
2641}
2642
initial.commit09911bf2008-07-26 23:55:292643// We are supposed to get a single call to Show for a newly created RenderView
2644// that was created via RenderView::CreateWebView. So, we wait until this
2645// point to dispatch the ShowView message.
2646//
2647// This method provides us with the information about how to display the newly
2648// created RenderView (i.e., as a constrained popup or as a new tab).
2649//
[email protected]4873c7d2009-07-16 06:36:282650void RenderView::show(WebNavigationPolicy policy) {
initial.commit09911bf2008-07-26 23:55:292651 DCHECK(!did_show_) << "received extraneous Show call";
2652 DCHECK(opener_id_ != MSG_ROUTING_NONE);
2653
2654 if (did_show_)
2655 return;
2656 did_show_ = true;
2657
[email protected]4026ce1e2010-09-14 19:35:042658 // Extensions and apps always allowed to create unrequested popups. The second
2659 // check is necessary to include content scripts.
[email protected]2a521c52011-01-26 18:45:212660 if (render_thread_->GetExtensions()->GetByURL(creator_url_) ||
[email protected]4026ce1e2010-09-14 19:35:042661 bindings_utils::GetInfoForCurrentContext()) {
2662 opened_by_user_gesture_ = true;
2663 }
2664
[email protected]28295ec2009-10-16 05:34:332665 // Force new windows to a popup if they were not opened with a user gesture.
2666 if (!opened_by_user_gesture_) {
2667 // We exempt background tabs for compat with older versions of Chrome.
2668 // TODO(darin): This seems bogus. These should have a user gesture, so
2669 // we probably don't need this check.
2670 if (policy != WebKit::WebNavigationPolicyNewBackgroundTab)
2671 policy = WebKit::WebNavigationPolicyNewPopup;
2672 }
2673
initial.commit09911bf2008-07-26 23:55:292674 // NOTE: initial_pos_ may still have its default values at this point, but
2675 // that's okay. It'll be ignored if disposition is not NEW_POPUP, or the
2676 // browser process will impose a default position otherwise.
[email protected]4873c7d2009-07-16 06:36:282677 Send(new ViewHostMsg_ShowView(opener_id_, routing_id_,
2678 NavigationPolicyToDisposition(policy), initial_pos_,
[email protected]7e7414ae2010-01-26 20:19:292679 opened_by_user_gesture_));
[email protected]2533ce12009-05-09 00:02:242680 SetPendingWindowRect(initial_pos_);
initial.commit09911bf2008-07-26 23:55:292681}
2682
[email protected]4873c7d2009-07-16 06:36:282683void RenderView::runModal() {
initial.commit09911bf2008-07-26 23:55:292684 DCHECK(did_show_) << "should already have shown the view";
2685
[email protected]c1f50aa2010-02-18 03:46:572686 // We must keep WebKit's shared timer running in this case in order to allow
2687 // showModalDialog to function properly.
2688 //
2689 // TODO(darin): WebKit should really be smarter about suppressing events and
2690 // timers so that we do not need to manage the shared timer in such a heavy
2691 // handed manner.
2692 //
2693 if (RenderThread::current()) // Will be NULL during unit tests.
2694 RenderThread::current()->DoNotSuspendWebKitSharedTimer();
2695
[email protected]12636df2009-09-28 22:32:212696 SendAndRunNestedMessageLoop(new ViewHostMsg_RunModal(routing_id_));
initial.commit09911bf2008-07-26 23:55:292697}
2698
[email protected]3d9689372009-09-10 04:29:172699// WebKit::WebFrameClient -----------------------------------------------------
2700
[email protected]00152e92010-07-19 11:47:402701WebPlugin* RenderView::createPlugin(WebFrame* frame,
2702 const WebPluginParams& params) {
[email protected]6fdd4182010-10-14 23:59:262703 bool found = false;
[email protected]414508d2010-11-02 10:45:392704 ContentSetting plugin_setting = CONTENT_SETTING_DEFAULT;
[email protected]55126132010-08-19 14:53:282705 CommandLine* cmd = CommandLine::ForCurrentProcess();
[email protected]191eb3f72010-12-21 06:27:502706 webkit::npapi::WebPluginInfo info;
[email protected]7a13e792010-08-03 08:18:242707 GURL url(params.url);
[email protected]6fdd4182010-10-14 23:59:262708 std::string actual_mime_type;
[email protected]c8f73ab2011-01-22 00:05:172709 Send(new ViewHostMsg_GetPluginInfo(routing_id_,
2710 url,
[email protected]6fdd4182010-10-14 23:59:262711 frame->top()->url(),
2712 params.mimeType.utf8(),
2713 &found,
2714 &info,
[email protected]44fda5c2010-11-02 10:50:542715 &plugin_setting,
[email protected]6fdd4182010-10-14 23:59:262716 &actual_mime_type));
[email protected]7a13e792010-08-03 08:18:242717
[email protected]6fdd4182010-10-14 23:59:262718 if (!found)
[email protected]0cdafff2010-07-26 09:54:372719 return NULL;
[email protected]414508d2010-11-02 10:45:392720 DCHECK(plugin_setting != CONTENT_SETTING_DEFAULT);
[email protected]8d91f862011-02-24 13:38:102721 if (!webkit::npapi::IsPluginEnabled(info))
2722 return NULL;
[email protected]4e0616e2010-05-28 14:55:532723
[email protected]191eb3f72010-12-21 06:27:502724 const webkit::npapi::PluginGroup* group =
2725 webkit::npapi::PluginList::Singleton()->GetPluginGroup(info);
[email protected]79ce1032010-12-07 13:29:412726 DCHECK(group != NULL);
[email protected]851b1eb2010-08-09 13:32:292727
[email protected]6e74a3b2010-12-21 22:27:542728 if (group->IsVulnerable() &&
2729 !cmd->HasSwitch(switches::kAllowOutdatedPlugins)) {
[email protected]3c2826852010-12-16 19:09:142730 Send(new ViewHostMsg_BlockedOutdatedPlugin(routing_id_,
2731 group->GetGroupName(),
2732 GURL(group->GetUpdateURL())));
2733 return CreatePluginPlaceholder(frame,
2734 params,
2735 *group,
[email protected]2e34ab3f2010-12-17 05:47:372736 IDR_BLOCKED_PLUGIN_HTML,
[email protected]90dba072011-01-20 20:10:202737 IDS_PLUGIN_OUTDATED,
2738 false);
[email protected]851b1eb2010-08-09 13:32:292739 }
[email protected]6e74a3b2010-12-21 22:27:542740
[email protected]414508d2010-11-02 10:45:392741 ContentSetting host_setting =
2742 current_content_settings_.settings[CONTENT_SETTINGS_TYPE_PLUGINS];
[email protected]d12dcdd62011-01-27 06:53:252743
2744 if (group->RequiresAuthorization() &&
2745 !cmd->HasSwitch(switches::kAlwaysAuthorizePlugins) &&
2746 (plugin_setting == CONTENT_SETTING_ALLOW ||
2747 plugin_setting == CONTENT_SETTING_ASK) &&
2748 host_setting == CONTENT_SETTING_DEFAULT) {
2749 Send(new ViewHostMsg_BlockedOutdatedPlugin(routing_id_,
2750 group->GetGroupName(),
2751 GURL()));
2752 return CreatePluginPlaceholder(frame,
2753 params,
2754 *group,
2755 IDR_BLOCKED_PLUGIN_HTML,
2756 IDS_PLUGIN_NOT_AUTHORIZED,
2757 false);
2758 }
2759
[email protected]191eb3f72010-12-21 06:27:502760 if (info.path.value() == webkit::npapi::kDefaultPluginLibraryName ||
[email protected]414508d2010-11-02 10:45:392761 plugin_setting == CONTENT_SETTING_ALLOW ||
2762 host_setting == CONTENT_SETTING_ALLOW) {
[email protected]987d51af2011-02-24 17:50:182763 // Delay loading plugins if prerendering.
2764 if (is_prerendering_) {
[email protected]90dba072011-01-20 20:10:202765 return CreatePluginPlaceholder(frame,
2766 params,
2767 *group,
2768 IDR_CLICK_TO_PLAY_PLUGIN_HTML,
2769 IDS_PLUGIN_LOAD,
2770 true);
2771 }
2772
[email protected]0bd753682010-12-16 18:15:522773 scoped_refptr<webkit::ppapi::PluginModule> pepper_module(
[email protected]1a78d9f32010-12-08 06:38:452774 pepper_delegate_.CreatePepperPlugin(info.path));
2775 if (pepper_module)
2776 return CreatePepperPlugin(frame, params, info.path, pepper_module.get());
[email protected]6fdd4182010-10-14 23:59:262777 return CreateNPAPIPlugin(frame, params, info.path, actual_mime_type);
[email protected]0cdafff2010-07-26 09:54:372778 }
[email protected]fc61e222010-10-11 15:42:142779 std::string resource;
2780 if (cmd->HasSwitch(switches::kEnableResourceContentSettings))
2781 resource = group->identifier();
2782 DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, resource);
[email protected]414508d2010-11-02 10:45:392783 if (plugin_setting == CONTENT_SETTING_ASK) {
[email protected]3c2826852010-12-16 19:09:142784 return CreatePluginPlaceholder(frame,
2785 params,
2786 *group,
[email protected]2e34ab3f2010-12-17 05:47:372787 IDR_CLICK_TO_PLAY_PLUGIN_HTML,
[email protected]90dba072011-01-20 20:10:202788 IDS_PLUGIN_LOAD,
2789 false);
[email protected]fc61e222010-10-11 15:42:142790 } else {
[email protected]3c2826852010-12-16 19:09:142791 return CreatePluginPlaceholder(frame,
2792 params,
2793 *group,
[email protected]2e34ab3f2010-12-17 05:47:372794 IDR_BLOCKED_PLUGIN_HTML,
[email protected]90dba072011-01-20 20:10:202795 IDS_PLUGIN_BLOCKED,
2796 false);
[email protected]fc61e222010-10-11 15:42:142797 }
[email protected]3d9689372009-09-10 04:29:172798}
2799
2800WebWorker* RenderView::createWorker(WebFrame* frame, WebWorkerClient* client) {
[email protected]14396e92010-05-06 20:40:562801 WebApplicationCacheHostImpl* appcache_host =
2802 WebApplicationCacheHostImpl::FromFrame(frame);
2803 int appcache_host_id = appcache_host ? appcache_host->host_id() : 0;
2804 return new WebWorkerProxy(client, RenderThread::current(), routing_id_,
2805 appcache_host_id);
[email protected]3d9689372009-09-10 04:29:172806}
2807
[email protected]9c00f002009-11-05 22:37:422808WebSharedWorker* RenderView::createSharedWorker(
2809 WebFrame* frame, const WebURL& url, const WebString& name,
[email protected]30447b62009-11-13 01:13:372810 unsigned long long document_id) {
[email protected]9c00f002009-11-05 22:37:422811
[email protected]30447b62009-11-13 01:13:372812 int route_id = MSG_ROUTING_NONE;
[email protected]6de0bcf2010-02-17 22:00:512813 bool exists = false;
[email protected]30447b62009-11-13 01:13:372814 bool url_mismatch = false;
[email protected]6de0bcf2010-02-17 22:00:512815 ViewHostMsg_CreateWorker_Params params;
2816 params.url = url;
2817 params.is_shared = true;
2818 params.name = name;
2819 params.document_id = document_id;
2820 params.render_view_route_id = routing_id_;
2821 params.route_id = MSG_ROUTING_NONE;
[email protected]f9bc9c02010-05-24 19:19:232822 params.parent_appcache_host_id = 0;
2823 params.script_resource_appcache_id = 0;
[email protected]30447b62009-11-13 01:13:372824 Send(new ViewHostMsg_LookupSharedWorker(
[email protected]6de0bcf2010-02-17 22:00:512825 params, &exists, &route_id, &url_mismatch));
[email protected]30447b62009-11-13 01:13:372826 if (url_mismatch) {
2827 return NULL;
2828 } else {
2829 return new WebSharedWorkerProxy(RenderThread::current(),
[email protected]0791d3a2010-01-28 01:28:492830 document_id,
[email protected]6de0bcf2010-02-17 22:00:512831 exists,
[email protected]30447b62009-11-13 01:13:372832 route_id,
2833 routing_id_);
2834 }
[email protected]9c00f002009-11-05 22:37:422835}
2836
[email protected]3d9689372009-09-10 04:29:172837WebMediaPlayer* RenderView::createMediaPlayer(
2838 WebFrame* frame, WebMediaPlayerClient* client) {
[email protected]f78d1dfc2011-01-15 07:09:272839 scoped_ptr<media::MessageLoopFactory> message_loop_factory(
2840 new media::MessageLoopFactoryImpl());
[email protected]f8db8132010-12-03 00:27:492841 scoped_ptr<media::FilterCollection> collection(
2842 new media::FilterCollection());
[email protected]457d8342010-10-23 01:20:372843
[email protected]3d9689372009-09-10 04:29:172844 // Add in any custom filter factories first.
2845 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
2846 if (!cmd_line->HasSwitch(switches::kDisableAudio)) {
2847 // Add the chrome specific audio renderer.
[email protected]b7ba5b52010-11-15 22:04:492848 collection->AddAudioRenderer(new AudioRendererImpl(audio_message_filter()));
[email protected]3d9689372009-09-10 04:29:172849 }
2850
[email protected]3bb08602010-10-07 21:47:172851 if (cmd_line->HasSwitch(switches::kEnableAcceleratedDecoding) &&
[email protected]11c4c812010-10-22 19:50:122852 !cmd_line->HasSwitch(switches::kDisableAcceleratedCompositing)) {
[email protected]5aa6a312010-11-06 00:00:072853 WebGraphicsContext3DCommandBufferImpl* context =
2854 static_cast<WebGraphicsContext3DCommandBufferImpl*>(
2855 frame->view()->graphicsContext3D());
2856 if (!context)
2857 return NULL;
[email protected]a9a43012010-11-05 01:54:062858
[email protected]5aa6a312010-11-06 00:00:072859 // Add the hardware video decoder factory.
2860 // TODO(hclam): This will cause the renderer process to crash on context
2861 // lost.
2862 bool ret = context->makeContextCurrent();
2863 CHECK(ret) << "Failed to switch context";
[email protected]b7ba5b52010-11-15 22:04:492864 collection->AddVideoDecoder(new IpcVideoDecoder(
[email protected]5aa6a312010-11-06 00:00:072865 MessageLoop::current(), context->context()));
[email protected]3bb08602010-10-07 21:47:172866 }
2867
[email protected]457d8342010-10-23 01:20:372868 scoped_refptr<webkit_glue::WebVideoRenderer> video_renderer;
[email protected]77128dec2010-11-08 17:05:312869 bool pts_logging = cmd_line->HasSwitch(switches::kEnableVideoLogging);
2870 scoped_refptr<webkit_glue::VideoRendererImpl> renderer(
2871 new webkit_glue::VideoRendererImpl(pts_logging));
[email protected]b7ba5b52010-11-15 22:04:492872 collection->AddVideoRenderer(renderer);
[email protected]77128dec2010-11-08 17:05:312873 video_renderer = renderer;
[email protected]8400e032010-02-26 18:50:112874
[email protected]a8e24d522010-12-01 07:13:582875 scoped_ptr<webkit_glue::WebMediaPlayerImpl> result(
[email protected]f78d1dfc2011-01-15 07:09:272876 new webkit_glue::WebMediaPlayerImpl(client,
2877 collection.release(),
2878 message_loop_factory.release()));
[email protected]79684282010-12-06 21:15:462879 if (!result->Initialize(frame,
[email protected]a8e24d522010-12-01 07:13:582880 cmd_line->HasSwitch(switches::kSimpleDataSource),
2881 video_renderer)) {
2882 return NULL;
2883 }
2884 return result.release();
[email protected]3d9689372009-09-10 04:29:172885}
2886
[email protected]035545f2010-04-09 13:10:212887WebApplicationCacheHost* RenderView::createApplicationCacheHost(
2888 WebFrame* frame, WebApplicationCacheHostClient* client) {
2889 return new RendererWebApplicationCacheHostImpl(
2890 FromWebView(frame->view()), client,
2891 RenderThread::current()->appcache_dispatcher()->backend_proxy());
2892}
2893
[email protected]8ff181072010-11-29 17:09:382894WebCookieJar* RenderView::cookieJar(WebFrame* frame) {
2895 return &cookie_jar_;
2896}
2897
[email protected]5041f982010-08-11 21:40:452898void RenderView::frameDetached(WebFrame* frame) {
[email protected]676126f72011-01-15 00:03:512899 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame));
[email protected]5041f982010-08-11 21:40:452900}
2901
[email protected]3d9689372009-09-10 04:29:172902void RenderView::willClose(WebFrame* frame) {
[email protected]fa7b6b542009-11-03 05:02:302903 WebDataSource* ds = frame->dataSource();
2904 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
[email protected]05c8e502010-08-15 15:13:522905
[email protected]a5a65ac2010-11-05 18:14:362906 page_load_histograms_.Dump(frame);
[email protected]fa7b6b542009-11-03 05:02:302907 navigation_state->user_script_idle_scheduler()->Cancel();
[email protected]f3ce0a32011-01-11 08:18:182908
[email protected]676126f72011-01-15 00:03:512909 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame));
[email protected]3d9689372009-09-10 04:29:172910}
2911
[email protected]684e4a42010-01-30 06:44:112912bool RenderView::allowImages(WebFrame* frame, bool enabled_per_settings) {
[email protected]12bc8472010-04-15 07:29:402913 if (enabled_per_settings &&
2914 AllowContentType(CONTENT_SETTINGS_TYPE_IMAGES))
2915 return true;
2916
2917 if (IsWhitelistedForContentSettings(frame))
2918 return true;
2919
[email protected]55126132010-08-19 14:53:282920 DidBlockContentType(CONTENT_SETTINGS_TYPE_IMAGES, std::string());
[email protected]12bc8472010-04-15 07:29:402921 return false; // Other protocols fall through here.
[email protected]684e4a42010-01-30 06:44:112922}
2923
[email protected]d5f9e4f2010-07-28 08:31:302924bool RenderView::allowPlugins(WebFrame* frame, bool enabled_per_settings) {
[email protected]3627b06d2010-11-12 16:36:162925 return WebFrameClient::allowPlugins(frame, enabled_per_settings);
[email protected]d5f9e4f2010-07-28 08:31:302926}
2927
2928
[email protected]3d9689372009-09-10 04:29:172929void RenderView::loadURLExternally(
2930 WebFrame* frame, const WebURLRequest& request,
2931 WebNavigationPolicy policy) {
[email protected]efce17b2009-09-11 18:04:592932 GURL referrer(request.httpHeaderField(WebString::fromUTF8("Referer")));
2933 if (policy == WebKit::WebNavigationPolicyDownload) {
2934 Send(new ViewHostMsg_DownloadUrl(routing_id_, request.url(), referrer));
2935 } else {
2936 OpenURL(request.url(), referrer, policy);
2937 }
[email protected]3d9689372009-09-10 04:29:172938}
2939
2940WebNavigationPolicy RenderView::decidePolicyForNavigation(
2941 WebFrame* frame, const WebURLRequest& request, WebNavigationType type,
[email protected]65b95cd2009-10-09 05:10:222942 const WebNode&, WebNavigationPolicy default_policy, bool is_redirect) {
[email protected]3d9689372009-09-10 04:29:172943 // Webkit is asking whether to navigate to a new URL.
2944 // This is fine normally, except if we're showing UI from one security
2945 // context and they're trying to navigate to a different context.
2946 const GURL& url = request.url();
2947
2948 // If the browser is interested, then give it a chance to look at top level
[email protected]3a8eecb2010-04-22 23:56:302949 // navigations.
[email protected]8079b362010-05-07 18:37:452950 if (renderer_preferences_.browser_handles_top_level_requests &&
2951 IsNonLocalTopLevelNavigation(url, frame, type)) {
[email protected]61c9f032010-03-31 23:04:192952 GURL referrer(request.httpHeaderField(WebString::fromUTF8("Referer")));
[email protected]a58db8b2010-08-24 01:51:232953 // Reset these counters as the RenderView could be reused for the next
2954 // navigation.
2955 page_id_ = -1;
[email protected]a58db8b2010-08-24 01:51:232956 last_page_id_sent_to_browser_ = -1;
[email protected]61c9f032010-03-31 23:04:192957 OpenURL(url, referrer, default_policy);
2958 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
[email protected]3d9689372009-09-10 04:29:172959 }
2960
2961 // A content initiated navigation may have originated from a link-click,
2962 // script, drag-n-drop operation, etc.
2963 bool is_content_initiated =
2964 NavigationState::FromDataSource(frame->provisionalDataSource())->
2965 is_content_initiated();
[email protected]a6b960ad972010-09-01 19:53:582966 GURL old_url(frame->url());
[email protected]3d9689372009-09-10 04:29:172967
[email protected]6101c342010-12-16 22:44:372968 // Detect when we're crossing a permission-based boundary (e.g. into or out of
[email protected]c39f9bf2011-02-12 00:43:552969 // an extension or app origin, leaving a WebUI page, etc). We only care about
[email protected]8f4da8c2011-02-09 19:49:572970 // top-level navigations within the current tab (as opposed to, for example,
[email protected]6101c342010-12-16 22:44:372971 // opening a new window). But we sometimes navigate to about:blank to clear a
2972 // tab, and we want to still allow that.
2973 //
[email protected]8f4da8c2011-02-09 19:49:572974 // Note: we do this only for GET requests because our mechanism for switching
2975 // processes only issues GET requests. In particular, POST requests don't
2976 // work, because this mechanism does not preserve form POST data. If it
2977 // becomes necessary to support process switching for POST requests, we will
2978 // need to send the request's httpBody data up to the browser process, and
2979 // issue a special POST navigation in WebKit (via
2980 // FrameLoader::loadFrameRequest). See ResourceDispatcher and WebURLLoaderImpl
2981 // for examples of how to send the httpBody data.
2982 // Note2: We normally don't do this for browser-initiated navigations, since
2983 // it's pointless to tell the browser about navigations it gave us. But
2984 // we do potentially ask the browser to handle a redirect that was originally
2985 // initiated by the browser. See http://crbug.com/70943
2986 //
2987 // TODO(creis): Move this redirect check to the browser process to avoid
2988 // ping-ponging. See http://crbug.com/72380.
2989 if (!frame->parent() && (is_content_initiated || is_redirect) &&
[email protected]6101c342010-12-16 22:44:372990 default_policy == WebKit::WebNavigationPolicyCurrentTab &&
2991 request.httpMethod() == "GET" && !url.SchemeIs(chrome::kAboutScheme)) {
2992 bool send_referrer = false;
2993 bool should_fork =
[email protected]c09163a2011-02-15 00:05:552994 BindingsPolicy::is_web_ui_enabled(enabled_bindings_) ||
[email protected]3d9689372009-09-10 04:29:172995 frame->isViewSourceModeEnabled() ||
[email protected]6101c342010-12-16 22:44:372996 url.SchemeIs(chrome::kViewSourceScheme);
[email protected]5351dbc2010-08-27 15:22:112997
2998 // If the navigation would cross an app extent boundary, we also need
2999 // to defer to the browser to ensure process isolation.
3000 // TODO(erikkay) This is happening inside of a check to is_content_initiated
3001 // which means that things like the back button won't trigger it. Is that
3002 // OK?
[email protected]88c15e972011-02-05 04:19:533003 // TODO(creis): For hosted apps, we currently only swap processes to enter
3004 // the app and not exit it, since we currently lose context (e.g.,
3005 // window.opener) if the window navigates back. See crbug.com/65953.
[email protected]2a521c52011-01-26 18:45:213006 if (!should_fork &&
[email protected]88c15e972011-02-05 04:19:533007 CrossesExtensionExtents(
[email protected]2a521c52011-01-26 18:45:213008 render_thread_->GetExtensions(),
3009 frame,
3010 url)) {
[email protected]5351dbc2010-08-27 15:22:113011 // Include the referrer in this case since we're going from a hosted web
3012 // page. (the packaged case is handled previously by the extension
3013 // navigation test)
[email protected]6101c342010-12-16 22:44:373014 should_fork = true;
3015 send_referrer = true;
[email protected]46fd1ea42011-02-16 15:59:333016
3017 if (is_content_initiated) {
3018 const Extension* extension =
3019 render_thread_->GetExtensions()->GetByURL(url);
3020 if (extension && extension->is_app()) {
3021 UMA_HISTOGRAM_ENUMERATION(
3022 extension_misc::kAppLaunchHistogram,
3023 extension_misc::APP_LAUNCH_CONTENT_NAVIGATION,
3024 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
3025 }
3026 }
[email protected]6101c342010-12-16 22:44:373027 }
3028
3029 if (should_fork) {
[email protected]5351dbc2010-08-27 15:22:113030 GURL referrer(request.httpHeaderField(WebString::fromUTF8("Referer")));
[email protected]6101c342010-12-16 22:44:373031 OpenURL(url, send_referrer ? referrer : GURL(), default_policy);
[email protected]5351dbc2010-08-27 15:22:113032 return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
3033 }
[email protected]3d9689372009-09-10 04:29:173034 }
3035
3036 // Detect when a page is "forking" a new tab that can be safely rendered in
3037 // its own process. This is done by sites like Gmail that try to open links
3038 // in new windows without script connections back to the original page. We
3039 // treat such cases as browser navigations (in which we will create a new
3040 // renderer for a cross-site navigation), rather than WebKit navigations.
3041 //
3042 // We use the following heuristic to decide whether to fork a new page in its
3043 // own process:
3044 // The parent page must open a new tab to about:blank, set the new tab's
3045 // window.opener to null, and then redirect the tab to a cross-site URL using
3046 // JavaScript.
[email protected]007a848b2009-10-26 15:55:463047 //
3048 // TODO(creis): Deprecate this logic once we can rely on rel=noreferrer
3049 // (see below).
[email protected]3d9689372009-09-10 04:29:173050 bool is_fork =
3051 // Must start from a tab showing about:blank, which is later redirected.
[email protected]a6b960ad972010-09-01 19:53:583052 old_url == GURL(chrome::kAboutBlankURL) &&
[email protected]3d9689372009-09-10 04:29:173053 // Must be the first real navigation of the tab.
[email protected]48c9cf2d2009-09-16 16:47:523054 historyBackListCount() < 1 &&
3055 historyForwardListCount() < 1 &&
[email protected]3d9689372009-09-10 04:29:173056 // The parent page must have set the child's window.opener to null before
3057 // redirecting to the desired URL.
3058 frame->opener() == NULL &&
3059 // Must be a top-level frame.
3060 frame->parent() == NULL &&
3061 // Must not have issued the request from this page.
3062 is_content_initiated &&
3063 // Must be targeted at the current tab.
3064 default_policy == WebKit::WebNavigationPolicyCurrentTab &&
3065 // Must be a JavaScript navigation, which appears as "other".
3066 type == WebKit::WebNavigationTypeOther;
[email protected]007a848b2009-10-26 15:55:463067
3068 // Recognize if this navigation is from a link with rel=noreferrer and
3069 // target=_blank attributes, in which case the opener will be suppressed. If
3070 // so, it is safe to load cross-site pages in a separate process, so we
3071 // should let the browser handle it.
3072 bool is_noreferrer_and_blank_target =
3073 // Frame should be top level and not yet navigated.
3074 frame->parent() == NULL &&
3075 frame->url().isEmpty() &&
3076 historyBackListCount() < 1 &&
3077 historyForwardListCount() < 1 &&
3078 // Links with rel=noreferrer will have no Referer field, and their
3079 // resulting frame will have its window.opener suppressed.
3080 // TODO(creis): should add a request.httpReferrer() method to help avoid
3081 // typos on the unusual spelling of Referer.
3082 request.httpHeaderField(WebString::fromUTF8("Referer")).isNull() &&
3083 opener_suppressed_ &&
3084 frame->opener() == NULL &&
3085 // Links with target=_blank will have no name.
3086 frame->name().isNull() &&
3087 // Another frame (with a non-empty creator) should have initiated the
3088 // request, targeted at this frame.
3089 !creator_url_.is_empty() &&
3090 is_content_initiated &&
3091 default_policy == WebKit::WebNavigationPolicyCurrentTab &&
3092 type == WebKit::WebNavigationTypeOther;
3093
3094 if (is_fork || is_noreferrer_and_blank_target) {
[email protected]3d9689372009-09-10 04:29:173095 // Open the URL via the browser, not via WebKit.
3096 OpenURL(url, GURL(), default_policy);
3097 return WebKit::WebNavigationPolicyIgnore;
3098 }
3099
3100 return default_policy;
3101}
3102
[email protected]6069da8c2009-10-20 20:33:493103bool RenderView::canHandleRequest(
3104 WebFrame* frame, const WebURLRequest& request) {
3105 // We allow WebKit to think that everything can be handled even though
3106 // browser-side we limit what we load.
[email protected]7b7a7dc2009-10-19 02:23:343107 return true;
3108}
3109
[email protected]6069da8c2009-10-20 20:33:493110WebURLError RenderView::cannotHandleRequestError(
3111 WebFrame* frame, const WebURLRequest& request) {
3112 NOTREACHED(); // Since we said we can handle all requests.
3113 return WebURLError();
3114}
3115
3116WebURLError RenderView::cancelledError(
3117 WebFrame* frame, const WebURLRequest& request) {
3118 WebURLError error;
3119 error.domain = WebString::fromUTF8(net::kErrorDomain);
3120 error.reason = net::ERR_ABORTED;
3121 error.unreachableURL = request.url();
3122 return error;
[email protected]7b7a7dc2009-10-19 02:23:343123}
3124
3125void RenderView::unableToImplementPolicyWithError(
[email protected]6069da8c2009-10-20 20:33:493126 WebFrame*, const WebURLError&) {
3127 NOTREACHED(); // Since we said we can handle all requests.
[email protected]7b7a7dc2009-10-19 02:23:343128}
3129
[email protected]90eeddb2010-05-06 21:06:433130void RenderView::willSendSubmitEvent(WebKit::WebFrame* frame,
3131 const WebKit::WebFormElement& form) {
3132 // Some login forms have onSubmit handlers that put a hash of the password
3133 // into a hidden field and then clear the password. (Issue 28910.)
3134 // This method gets called before any of those handlers run, so save away
3135 // a copy of the password in case it gets lost.
3136 NavigationState* navigation_state =
3137 NavigationState::FromDataSource(frame->dataSource());
3138 navigation_state->set_password_form_data(
3139 PasswordFormDomManager::CreatePasswordForm(form));
3140}
3141
[email protected]979c28b2009-11-07 01:30:483142void RenderView::willSubmitForm(WebFrame* frame, const WebFormElement& form) {
[email protected]3d9689372009-09-10 04:29:173143 NavigationState* navigation_state =
3144 NavigationState::FromDataSource(frame->provisionalDataSource());
3145
3146 if (navigation_state->transition_type() == PageTransition::LINK)
3147 navigation_state->set_transition_type(PageTransition::FORM_SUBMIT);
3148
3149 // Save these to be processed when the ensuing navigation is committed.
[email protected]ce0e250d2009-10-23 21:00:353150 WebSearchableFormData web_searchable_form_data(form);
3151 navigation_state->set_searchable_form_url(web_searchable_form_data.url());
3152 navigation_state->set_searchable_form_encoding(
[email protected]b7910b3a2010-01-13 18:33:213153 web_searchable_form_data.encoding().utf8());
[email protected]90eeddb2010-05-06 21:06:433154 PasswordForm* password_form_data =
3155 PasswordFormDomManager::CreatePasswordForm(form);
3156 navigation_state->set_password_form_data(password_form_data);
3157
3158 // If the password has been cleared, recover it from the form contents already
3159 // stored by willSendSubmitEvent into the dataSource's NavigationState (as
3160 // opposed to the provisionalDataSource's, which is what we're storing into
3161 // now.)
3162 if (password_form_data && password_form_data->password_value.empty()) {
3163 NavigationState* old_navigation_state =
3164 NavigationState::FromDataSource(frame->dataSource());
3165 if (old_navigation_state) {
3166 PasswordForm* old_form_data = old_navigation_state->password_form_data();
3167 if (old_form_data && old_form_data->action == password_form_data->action)
3168 password_form_data->password_value = old_form_data->password_value;
3169 }
3170 }
[email protected]3d9689372009-09-10 04:29:173171
[email protected]b1438212010-04-03 00:30:593172 FormData form_data;
[email protected]b715f7f2010-04-05 22:01:043173 if (FormManager::WebFormElementToFormData(
[email protected]5af80432010-11-01 01:25:223174 form,
3175 FormManager::REQUIRE_AUTOCOMPLETE,
[email protected]78192082011-01-29 05:43:443176 static_cast<FormManager::ExtractMask>(
3177 FormManager::EXTRACT_VALUE | FormManager::EXTRACT_OPTION_TEXT),
[email protected]5af80432010-11-01 01:25:223178 &form_data)) {
[email protected]19d6e1e82011-01-26 05:08:583179 Send(new AutoFillHostMsg_FormSubmitted(routing_id_, form_data));
[email protected]5af80432010-11-01 01:25:223180 }
[email protected]3d9689372009-09-10 04:29:173181}
3182
3183void RenderView::willPerformClientRedirect(
3184 WebFrame* frame, const WebURL& from, const WebURL& to, double interval,
3185 double fire_time) {
3186 // Ignore
3187}
3188
3189void RenderView::didCancelClientRedirect(WebFrame* frame) {
3190 // Ignore
3191}
3192
3193void RenderView::didCompleteClientRedirect(
3194 WebFrame* frame, const WebURL& from) {
3195 if (!frame->parent())
3196 completed_client_redirect_src_ = from;
3197}
3198
3199void RenderView::didCreateDataSource(WebFrame* frame, WebDataSource* ds) {
[email protected]bb461532010-11-26 21:50:233200 // If there are any app-related fetches in progress, they can be cancelled now
3201 // since we have navigated away from the page that created them.
3202 if (!frame->parent()) {
3203 app_icon_fetchers_.clear();
3204 app_definition_fetcher_.reset(NULL);
3205 }
3206
[email protected]3d9689372009-09-10 04:29:173207 // The rest of RenderView assumes that a WebDataSource will always have a
3208 // non-null NavigationState.
[email protected]a7ccc4d2010-01-27 08:14:483209 bool content_initiated = !pending_navigation_state_.get();
3210 NavigationState* state = content_initiated ?
3211 NavigationState::CreateContentInitiated() :
3212 pending_navigation_state_.release();
[email protected]8a3125a712010-08-09 18:58:513213
[email protected]8a3125a712010-08-09 18:58:513214 // NavigationState::referred_by_prefetcher_ is true if we are
3215 // navigating from a page that used prefetching using a link on that
3216 // page. We are early enough in the request process here that we
3217 // can still see the NavigationState of the previous page and set
3218 // this value appropriately.
3219 // TODO(gavinp): catch the important case of navigation in a new
3220 // renderer process.
3221 if (webview()) {
[email protected]e47aec52010-08-12 00:50:303222 if (WebFrame* old_frame = webview()->mainFrame()) {
[email protected]05c8e502010-08-15 15:13:523223 const WebURLRequest& original_request = ds->originalRequest();
[email protected]8a3125a712010-08-09 18:58:513224 const GURL referrer(
3225 original_request.httpHeaderField(WebString::fromUTF8("Referer")));
3226 if (!referrer.is_empty() &&
3227 NavigationState::FromDataSource(
3228 old_frame->dataSource())->was_prefetcher()) {
3229 for (;old_frame;old_frame = old_frame->traverseNext(false)) {
3230 WebDataSource* old_frame_ds = old_frame->dataSource();
3231 if (old_frame_ds && referrer == GURL(old_frame_ds->request().url())) {
3232 state->set_was_referred_by_prefetcher(true);
3233 break;
3234 }
3235 }
3236 }
3237 }
3238 }
3239
[email protected]4c1b6f0b2010-02-07 16:38:183240 if (content_initiated) {
[email protected]05c8e502010-08-15 15:13:523241 const WebURLRequest& request = ds->request();
[email protected]8a3125a712010-08-09 18:58:513242 switch (request.cachePolicy()) {
[email protected]4c1b6f0b2010-02-07 16:38:183243 case WebURLRequest::UseProtocolCachePolicy: // normal load.
3244 state->set_load_type(NavigationState::LINK_LOAD_NORMAL);
3245 break;
3246 case WebURLRequest::ReloadIgnoringCacheData: // reload.
3247 state->set_load_type(NavigationState::LINK_LOAD_RELOAD);
3248 break;
3249 case WebURLRequest::ReturnCacheDataElseLoad: // allow stale data.
3250 state->set_load_type(NavigationState::LINK_LOAD_CACHE_STALE_OK);
3251 break;
3252 case WebURLRequest::ReturnCacheDataDontLoad: // Don't re-post.
3253 state->set_load_type(NavigationState::LINK_LOAD_CACHE_ONLY);
3254 break;
3255 }
3256 }
[email protected]fa7b6b542009-11-03 05:02:303257
[email protected]5792d932011-01-18 20:33:293258 // If this datasource already has a UserScriptIdleScheduler, reuse that one.
3259 // This is for navigations within a page (didNavigateWithinPage). See
3260 // http://code.google.com/p/chromium/issues/detail?id=64093
3261 NavigationState* old_state = NavigationState::FromDataSource(ds);
3262 if (old_state && old_state->user_script_idle_scheduler()) {
3263 state->swap_user_script_idle_scheduler(old_state);
3264 } else {
3265 state->set_user_script_idle_scheduler(
3266 new UserScriptIdleScheduler(this, frame));
3267 }
[email protected]375e8bd2011-02-07 19:15:353268
[email protected]987d51af2011-02-24 17:50:183269 state->set_was_started_as_prerender(is_prerendering_);
[email protected]375e8bd2011-02-07 19:15:353270
[email protected]fa7b6b542009-11-03 05:02:303271 ds->setExtraData(state);
[email protected]3d9689372009-09-10 04:29:173272}
3273
3274void RenderView::didStartProvisionalLoad(WebFrame* frame) {
3275 WebDataSource* ds = frame->provisionalDataSource();
3276 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
3277
[email protected]3d9689372009-09-10 04:29:173278 // Update the request time if WebKit has better knowledge of it.
3279 if (navigation_state->request_time().is_null()) {
3280 double event_time = ds->triggeringEventTime();
3281 if (event_time != 0.0)
3282 navigation_state->set_request_time(Time::FromDoubleT(event_time));
3283 }
3284
[email protected]05c8e502010-08-15 15:13:523285 // Start time is only set after request time.
3286 navigation_state->set_start_load_time(Time::Now());
3287
[email protected]3d9689372009-09-10 04:29:173288 bool is_top_most = !frame->parent();
3289 if (is_top_most) {
3290 navigation_gesture_ = frame->isProcessingUserGesture() ?
[email protected]cd448092010-12-06 23:49:133291 NavigationGestureUser : NavigationGestureAuto;
[email protected]3d9689372009-09-10 04:29:173292
3293 // Make sure redirect tracking state is clear for the new load.
3294 completed_client_redirect_src_ = GURL();
3295 } else if (frame->parent()->isLoading()) {
3296 // Take note of AUTO_SUBFRAME loads here, so that we can know how to
[email protected]4fb66842009-12-04 21:41:003297 // load an error page. See didFailProvisionalLoad.
[email protected]3d9689372009-09-10 04:29:173298 navigation_state->set_transition_type(PageTransition::AUTO_SUBFRAME);
3299 }
3300
[email protected]28685da92011-02-07 21:49:173301 FOR_EACH_OBSERVER(
3302 RenderViewObserver, observers_, DidStartProvisionalLoad(frame));
3303
[email protected]3d9689372009-09-10 04:29:173304 Send(new ViewHostMsg_DidStartProvisionalLoadForFrame(
[email protected]dabb0d12010-10-05 12:50:073305 routing_id_, frame->identifier(), is_top_most, ds->request().url()));
[email protected]3d9689372009-09-10 04:29:173306}
3307
3308void RenderView::didReceiveServerRedirectForProvisionalLoad(WebFrame* frame) {
3309 if (frame->parent())
3310 return;
3311 // Received a redirect on the main frame.
3312 WebDataSource* data_source = frame->provisionalDataSource();
3313 if (!data_source) {
3314 // Should only be invoked when we have a data source.
3315 NOTREACHED();
3316 return;
3317 }
3318 std::vector<GURL> redirects;
3319 GetRedirectChain(data_source, &redirects);
3320 if (redirects.size() >= 2) {
[email protected]40bd6582009-12-04 23:49:513321 Send(new ViewHostMsg_DidRedirectProvisionalLoad(routing_id_, page_id_,
3322 redirects[redirects.size() - 2], redirects.back()));
[email protected]3d9689372009-09-10 04:29:173323 }
3324}
3325
[email protected]40bd6582009-12-04 23:49:513326void RenderView::didFailProvisionalLoad(WebFrame* frame,
3327 const WebURLError& error) {
[email protected]3d9689372009-09-10 04:29:173328 // Notify the browser that we failed a provisional load with an error.
3329 //
3330 // Note: It is important this notification occur before DidStopLoading so the
3331 // SSL manager can react to the provisional load failure before being
3332 // notified the load stopped.
3333 //
3334 WebDataSource* ds = frame->provisionalDataSource();
3335 DCHECK(ds);
3336
3337 const WebURLRequest& failed_request = ds->request();
3338
[email protected]28685da92011-02-07 21:49:173339 FOR_EACH_OBSERVER(
3340 RenderViewObserver, observers_, DidFailProvisionalLoad(frame, error));
3341
[email protected]3d9689372009-09-10 04:29:173342 bool show_repost_interstitial =
3343 (error.reason == net::ERR_CACHE_MISS &&
3344 EqualsASCII(failed_request.httpMethod(), "POST"));
3345 Send(new ViewHostMsg_DidFailProvisionalLoadWithError(
[email protected]dabb0d12010-10-05 12:50:073346 routing_id_, frame->identifier(), !frame->parent(), error.reason,
3347 error.unreachableURL, show_repost_interstitial));
[email protected]3d9689372009-09-10 04:29:173348
3349 // Don't display an error page if this is simply a cancelled load. Aside
3350 // from being dumb, WebCore doesn't expect it and it will cause a crash.
3351 if (error.reason == net::ERR_ABORTED)
3352 return;
3353
3354 // Make sure we never show errors in view source mode.
3355 frame->enableViewSourceMode(false);
3356
3357 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
3358
3359 // If this is a failed back/forward/reload navigation, then we need to do a
3360 // 'replace' load. This is necessary to avoid messing up session history.
3361 // Otherwise, we do a normal load, which simulates a 'go' navigation as far
3362 // as session history is concerned.
3363 //
3364 // AUTO_SUBFRAME loads should always be treated as loads that do not advance
3365 // the page id.
3366 //
3367 bool replace =
3368 navigation_state->pending_page_id() != -1 ||
3369 navigation_state->transition_type() == PageTransition::AUTO_SUBFRAME;
3370
3371 // If we failed on a browser initiated request, then make sure that our error
3372 // page load is regarded as the same browser initiated request.
3373 if (!navigation_state->is_content_initiated()) {
3374 pending_navigation_state_.reset(NavigationState::CreateBrowserInitiated(
3375 navigation_state->pending_page_id(),
[email protected]3cc72b12010-03-18 23:03:003376 navigation_state->pending_history_list_offset(),
[email protected]3d9689372009-09-10 04:29:173377 navigation_state->transition_type(),
3378 navigation_state->request_time()));
3379 }
3380
3381 // Provide the user with a more helpful error page?
3382 if (MaybeLoadAlternateErrorPage(frame, error, replace))
3383 return;
3384
3385 // Fallback to a local error page.
[email protected]3f853a52010-09-13 19:15:083386 LoadNavigationErrorPage(frame, failed_request, error, std::string(), replace);
[email protected]3d9689372009-09-10 04:29:173387}
3388
3389void RenderView::didReceiveDocumentData(
3390 WebFrame* frame, const char* data, size_t data_len,
3391 bool& prevent_default) {
3392 NavigationState* navigation_state =
3393 NavigationState::FromDataSource(frame->dataSource());
[email protected]06333afe2011-02-24 14:55:093394 navigation_state->set_use_error_page(false);
[email protected]3d9689372009-09-10 04:29:173395}
3396
[email protected]40bd6582009-12-04 23:49:513397void RenderView::didCommitProvisionalLoad(WebFrame* frame,
3398 bool is_new_navigation) {
[email protected]3d9689372009-09-10 04:29:173399 NavigationState* navigation_state =
3400 NavigationState::FromDataSource(frame->dataSource());
3401
3402 navigation_state->set_commit_load_time(Time::Now());
3403 if (is_new_navigation) {
[email protected]e15f680732010-11-23 22:30:203404 // When we perform a new navigation, we need to update the last committed
3405 // session history entry with state for the page we are leaving.
[email protected]3d9689372009-09-10 04:29:173406 UpdateSessionHistory(frame);
3407
3408 // We bump our Page ID to correspond with the new session history entry.
3409 page_id_ = next_page_id_++;
3410
[email protected]3cc72b12010-03-18 23:03:003411 // Advance our offset in session history, applying the length limit. There
3412 // is now no forward history.
3413 history_list_offset_++;
3414 if (history_list_offset_ >= chrome::kMaxSessionHistoryEntries)
3415 history_list_offset_ = chrome::kMaxSessionHistoryEntries - 1;
3416 history_list_length_ = history_list_offset_ + 1;
3417
[email protected]f9f4841b2010-03-20 05:41:423418 MessageLoop::current()->PostDelayedTask(
3419 FROM_HERE,
[email protected]e47aec52010-08-12 00:50:303420 page_info_method_factory_.NewRunnableMethod(
3421 &RenderView::CapturePageInfo, page_id_, true),
[email protected]3d9689372009-09-10 04:29:173422 kDelayForForcedCaptureMs);
3423 } else {
3424 // Inspect the navigation_state on this frame to see if the navigation
3425 // corresponds to a session history navigation... Note: |frame| may or
3426 // may not be the toplevel frame, but for the case of capturing session
3427 // history, the first committed frame suffices. We keep track of whether
3428 // we've seen this commit before so that only capture session history once
3429 // per navigation.
3430 //
3431 // Note that we need to check if the page ID changed. In the case of a
3432 // reload, the page ID doesn't change, and UpdateSessionHistory gets the
3433 // previous URL and the current page ID, which would be wrong.
3434 if (navigation_state->pending_page_id() != -1 &&
3435 navigation_state->pending_page_id() != page_id_ &&
3436 !navigation_state->request_committed()) {
3437 // This is a successful session history navigation!
3438 UpdateSessionHistory(frame);
3439 page_id_ = navigation_state->pending_page_id();
[email protected]3cc72b12010-03-18 23:03:003440
3441 history_list_offset_ = navigation_state->pending_history_list_offset();
[email protected]3d9689372009-09-10 04:29:173442 }
3443 }
3444
[email protected]28685da92011-02-07 21:49:173445 FOR_EACH_OBSERVER(RenderViewObserver, observers_,
3446 DidCommitProvisionalLoad(frame, is_new_navigation));
3447
[email protected]3d9689372009-09-10 04:29:173448 // Remember that we've already processed this request, so we don't update
3449 // the session history again. We do this regardless of whether this is
3450 // a session history navigation, because if we attempted a session history
3451 // navigation without valid HistoryItem state, WebCore will think it is a
3452 // new navigation.
3453 navigation_state->set_request_committed(true);
3454
3455 UpdateURL(frame);
3456
3457 // If this committed load was initiated by a client redirect, we're
3458 // at the last stop now, so clear it.
3459 completed_client_redirect_src_ = GURL();
3460
3461 // Check whether we have new encoding name.
[email protected]26aa0482009-09-30 16:55:273462 UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
[email protected]3d9689372009-09-10 04:29:173463}
3464
3465void RenderView::didClearWindowObject(WebFrame* frame) {
3466 if (BindingsPolicy::is_dom_automation_enabled(enabled_bindings_))
3467 BindDOMAutomationController(frame);
[email protected]0d7ae862010-10-01 13:52:453468 GURL frame_url = frame->url();
[email protected]c09163a2011-02-15 00:05:553469 if (BindingsPolicy::is_web_ui_enabled(enabled_bindings_) &&
[email protected]bfa83eb82010-10-06 08:41:253470 (frame_url.SchemeIs(chrome::kChromeUIScheme) ||
[email protected]731ae512010-10-15 18:20:173471 frame_url.SchemeIs(chrome::kGearsScheme) ||
[email protected]bfa83eb82010-10-06 08:41:253472 frame_url.SchemeIs(chrome::kDataScheme))) {
[email protected]c50008512011-02-03 01:17:273473 GetWebUIBindings()->set_message_sender(this);
3474 GetWebUIBindings()->set_routing_id(routing_id_);
3475 GetWebUIBindings()->BindToJavascript(frame, "chrome");
[email protected]3d9689372009-09-10 04:29:173476 }
3477 if (BindingsPolicy::is_external_host_enabled(enabled_bindings_)) {
[email protected]c091c2c2010-09-17 19:05:463478 GetExternalHostBindings()->set_message_sender(this);
3479 GetExternalHostBindings()->set_routing_id(routing_id_);
[email protected]906690b2010-12-03 18:11:253480 GetExternalHostBindings()->BindToJavascript(frame, "externalHost");
[email protected]3d9689372009-09-10 04:29:173481 }
3482}
3483
3484void RenderView::didCreateDocumentElement(WebFrame* frame) {
3485 if (RenderThread::current()) { // Will be NULL during unit tests.
3486 RenderThread::current()->user_script_slave()->InjectScripts(
3487 frame, UserScript::DOCUMENT_START);
3488 }
3489
3490 // Notify the browser about non-blank documents loading in the top frame.
3491 GURL url = frame->url();
[email protected]e0d481582009-09-15 21:06:253492 if (url.is_valid() && url.spec() != chrome::kAboutBlankURL) {
[email protected]26aa0482009-09-30 16:55:273493 if (frame == webview()->mainFrame())
[email protected]3d9689372009-09-10 04:29:173494 Send(new ViewHostMsg_DocumentAvailableInMainFrame(routing_id_));
3495 }
3496}
3497
3498void RenderView::didReceiveTitle(WebFrame* frame, const WebString& title) {
3499 UpdateTitle(frame, title);
3500
3501 // Also check whether we have new encoding name.
[email protected]26aa0482009-09-30 16:55:273502 UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
[email protected]3d9689372009-09-10 04:29:173503}
3504
[email protected]5019ef12010-04-27 17:26:583505void RenderView::didChangeIcons(WebFrame* frame) {
3506 if (!frame->parent()) {
3507 Send(new ViewHostMsg_UpdateFavIconURL(
3508 routing_id_,
3509 page_id_,
3510 frame->favIconURL()));
3511 }
3512}
3513
[email protected]3d9689372009-09-10 04:29:173514void RenderView::didFinishDocumentLoad(WebFrame* frame) {
3515 WebDataSource* ds = frame->dataSource();
3516 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
3517 DCHECK(navigation_state);
3518 navigation_state->set_finish_document_load_time(Time::Now());
3519
[email protected]622474d2010-11-04 09:21:083520 Send(new ViewHostMsg_DocumentLoadedInFrame(routing_id_, frame->identifier()));
[email protected]3d9689372009-09-10 04:29:173521
[email protected]28685da92011-02-07 21:49:173522 FOR_EACH_OBSERVER(RenderViewObserver, observers_,
3523 DidFinishDocumentLoad(frame));
[email protected]3d9689372009-09-10 04:29:173524
3525 // Check whether we have new encoding name.
[email protected]26aa0482009-09-30 16:55:273526 UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
[email protected]3d9689372009-09-10 04:29:173527
3528 if (RenderThread::current()) { // Will be NULL during unit tests.
3529 RenderThread::current()->user_script_slave()->InjectScripts(
3530 frame, UserScript::DOCUMENT_END);
3531 }
[email protected]fa7b6b542009-11-03 05:02:303532
[email protected]41f16632010-10-20 01:21:323533 // InjectScripts() can end up creating a new NavigationState if it triggers a
3534 // fragment navigation, so we need to re-fetch it here.
3535 navigation_state = NavigationState::FromDataSource(ds);
[email protected]fa7b6b542009-11-03 05:02:303536 navigation_state->user_script_idle_scheduler()->DidFinishDocumentLoad();
3537}
3538
3539void RenderView::OnUserScriptIdleTriggered(WebFrame* frame) {
3540 if (RenderThread::current()) { // Will be NULL during unit tests.
3541 RenderThread::current()->user_script_slave()->InjectScripts(
3542 frame, UserScript::DOCUMENT_IDLE);
3543 }
3544
3545 WebFrame* main_frame = webview()->mainFrame();
3546 if (frame == main_frame) {
3547 while (!pending_code_execution_queue_.empty()) {
[email protected]61f5a7b2009-12-22 22:21:203548 linked_ptr<ViewMsg_ExecuteCode_Params>& params =
[email protected]fa7b6b542009-11-03 05:02:303549 pending_code_execution_queue_.front();
[email protected]61f5a7b2009-12-22 22:21:203550 ExecuteCodeImpl(main_frame, *params);
[email protected]fa7b6b542009-11-03 05:02:303551 pending_code_execution_queue_.pop();
3552 }
3553 }
[email protected]3d9689372009-09-10 04:29:173554}
3555
3556void RenderView::didHandleOnloadEvents(WebFrame* frame) {
[email protected]25497492010-09-11 15:15:083557 if (webview()->mainFrame() == frame) {
3558 Send(new ViewHostMsg_DocumentOnLoadCompletedInMainFrame(routing_id_,
3559 page_id_));
3560 }
[email protected]3d9689372009-09-10 04:29:173561}
3562
3563void RenderView::didFailLoad(WebFrame* frame, const WebURLError& error) {
[email protected]28685da92011-02-07 21:49:173564 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidFailLoad(frame, error));
[email protected]3d9689372009-09-10 04:29:173565}
3566
3567void RenderView::didFinishLoad(WebFrame* frame) {
3568 WebDataSource* ds = frame->dataSource();
3569 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
3570 DCHECK(navigation_state);
3571 navigation_state->set_finish_load_time(Time::Now());
[email protected]fa7b6b542009-11-03 05:02:303572 navigation_state->user_script_idle_scheduler()->DidFinishLoad();
[email protected]4d44a1c2010-04-28 19:20:413573
[email protected]676126f72011-01-15 00:03:513574 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidFinishLoad(frame));
[email protected]fdd94a02010-11-05 08:07:173575
3576 Send(new ViewHostMsg_DidFinishLoad(routing_id_, frame->identifier()));
[email protected]3d9689372009-09-10 04:29:173577}
3578
[email protected]ccbe04e2010-03-17 17:58:433579void RenderView::didNavigateWithinPage(
[email protected]3d9689372009-09-10 04:29:173580 WebFrame* frame, bool is_new_navigation) {
3581 // If this was a reference fragment navigation that we initiated, then we
3582 // could end up having a non-null pending navigation state. We just need to
3583 // update the ExtraData on the datasource so that others who read the
3584 // ExtraData will get the new NavigationState. Similarly, if we did not
3585 // initiate this navigation, then we need to take care to reset any pre-
3586 // existing navigation state to a content-initiated navigation state.
3587 // DidCreateDataSource conveniently takes care of this for us.
3588 didCreateDataSource(frame, frame->dataSource());
3589
[email protected]af15bed2010-08-25 21:12:093590 NavigationState* new_state =
3591 NavigationState::FromDataSource(frame->dataSource());
3592 new_state->set_was_within_same_page(true);
3593
[email protected]3d9689372009-09-10 04:29:173594 didCommitProvisionalLoad(frame, is_new_navigation);
3595
[email protected]26aa0482009-09-30 16:55:273596 UpdateTitle(frame, frame->view()->mainFrame()->dataSource()->pageTitle());
[email protected]3d9689372009-09-10 04:29:173597}
3598
[email protected]476b6f82009-09-10 21:00:593599void RenderView::didUpdateCurrentHistoryItem(WebFrame* frame) {
[email protected]882daa92009-11-05 16:31:313600 StartNavStateSyncTimerIfNecessary();
[email protected]476b6f82009-09-10 21:00:593601}
3602
[email protected]3d9689372009-09-10 04:29:173603void RenderView::assignIdentifierToRequest(
3604 WebFrame* frame, unsigned identifier, const WebURLRequest& request) {
3605 // Ignore
3606}
3607
3608void RenderView::willSendRequest(
3609 WebFrame* frame, unsigned identifier, WebURLRequest& request,
3610 const WebURLResponse& redirect_response) {
[email protected]5e369672009-11-03 23:48:303611 WebFrame* top_frame = frame->top();
3612 if (!top_frame)
3613 top_frame = frame;
[email protected]8a3125a712010-08-09 18:58:513614 WebDataSource* provisional_data_source = top_frame->provisionalDataSource();
3615 WebDataSource* top_data_source = top_frame->dataSource();
3616 WebDataSource* data_source =
3617 provisional_data_source ? provisional_data_source : top_data_source;
[email protected]78d5cfe2011-02-04 08:43:223618
3619 // If the request is for an extension resource, check whether it should be
3620 // allowed. If not allowed, we reset the URL to something invalid to prevent
3621 // the request and cause an error.
3622 GURL request_url(request.url());
3623 if (request_url.SchemeIs(chrome::kExtensionScheme) &&
3624 !ExtensionResourceRequestPolicy::CanRequestResource(
3625 request_url,
3626 GURL(frame->url()),
3627 render_thread_->GetExtensions())) {
3628 request.setURL(WebURL(GURL("chrome-extension://invalid/")));
3629 }
3630
[email protected]5e369672009-11-03 23:48:303631 if (data_source) {
3632 NavigationState* state = NavigationState::FromDataSource(data_source);
3633 if (state && state->is_cache_policy_override_set())
3634 request.setCachePolicy(state->cache_policy_override());
3635 }
[email protected]8a3125a712010-08-09 18:58:513636
3637 if (top_data_source) {
3638 NavigationState* state = NavigationState::FromDataSource(top_data_source);
3639 if (state && request.targetType() == WebURLRequest::TargetIsPrefetch)
3640 state->set_was_prefetcher(true);
3641 }
3642
[email protected]3d9689372009-09-10 04:29:173643 request.setRequestorID(routing_id_);
[email protected]cd448092010-12-06 23:49:133644 request.setHasUserGesture(frame->isProcessingUserGesture());
3645
[email protected]c5bbc2452010-03-08 08:33:503646 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoReferrers))
[email protected]7deade42010-03-05 09:33:133647 request.clearHTTPHeaderField("Referer");
[email protected]fa0a3432010-03-30 16:53:493648
[email protected]85cc78c2010-05-04 18:30:093649 // Temporary metrics, see site_isolation_metrics.h
3650 SiteIsolationMetrics::AddRequest(identifier, request.targetType());
[email protected]3d9689372009-09-10 04:29:173651}
3652
3653void RenderView::didReceiveResponse(
3654 WebFrame* frame, unsigned identifier, const WebURLResponse& response) {
[email protected]fa0a3432010-03-30 16:53:493655
[email protected]85cc78c2010-05-04 18:30:093656 // Temporary metrics, see site_isolation_metrics.h
3657 SiteIsolationMetrics::LogMimeTypeForCrossOriginRequest(frame,
3658 identifier,
3659 response);
[email protected]fa0a3432010-03-30 16:53:493660
[email protected]3d9689372009-09-10 04:29:173661 // Only do this for responses that correspond to a provisional data source
3662 // of the top-most frame. If we have a provisional data source, then we
3663 // can't have any sub-resources yet, so we know that this response must
3664 // correspond to a frame load.
3665 if (!frame->provisionalDataSource() || frame->parent())
3666 return;
3667
3668 // If we are in view source mode, then just let the user see the source of
[email protected]3f853a52010-09-13 19:15:083669 // the server's error page.
[email protected]3d9689372009-09-10 04:29:173670 if (frame->isViewSourceModeEnabled())
3671 return;
3672
[email protected]65041fa2010-05-21 06:56:533673 NavigationState* navigation_state =
3674 NavigationState::FromDataSource(frame->provisionalDataSource());
3675 CHECK(navigation_state);
[email protected]3f853a52010-09-13 19:15:083676 int http_status_code = response.httpStatusCode();
[email protected]65041fa2010-05-21 06:56:533677
[email protected]972ebdff2010-06-10 22:59:073678 // Record page load flags.
3679 navigation_state->set_was_fetched_via_spdy(response.wasFetchedViaSPDY());
3680 navigation_state->set_was_npn_negotiated(response.wasNpnNegotiated());
[email protected]193b0b892010-06-26 03:57:573681 navigation_state->set_was_alternate_protocol_available(
3682 response.wasAlternateProtocolAvailable());
[email protected]972ebdff2010-06-10 22:59:073683 navigation_state->set_was_fetched_via_proxy(response.wasFetchedViaProxy());
[email protected]3f853a52010-09-13 19:15:083684 navigation_state->set_http_status_code(http_status_code);
[email protected]06333afe2011-02-24 14:55:093685 // Whether or not the http status code actually corresponds to an error is
3686 // only checked when the page is done loading, if |use_error_page| is
3687 // still true.
3688 navigation_state->set_use_error_page(true);
[email protected]3d9689372009-09-10 04:29:173689}
3690
3691void RenderView::didFinishResourceLoad(
3692 WebFrame* frame, unsigned identifier) {
3693 NavigationState* navigation_state =
3694 NavigationState::FromDataSource(frame->dataSource());
[email protected]06333afe2011-02-24 14:55:093695 if (!navigation_state->use_error_page())
[email protected]3d9689372009-09-10 04:29:173696 return;
3697
[email protected]06333afe2011-02-24 14:55:093698 // Display error page, if appropriate.
[email protected]3f853a52010-09-13 19:15:083699 int http_status_code = navigation_state->http_status_code();
3700 if (http_status_code == 404) {
3701 // On 404s, try a remote search page as a fallback.
3702 const GURL& frame_url = frame->url();
[email protected]3d9689372009-09-10 04:29:173703
[email protected]3f853a52010-09-13 19:15:083704 const GURL& error_page_url = GetAlternateErrorPageURL(frame_url, HTTP_404);
[email protected]06333afe2011-02-24 14:55:093705 if (error_page_url.is_valid()) {
3706 WebURLError original_error;
3707 original_error.unreachableURL = frame_url;
[email protected]3d9689372009-09-10 04:29:173708
[email protected]06333afe2011-02-24 14:55:093709 navigation_state->set_alt_error_page_fetcher(
3710 new AltErrorPageResourceFetcher(
3711 error_page_url, frame, original_error,
3712 NewCallback(this, &RenderView::AltErrorPageFinished)));
3713 return;
3714 }
3715 }
[email protected]3d9689372009-09-10 04:29:173716
[email protected]06333afe2011-02-24 14:55:093717 // Use an internal error page, if we have one for the status code.
3718 if (LocalizedError::HasStrings(LocalizedError::kHttpErrorDomain,
3719 http_status_code)) {
[email protected]3f853a52010-09-13 19:15:083720 WebURLError error;
3721 error.unreachableURL = frame->url();
3722 error.domain = WebString::fromUTF8(LocalizedError::kHttpErrorDomain);
3723 error.reason = http_status_code;
[email protected]3d9689372009-09-10 04:29:173724
[email protected]3f853a52010-09-13 19:15:083725 LoadNavigationErrorPage(frame, frame->dataSource()->request(), error,
3726 std::string(), true);
3727 }
[email protected]3d9689372009-09-10 04:29:173728}
3729
3730void RenderView::didFailResourceLoad(
3731 WebFrame* frame, unsigned identifier, const WebURLError& error) {
3732 // Ignore
3733}
3734
3735void RenderView::didLoadResourceFromMemoryCache(
3736 WebFrame* frame, const WebURLRequest& request,
3737 const WebURLResponse& response) {
3738 // Let the browser know we loaded a resource from the memory cache. This
3739 // message is needed to display the correct SSL indicators.
3740 Send(new ViewHostMsg_DidLoadResourceFromMemoryCache(
3741 routing_id_,
3742 request.url(),
[email protected]3d9689372009-09-10 04:29:173743 response.securityInfo()));
3744}
3745
[email protected]6069da8c2009-10-20 20:33:493746void RenderView::didDisplayInsecureContent(WebFrame* frame) {
[email protected]e3d60e5d2009-09-25 21:08:293747 Send(new ViewHostMsg_DidDisplayInsecureContent(routing_id_));
3748}
3749
[email protected]92771112011-01-20 00:13:023750void RenderView::didRunInsecureContent(
3751 WebFrame* frame, const WebSecurityOrigin& origin, const WebURL& target) {
[email protected]e3d60e5d2009-09-25 21:08:293752 Send(new ViewHostMsg_DidRunInsecureContent(
3753 routing_id_,
[email protected]92771112011-01-20 00:13:023754 origin.toString().utf8(),
3755 target));
[email protected]e3d60e5d2009-09-25 21:08:293756}
3757
[email protected]7ea093ba2009-11-03 05:54:593758bool RenderView::allowScript(WebFrame* frame, bool enabled_per_settings) {
[email protected]12bc8472010-04-15 07:29:403759 if (enabled_per_settings &&
3760 AllowContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT))
3761 return true;
[email protected]7ea093ba2009-11-03 05:54:593762
[email protected]12bc8472010-04-15 07:29:403763 if (IsWhitelistedForContentSettings(frame))
3764 return true;
[email protected]7ea093ba2009-11-03 05:54:593765
3766 return false; // Other protocols fall through here.
3767}
3768
[email protected]0a1a45432010-03-31 08:09:453769bool RenderView::allowDatabase(
3770 WebFrame* frame, const WebString& name, const WebString& display_name,
3771 unsigned long estimated_size) {
3772 WebSecurityOrigin origin = frame->securityOrigin();
3773 if (origin.isEmpty())
3774 return false; // Uninitialized document?
3775
3776 bool result;
[email protected]26a9acf2010-12-13 19:35:053777 if (!Send(new DatabaseHostMsg_Allow(routing_id_,
[email protected]0a1a45432010-03-31 08:09:453778 origin.toString().utf8(), name, display_name, estimated_size, &result)))
3779 return false;
[email protected]9fb83e82010-07-02 18:24:553780 Send(new ViewHostMsg_WebDatabaseAccessed(routing_id_,
3781 GURL(origin.toString().utf8()),
3782 name,
3783 display_name,
3784 estimated_size,
3785 !result));
[email protected]0a1a45432010-03-31 08:09:453786 return result;
3787}
[email protected]8934a3b2010-02-25 00:34:003788void RenderView::didNotAllowScript(WebKit::WebFrame* frame) {
[email protected]55126132010-08-19 14:53:283789 DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string());
[email protected]8934a3b2010-02-25 00:34:003790}
3791
[email protected]c21f1d52010-03-04 03:19:433792void RenderView::didNotAllowPlugins(WebKit::WebFrame* frame) {
[email protected]55126132010-08-19 14:53:283793 DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, std::string());
[email protected]c21f1d52010-03-04 03:19:433794}
3795
[email protected]3d9689372009-09-10 04:29:173796void RenderView::didExhaustMemoryAvailableForScript(WebFrame* frame) {
3797 Send(new ViewHostMsg_JSOutOfMemory(routing_id_));
3798}
3799
[email protected]0c882b282009-10-07 17:01:283800void RenderView::didCreateScriptContext(WebFrame* frame) {
3801 EventBindings::HandleContextCreated(frame, false);
3802}
3803
3804void RenderView::didDestroyScriptContext(WebFrame* frame) {
3805 EventBindings::HandleContextDestroyed(frame);
3806}
3807
3808void RenderView::didCreateIsolatedScriptContext(WebFrame* frame) {
3809 EventBindings::HandleContextCreated(frame, true);
3810}
3811
[email protected]af7eb3fb2010-09-23 21:31:063812bool RenderView::allowScriptExtension(WebFrame* frame,
3813 const WebString& extension_name,
3814 int extension_group) {
3815 // NULL in unit tests.
3816 if (!RenderThread::current())
3817 return true;
3818
3819 // Note: we prefer the provisional URL here instead of the document URL
3820 // because we might be currently loading an URL into a blank page.
3821 // See http://code.google.com/p/chromium/issues/detail?id=10924
3822 WebDataSource* ds = frame->provisionalDataSource();
3823 if (!ds)
3824 ds = frame->dataSource();
3825 return RenderThread::current()->AllowScriptExtension(
3826 extension_name.utf8(), ds->request().url(), extension_group);
3827}
3828
[email protected]fc86daa2010-03-30 23:52:533829void RenderView::logCrossFramePropertyAccess(WebFrame* frame,
3830 WebFrame* target,
3831 bool cross_origin,
3832 const WebString& property_name,
3833 unsigned long long event_id) {
[email protected]ab9eabac2010-03-16 16:54:103834 // TODO(johnnyg): track the individual properties and repeat event_ids.
[email protected]a5a65ac2010-11-05 18:14:363835 page_load_histograms_.IncrementCrossFramePropertyAccess(cross_origin);
[email protected]ab9eabac2010-03-16 16:54:103836}
3837
[email protected]3d9689372009-09-10 04:29:173838void RenderView::didChangeContentsSize(WebFrame* frame, const WebSize& size) {
[email protected]d8a179c2010-01-31 00:58:143839 CheckPreferredSize();
3840}
3841
3842void RenderView::CheckPreferredSize() {
[email protected]3d9689372009-09-10 04:29:173843 // We don't always want to send the change messages over IPC, only if we've
[email protected]ab32b16c2009-10-16 14:57:253844 // be put in that mode by getting a |ViewMsg_EnablePreferredSizeChangedMode|
[email protected]3d9689372009-09-10 04:29:173845 // message.
[email protected]705243f2010-05-05 19:58:073846 if (!send_preferred_size_changes_ || !webview())
3847 return;
[email protected]dfca5acf2010-03-22 03:28:433848
[email protected]705243f2010-05-05 19:58:073849 // WebCore likes to tell us things have changed even when they haven't, so
3850 // cache the width and height and only send the IPC message when we're sure
3851 // they're different.
3852 gfx::Size size(webview()->mainFrame()->contentsPreferredWidth(),
3853 webview()->mainFrame()->documentElementScrollHeight());
[email protected]8205d742010-10-22 23:51:533854
3855 // In the presence of zoom, these sizes are still reported as if unzoomed,
3856 // so we need to adjust.
3857 double zoom_factor = WebView::zoomLevelToZoomFactor(webview()->zoomLevel());
3858 size.set_width(static_cast<int>(size.width() * zoom_factor));
3859 size.set_height(static_cast<int>(size.height() * zoom_factor));
3860
[email protected]705243f2010-05-05 19:58:073861 if (size == preferred_size_)
3862 return;
[email protected]c27324b2009-11-19 22:44:293863
[email protected]705243f2010-05-05 19:58:073864 preferred_size_ = size;
3865 Send(new ViewHostMsg_DidContentsPreferredSizeChange(routing_id_,
3866 preferred_size_));
[email protected]3d9689372009-09-10 04:29:173867}
3868
[email protected]143dcd592009-11-06 21:33:493869void RenderView::didChangeScrollOffset(WebFrame* frame) {
3870 StartNavStateSyncTimerIfNecessary();
3871}
3872
[email protected]8922e1f2009-10-03 05:01:263873void RenderView::reportFindInPageMatchCount(int request_id, int count,
3874 bool final_update) {
[email protected]e7c58a32010-08-13 19:47:113875 int active_match_ordinal = -1; // -1 = don't update active match ordinal
3876 if (!count)
3877 active_match_ordinal = 0;
3878
3879 IPC::Message* msg = new ViewHostMsg_Find_Reply(
3880 routing_id_,
3881 request_id,
3882 count,
3883 gfx::Rect(),
3884 active_match_ordinal,
3885 final_update);
3886
[email protected]8922e1f2009-10-03 05:01:263887 // If we have a message that has been queued up, then we should just replace
3888 // it. The ACK from the browser will make sure it gets sent when the browser
3889 // wants it.
3890 if (queued_find_reply_message_.get()) {
[email protected]8922e1f2009-10-03 05:01:263891 queued_find_reply_message_.reset(msg);
3892 } else {
3893 // Send the search result over to the browser process.
[email protected]e7c58a32010-08-13 19:47:113894 Send(msg);
[email protected]8922e1f2009-10-03 05:01:263895 }
3896}
3897
3898void RenderView::reportFindInPageSelection(int request_id,
3899 int active_match_ordinal,
3900 const WebRect& selection_rect) {
3901 // Send the search result over to the browser process.
3902 Send(new ViewHostMsg_Find_Reply(routing_id_,
3903 request_id,
3904 -1,
3905 selection_rect,
3906 active_match_ordinal,
3907 false));
3908}
3909
[email protected]2b06a992010-08-21 05:48:223910void RenderView::openFileSystem(
3911 WebFrame* frame,
3912 WebFileSystem::Type type,
3913 long long size,
[email protected]d275d7a2010-11-03 01:34:493914 bool create,
[email protected]2b06a992010-08-21 05:48:223915 WebFileSystemCallbacks* callbacks) {
[email protected]c5a272d2010-09-27 18:37:083916 DCHECK(callbacks);
[email protected]2b06a992010-08-21 05:48:223917
3918 WebSecurityOrigin origin = frame->securityOrigin();
[email protected]c5a272d2010-09-27 18:37:083919 if (origin.isEmpty()) {
3920 // Uninitialized document?
3921 callbacks->didFail(WebKit::WebFileErrorAbort);
3922 return;
3923 }
[email protected]2b06a992010-08-21 05:48:223924
[email protected]c5a272d2010-09-27 18:37:083925 ChildThread::current()->file_system_dispatcher()->OpenFileSystem(
3926 GURL(origin.toString()), static_cast<fileapi::FileSystemType>(type),
[email protected]d275d7a2010-11-03 01:34:493927 size, create, new WebFileSystemCallbackDispatcher(callbacks));
[email protected]2b06a992010-08-21 05:48:223928}
3929
[email protected]79dbc662009-09-04 05:42:513930// webkit_glue::WebPluginPageDelegate -----------------------------------------
3931
[email protected]191eb3f72010-12-21 06:27:503932webkit::npapi::WebPluginDelegate* RenderView::CreatePluginDelegate(
[email protected]4e0616e2010-05-28 14:55:533933 const FilePath& file_path,
3934 const std::string& mime_type) {
[email protected]f103ab72009-09-02 17:10:593935 if (!PluginChannelHost::IsListening())
3936 return NULL;
3937
[email protected]d2139662009-12-10 03:21:143938 bool use_pepper_host = false;
[email protected]00c39612010-03-06 02:53:283939 bool in_process_plugin = RenderProcess::current()->UseInProcessPlugins();
[email protected]d2139662009-12-10 03:21:143940 // Check for trusted Pepper plugins.
[email protected]26e8d5e2009-10-13 02:47:163941 const char kPepperPrefix[] = "pepper-";
[email protected]4e0616e2010-05-28 14:55:533942 if (StartsWithASCII(mime_type, kPepperPrefix, true)) {
[email protected]d2139662009-12-10 03:21:143943 if (CommandLine::ForCurrentProcess()->
3944 HasSwitch(switches::kInternalPepper)) {
3945 in_process_plugin = true;
3946 use_pepper_host = true;
3947 } else {
3948 // In process Pepper plugins must be explicitly enabled.
3949 return NULL;
3950 }
[email protected]4e0616e2010-05-28 14:55:533951 } else {
3952 FilePath internal_pdf_path;
3953 PathService::Get(chrome::FILE_PDF_PLUGIN, &internal_pdf_path);
3954 if (file_path == internal_pdf_path) {
3955 in_process_plugin = true;
3956 use_pepper_host = true;
3957 }
[email protected]26e8d5e2009-10-13 02:47:163958 }
[email protected]4e0616e2010-05-28 14:55:533959
[email protected]d032f492009-09-29 00:33:463960 if (in_process_plugin) {
[email protected]d2139662009-12-10 03:21:143961 if (use_pepper_host) {
[email protected]00c39612010-03-06 02:53:283962 WebPluginDelegatePepper* pepper_plugin =
[email protected]4e0616e2010-05-28 14:55:533963 WebPluginDelegatePepper::Create(file_path, mime_type, AsWeakPtr());
[email protected]b7d7ed52010-07-20 00:12:333964 if (!pepper_plugin)
3965 return NULL;
3966
[email protected]53900d52010-06-16 04:25:013967 current_oldstyle_pepper_plugins_.insert(pepper_plugin);
[email protected]00c39612010-03-06 02:53:283968 return pepper_plugin;
[email protected]d2139662009-12-10 03:21:143969 } else {
[email protected]6876dff2010-01-15 19:38:093970#if defined(OS_WIN) // In-proc plugins aren't supported on Linux or Mac.
[email protected]191eb3f72010-12-21 06:27:503971 return webkit::npapi::WebPluginDelegateImpl::Create(
[email protected]4e0616e2010-05-28 14:55:533972 file_path, mime_type, gfx::NativeViewFromId(host_window_));
[email protected]6876dff2010-01-15 19:38:093973#else
[email protected]596b2c42010-01-14 20:40:433974 NOTIMPLEMENTED();
3975 return NULL;
[email protected]7b6616f2010-01-14 18:07:553976#endif
[email protected]6876dff2010-01-15 19:38:093977 }
[email protected]f103ab72009-09-02 17:10:593978 }
3979
[email protected]4e0616e2010-05-28 14:55:533980 return new WebPluginDelegateProxy(mime_type, AsWeakPtr());
[email protected]f103ab72009-09-02 17:10:593981}
3982
3983void RenderView::CreatedPluginWindow(gfx::PluginWindowHandle window) {
[email protected]6981f7f2010-03-09 00:53:033984#if defined(USE_X11)
[email protected]f103ab72009-09-02 17:10:593985 RenderThread::current()->Send(new ViewHostMsg_CreatePluginContainer(
3986 routing_id(), window));
3987#endif
3988}
3989
3990void RenderView::WillDestroyPluginWindow(gfx::PluginWindowHandle window) {
[email protected]6981f7f2010-03-09 00:53:033991#if defined(USE_X11)
[email protected]f103ab72009-09-02 17:10:593992 RenderThread::current()->Send(new ViewHostMsg_DestroyPluginContainer(
3993 routing_id(), window));
3994#endif
3995 CleanupWindowInPluginMoves(window);
3996}
3997
[email protected]191eb3f72010-12-21 06:27:503998void RenderView::DidMovePlugin(const webkit::npapi::WebPluginGeometry& move) {
[email protected]f103ab72009-09-02 17:10:593999 SchedulePluginMove(move);
4000}
4001
4002void RenderView::DidStartLoadingForPlugin() {
4003 // TODO(darin): Make is_loading_ be a counter!
[email protected]48c9cf2d2009-09-16 16:47:524004 didStartLoading();
[email protected]f103ab72009-09-02 17:10:594005}
4006
4007void RenderView::DidStopLoadingForPlugin() {
4008 // TODO(darin): Make is_loading_ be a counter!
[email protected]48c9cf2d2009-09-16 16:47:524009 didStopLoading();
[email protected]f103ab72009-09-02 17:10:594010}
4011
4012void RenderView::ShowModalHTMLDialogForPlugin(
4013 const GURL& url,
4014 const gfx::Size& size,
4015 const std::string& json_arguments,
4016 std::string* json_retval) {
[email protected]12636df2009-09-28 22:32:214017 SendAndRunNestedMessageLoop(new ViewHostMsg_ShowModalHTMLDialog(
[email protected]f103ab72009-09-02 17:10:594018 routing_id_, url, size.width(), size.height(), json_arguments,
[email protected]12636df2009-09-28 22:32:214019 json_retval));
[email protected]f103ab72009-09-02 17:10:594020}
4021
[email protected]b921cfd22010-02-25 16:57:514022WebCookieJar* RenderView::GetCookieJar() {
4023 return &cookie_jar_;
4024}
4025
initial.commit09911bf2008-07-26 23:55:294026void RenderView::SyncNavigationState() {
4027 if (!webview())
4028 return;
4029
[email protected]26aa0482009-09-30 16:55:274030 const WebHistoryItem& item = webview()->mainFrame()->currentHistoryItem();
[email protected]ca948a22009-06-25 19:36:174031 if (item.isNull())
initial.commit09911bf2008-07-26 23:55:294032 return;
[email protected]ca948a22009-06-25 19:36:174033
4034 Send(new ViewHostMsg_UpdateState(
4035 routing_id_, page_id_, webkit_glue::HistoryItemToString(item)));
initial.commit09911bf2008-07-26 23:55:294036}
4037
[email protected]b0950a72009-09-29 23:16:174038bool RenderView::DownloadImage(int id, const GURL& image_url, int image_size) {
4039 // Make sure webview was not shut down.
4040 if (!webview())
4041 return false;
4042 // Create an image resource fetcher and assign it with a call back object.
[email protected]bb461532010-11-26 21:50:234043 image_fetchers_.push_back(linked_ptr<ImageResourceFetcher>(
4044 new ImageResourceFetcher(
4045 image_url, webview()->mainFrame(), id, image_size,
4046 NewCallback(this, &RenderView::DidDownloadImage))));
[email protected]b0950a72009-09-29 23:16:174047 return true;
4048}
4049
4050void RenderView::DidDownloadImage(ImageResourceFetcher* fetcher,
initial.commit09911bf2008-07-26 23:55:294051 const SkBitmap& image) {
[email protected]b0950a72009-09-29 23:16:174052 // Notify requester of image download status.
[email protected]51bd36612009-10-20 22:49:474053 Send(new ViewHostMsg_DidDownloadFavIcon(routing_id_,
4054 fetcher->id(),
4055 fetcher->image_url(),
4056 image.isNull(),
4057 image));
[email protected]bb461532010-11-26 21:50:234058
4059 // Remove the image fetcher from our pending list. We're in the callback from
4060 // ImageResourceFetcher, best to delay deletion.
4061 for (ImageResourceFetcherList::iterator iter = image_fetchers_.begin();
4062 iter != image_fetchers_.end(); ++iter) {
4063 if (iter->get() == fetcher) {
4064 iter->release();
4065 image_fetchers_.erase(iter);
4066 break;
4067 }
4068 }
[email protected]b0950a72009-09-29 23:16:174069 MessageLoop::current()->DeleteSoon(FROM_HERE, fetcher);
initial.commit09911bf2008-07-26 23:55:294070}
4071
[email protected]bf5c2ff392009-07-08 16:24:334072void RenderView::OnDownloadFavIcon(int id,
4073 const GURL& image_url,
4074 int image_size) {
[email protected]f11ca0732009-04-11 00:09:344075 bool data_image_failed = false;
4076 if (image_url.SchemeIs("data")) {
4077 SkBitmap data_image = ImageFromDataUrl(image_url);
4078 data_image_failed = data_image.empty();
4079 if (!data_image_failed) {
[email protected]bf5c2ff392009-07-08 16:24:334080 Send(new ViewHostMsg_DidDownloadFavIcon(routing_id_, id, image_url, false,
4081 data_image));
[email protected]f11ca0732009-04-11 00:09:344082 }
4083 }
4084
[email protected]bf5c2ff392009-07-08 16:24:334085 if (data_image_failed ||
[email protected]b0950a72009-09-29 23:16:174086 !DownloadImage(id, image_url, image_size)) {
[email protected]bf5c2ff392009-07-08 16:24:334087 Send(new ViewHostMsg_DidDownloadFavIcon(routing_id_, id, image_url, true,
4088 SkBitmap()));
4089 }
initial.commit09911bf2008-07-26 23:55:294090}
4091
[email protected]f11ca0732009-04-11 00:09:344092SkBitmap RenderView::ImageFromDataUrl(const GURL& url) const {
4093 std::string mime_type, char_set, data;
4094 if (net::DataURL::Parse(url, &mime_type, &char_set, &data) && !data.empty()) {
4095 // Decode the favicon using WebKit's image decoder.
4096 webkit_glue::ImageDecoder decoder(gfx::Size(kFavIconSize, kFavIconSize));
4097 const unsigned char* src_data =
4098 reinterpret_cast<const unsigned char*>(&data[0]);
4099
4100 return decoder.Decode(src_data, data.size());
4101 }
4102 return SkBitmap();
4103}
4104
initial.commit09911bf2008-07-26 23:55:294105void RenderView::OnGetApplicationInfo(int page_id) {
[email protected]38789d82010-11-17 06:03:444106 WebApplicationInfo app_info;
4107 if (page_id == page_id_) {
4108 string16 error;
4109 web_apps::ParseWebAppFromWebDocument(webview()->mainFrame(), &app_info,
4110 &error);
4111 }
initial.commit09911bf2008-07-26 23:55:294112
4113 // Prune out any data URLs in the set of icons. The browser process expects
4114 // any icon with a data URL to have originated from a favicon. We don't want
4115 // to decode arbitrary data URLs in the browser process. See
4116 // http://b/issue?id=1162972
4117 for (size_t i = 0; i < app_info.icons.size(); ++i) {
[email protected]6de74452009-02-25 18:04:594118 if (app_info.icons[i].url.SchemeIs(chrome::kDataScheme)) {
initial.commit09911bf2008-07-26 23:55:294119 app_info.icons.erase(app_info.icons.begin() + i);
4120 --i;
4121 }
4122 }
4123
4124 Send(new ViewHostMsg_DidGetApplicationInfo(routing_id_, page_id, app_info));
4125}
4126
[email protected]7ccddb8c2009-08-04 17:36:554127GURL RenderView::GetAlternateErrorPageURL(const GURL& failed_url,
initial.commit09911bf2008-07-26 23:55:294128 ErrorPageType error_type) {
[email protected]7ccddb8c2009-08-04 17:36:554129 if (failed_url.SchemeIsSecure()) {
initial.commit09911bf2008-07-26 23:55:294130 // If the URL that failed was secure, then the embedding web page was not
4131 // expecting a network attacker to be able to manipulate its contents. As
4132 // we fetch alternate error pages over HTTP, we would be allowing a network
4133 // attacker to manipulate the contents of the response if we tried to use
4134 // the link doctor here.
[email protected]810a52ef2010-01-08 01:22:154135 return GURL();
initial.commit09911bf2008-07-26 23:55:294136 }
4137
4138 // Grab the base URL from the browser process.
4139 if (!alternate_error_page_url_.is_valid())
[email protected]810a52ef2010-01-08 01:22:154140 return GURL();
initial.commit09911bf2008-07-26 23:55:294141
4142 // Strip query params from the failed URL.
4143 GURL::Replacements remove_params;
4144 remove_params.ClearUsername();
4145 remove_params.ClearPassword();
4146 remove_params.ClearQuery();
4147 remove_params.ClearRef();
[email protected]7ccddb8c2009-08-04 17:36:554148 const GURL url_to_send = failed_url.ReplaceComponents(remove_params);
[email protected]6fd28f642010-03-15 17:15:504149 std::string spec_to_send = url_to_send.spec();
4150 // Notify link doctor of the url truncation by sending of "?" at the end.
4151 if (failed_url.has_query())
4152 spec_to_send.append("?");
initial.commit09911bf2008-07-26 23:55:294153
4154 // Construct the query params to send to link doctor.
4155 std::string params(alternate_error_page_url_.query());
4156 params.append("&url=");
[email protected]6fd28f642010-03-15 17:15:504157 params.append(EscapeQueryParamValue(spec_to_send, true));
initial.commit09911bf2008-07-26 23:55:294158 params.append("&sourceid=chrome");
4159 params.append("&error=");
4160 switch (error_type) {
4161 case DNS_ERROR:
4162 params.append("dnserror");
4163 break;
4164
4165 case HTTP_404:
4166 params.append("http404");
4167 break;
4168
[email protected]5df266ac2008-10-15 19:50:134169 case CONNECTION_ERROR:
[email protected]e1f934b2009-01-26 20:41:334170 params.append("connectionfailure");
[email protected]5df266ac2008-10-15 19:50:134171 break;
4172
initial.commit09911bf2008-07-26 23:55:294173 default:
4174 NOTREACHED() << "unknown ErrorPageType";
4175 }
4176
4177 // OK, build the final url to return.
4178 GURL::Replacements link_doctor_params;
4179 link_doctor_params.SetQueryStr(params);
4180 GURL url = alternate_error_page_url_.ReplaceComponents(link_doctor_params);
4181 return url;
4182}
4183
[email protected]c50008512011-02-03 01:17:274184WebUIBindings* RenderView::GetWebUIBindings() {
4185 if (!web_ui_bindings_.get()) {
4186 web_ui_bindings_.reset(new WebUIBindings());
[email protected]c091c2c2010-09-17 19:05:464187 }
[email protected]c50008512011-02-03 01:17:274188 return web_ui_bindings_.get();
[email protected]c091c2c2010-09-17 19:05:464189}
4190
4191ExternalHostBindings* RenderView::GetExternalHostBindings() {
4192 if (!external_host_bindings_.get()) {
4193 external_host_bindings_.reset(new ExternalHostBindings());
4194 }
4195 return external_host_bindings_.get();
4196}
4197
[email protected]0fdbf8c2010-07-08 20:33:014198WebKit::WebPlugin* RenderView::GetWebPluginFromPluginDocument() {
4199 return webview()->mainFrame()->document().to<WebPluginDocument>().plugin();
[email protected]24a7f3c2010-03-25 08:26:494200}
4201
[email protected]6069da8c2009-10-20 20:33:494202void RenderView::OnFind(int request_id, const string16& search_text,
4203 const WebFindOptions& options) {
[email protected]26aa0482009-09-30 16:55:274204 WebFrame* main_frame = webview()->mainFrame();
[email protected]24a7f3c2010-03-25 08:26:494205
4206 if (main_frame->document().isPluginDocument()) {
[email protected]24a7f3c2010-03-25 08:26:494207 if (options.findNext) {
4208 // Just navigate back/forward.
[email protected]0fdbf8c2010-07-08 20:33:014209 GetWebPluginFromPluginDocument()->selectFindResult(options.forward);
[email protected]24a7f3c2010-03-25 08:26:494210 } else {
[email protected]afdbd142010-07-10 08:01:234211 if (GetWebPluginFromPluginDocument()->startFind(
4212 search_text, options.matchCase, request_id)) {
[email protected]24a7f3c2010-03-25 08:26:494213 } else {
[email protected]e7c58a32010-08-13 19:47:114214 // Send "no results".
4215 Send(new ViewHostMsg_Find_Reply(routing_id_,
4216 request_id,
4217 0,
4218 gfx::Rect(),
4219 0,
4220 true));
[email protected]24a7f3c2010-03-25 08:26:494221 }
4222 }
4223 return;
4224 }
4225
[email protected]b4bb2502009-10-01 22:35:274226 WebFrame* frame_after_main = main_frame->traverseNext(true);
[email protected]26aa0482009-09-30 16:55:274227 WebFrame* focused_frame = webview()->focusedFrame();
initial.commit09911bf2008-07-26 23:55:294228 WebFrame* search_frame = focused_frame; // start searching focused frame.
4229
4230 bool multi_frame = (frame_after_main != main_frame);
4231
4232 // If we have multiple frames, we don't want to wrap the search within the
4233 // frame, so we check here if we only have main_frame in the chain.
4234 bool wrap_within_frame = !multi_frame;
4235
[email protected]b3f2b912009-04-09 16:18:524236 WebRect selection_rect;
initial.commit09911bf2008-07-26 23:55:294237 bool result = false;
4238
[email protected]7830da3e2009-11-06 16:27:264239 // If something is selected when we start searching it means we cannot just
4240 // increment the current match ordinal; we need to re-generate it.
4241 WebRange current_selection = focused_frame->selectionRange();
4242
initial.commit09911bf2008-07-26 23:55:294243 do {
[email protected]dd7daa82009-08-10 05:46:454244 result = search_frame->find(
[email protected]7ea066a2009-04-06 20:21:594245 request_id, search_text, options, wrap_within_frame, &selection_rect);
initial.commit09911bf2008-07-26 23:55:294246
4247 if (!result) {
4248 // don't leave text selected as you move to the next frame.
[email protected]a100d76bb2009-08-14 17:50:224249 search_frame->executeCommand(WebString::fromUTF8("Unselect"));
initial.commit09911bf2008-07-26 23:55:294250
4251 // Find the next frame, but skip the invisible ones.
4252 do {
4253 // What is the next frame to search? (we might be going backwards). Note
4254 // that we specify wrap=true so that search_frame never becomes NULL.
[email protected]7ea066a2009-04-06 20:21:594255 search_frame = options.forward ?
[email protected]b4bb2502009-10-01 22:35:274256 search_frame->traverseNext(true) :
4257 search_frame->traversePrevious(true);
[email protected]dd7daa82009-08-10 05:46:454258 } while (!search_frame->hasVisibleContent() &&
4259 search_frame != focused_frame);
initial.commit09911bf2008-07-26 23:55:294260
[email protected]884db412008-11-24 23:46:504261 // Make sure selection doesn't affect the search operation in new frame.
[email protected]a100d76bb2009-08-14 17:50:224262 search_frame->executeCommand(WebString::fromUTF8("Unselect"));
initial.commit09911bf2008-07-26 23:55:294263
4264 // If we have multiple frames and we have wrapped back around to the
4265 // focused frame, we need to search it once more allowing wrap within
4266 // the frame, otherwise it will report 'no match' if the focused frame has
4267 // reported matches, but no frames after the focused_frame contain a
4268 // match for the search word(s).
4269 if (multi_frame && search_frame == focused_frame) {
[email protected]dd7daa82009-08-10 05:46:454270 result = search_frame->find(
[email protected]7ea066a2009-04-06 20:21:594271 request_id, search_text, options, true, // Force wrapping.
4272 &selection_rect);
initial.commit09911bf2008-07-26 23:55:294273 }
4274 }
4275
[email protected]26aa0482009-09-30 16:55:274276 webview()->setFocusedFrame(search_frame);
initial.commit09911bf2008-07-26 23:55:294277 } while (!result && search_frame != focused_frame);
4278
[email protected]7830da3e2009-11-06 16:27:264279 if (options.findNext && current_selection.isNull()) {
[email protected]4f3dc372009-02-24 00:10:294280 // Force the main_frame to report the actual count.
[email protected]dd7daa82009-08-10 05:46:454281 main_frame->increaseMatchCount(0, request_id);
[email protected]4f3dc372009-02-24 00:10:294282 } else {
4283 // If nothing is found, set result to "0 of 0", otherwise, set it to
4284 // "-1 of 1" to indicate that we found at least one item, but we don't know
4285 // yet what is active.
4286 int ordinal = result ? -1 : 0; // -1 here means, we might know more later.
4287 int match_count = result ? 1 : 0; // 1 here means possibly more coming.
initial.commit09911bf2008-07-26 23:55:294288
[email protected]4f3dc372009-02-24 00:10:294289 // If we find no matches then this will be our last status update.
4290 // Otherwise the scoping effort will send more results.
4291 bool final_status_update = !result;
initial.commit09911bf2008-07-26 23:55:294292
[email protected]4f3dc372009-02-24 00:10:294293 // Send the search result over to the browser process.
[email protected]4f999132009-03-31 18:08:404294 Send(new ViewHostMsg_Find_Reply(routing_id_,
[email protected]7ea066a2009-04-06 20:21:594295 request_id,
[email protected]4f3dc372009-02-24 00:10:294296 match_count,
4297 selection_rect,
4298 ordinal,
4299 final_status_update));
initial.commit09911bf2008-07-26 23:55:294300
initial.commit09911bf2008-07-26 23:55:294301 // Scoping effort begins, starting with the mainframe.
4302 search_frame = main_frame;
4303
[email protected]dd7daa82009-08-10 05:46:454304 main_frame->resetMatchCount();
initial.commit09911bf2008-07-26 23:55:294305
4306 do {
4307 // Cancel all old scoping requests before starting a new one.
[email protected]dd7daa82009-08-10 05:46:454308 search_frame->cancelPendingScopingEffort();
initial.commit09911bf2008-07-26 23:55:294309
4310 // We don't start another scoping effort unless at least one match has
4311 // been found.
4312 if (result) {
4313 // Start new scoping request. If the scoping function determines that it
4314 // needs to scope, it will defer until later.
[email protected]dd7daa82009-08-10 05:46:454315 search_frame->scopeStringMatches(request_id,
[email protected]7ea066a2009-04-06 20:21:594316 search_text,
4317 options,
initial.commit09911bf2008-07-26 23:55:294318 true); // reset the tickmarks
4319 }
4320
4321 // Iterate to the next frame. The frame will not necessarily scope, for
4322 // example if it is not visible.
[email protected]b4bb2502009-10-01 22:35:274323 search_frame = search_frame->traverseNext(true);
initial.commit09911bf2008-07-26 23:55:294324 } while (search_frame != main_frame);
4325 }
4326}
4327
[email protected]24a7f3c2010-03-25 08:26:494328void RenderView::OnStopFinding(const ViewMsg_StopFinding_Params& params) {
4329 WebView* view = webview();
4330 if (!view)
4331 return;
4332
4333 WebDocument doc = view->mainFrame()->document();
4334 if (doc.isPluginDocument()) {
[email protected]0fdbf8c2010-07-08 20:33:014335 GetWebPluginFromPluginDocument()->stopFind();
[email protected]24a7f3c2010-03-25 08:26:494336 return;
4337 }
4338
4339 bool clear_selection =
4340 params.action == ViewMsg_StopFinding_Params::kClearSelection;
4341 if (clear_selection)
4342 view->focusedFrame()->executeCommand(WebString::fromUTF8("Unselect"));
4343
4344 WebFrame* frame = view->mainFrame();
4345 while (frame) {
4346 frame->stopFinding(clear_selection);
4347 frame = frame->traverseNext(false);
4348 }
4349
4350 if (params.action == ViewMsg_StopFinding_Params::kActivateSelection) {
4351 WebFrame* focused_frame = view->focusedFrame();
4352 if (focused_frame) {
4353 WebDocument doc = focused_frame->document();
4354 if (!doc.isNull()) {
4355 WebNode node = doc.focusedNode();
4356 if (!node.isNull())
4357 node.simulateClick();
4358 }
4359 }
4360 }
4361}
4362
4363void RenderView::OnFindReplyAck() {
4364 // Check if there is any queued up request waiting to be sent.
4365 if (queued_find_reply_message_.get()) {
4366 // Send the search result over to the browser process.
[email protected]d22d8732010-05-04 19:24:424367 Send(queued_find_reply_message_.release());
[email protected]24a7f3c2010-03-25 08:26:494368 }
4369}
4370
[email protected]8934a3b2010-02-25 00:34:004371bool RenderView::AllowContentType(ContentSettingsType settings_type) {
[email protected]0de80162010-02-03 04:52:354372 // CONTENT_SETTING_ASK is only valid for cookies.
[email protected]8934a3b2010-02-25 00:34:004373 return current_content_settings_.settings[settings_type] !=
4374 CONTENT_SETTING_BLOCK;
4375}
4376
[email protected]55126132010-08-19 14:53:284377void RenderView::DidBlockContentType(ContentSettingsType settings_type,
4378 const std::string& resource_identifier) {
[email protected]8934a3b2010-02-25 00:34:004379 if (!content_blocked_[settings_type]) {
4380 content_blocked_[settings_type] = true;
[email protected]55126132010-08-19 14:53:284381 Send(new ViewHostMsg_ContentBlocked(routing_id_, settings_type,
4382 resource_identifier));
[email protected]0de80162010-02-03 04:52:354383 }
[email protected]0de80162010-02-03 04:52:354384}
4385
[email protected]71b0d5d2010-02-15 05:43:074386void RenderView::ClearBlockedContentSettings() {
4387 for (size_t i = 0; i < arraysize(content_blocked_); ++i)
4388 content_blocked_[i] = false;
4389}
4390
[email protected]0bd753682010-12-16 18:15:524391WebPlugin* RenderView::CreatePepperPlugin(
4392 WebFrame* frame,
4393 const WebPluginParams& params,
4394 const FilePath& path,
4395 webkit::ppapi::PluginModule* pepper_module) {
4396 return new webkit::ppapi::WebPluginImpl(
[email protected]b75b8292010-10-01 07:28:254397 pepper_module, params, pepper_delegate_.AsWeakPtr());
[email protected]aad51d1c2010-08-05 08:38:094398}
[email protected]00152e92010-07-19 11:47:404399
[email protected]191eb3f72010-12-21 06:27:504400WebPlugin* RenderView::CreateNPAPIPlugin(
4401 WebFrame* frame,
4402 const WebPluginParams& params,
4403 const FilePath& path,
4404 const std::string& mime_type) {
4405 return new webkit::npapi::WebPluginImpl(
[email protected]20a793e2010-10-12 06:50:084406 frame, params, path, mime_type, AsWeakPtr());
[email protected]00152e92010-07-19 11:47:404407}
4408
[email protected]3c2826852010-12-16 19:09:144409WebPlugin* RenderView::CreatePluginPlaceholder(
[email protected]57b66d02010-09-30 11:24:514410 WebFrame* frame,
4411 const WebPluginParams& params,
[email protected]191eb3f72010-12-21 06:27:504412 const webkit::npapi::PluginGroup& group,
[email protected]3c2826852010-12-16 19:09:144413 int resource_id,
[email protected]90dba072011-01-20 20:10:204414 int message_id,
4415 bool is_blocked_for_prerendering) {
[email protected]3c2826852010-12-16 19:09:144416 // |blocked_plugin| will delete itself when the WebViewPlugin
4417 // is destroyed.
4418 BlockedPlugin* blocked_plugin =
4419 new BlockedPlugin(this,
4420 frame,
4421 group,
4422 params,
4423 webkit_preferences_,
4424 resource_id,
[email protected]2e34ab3f2010-12-17 05:47:374425 l10n_util::GetStringFUTF16(message_id,
[email protected]90dba072011-01-20 20:10:204426 group.GetGroupName()),
4427 is_blocked_for_prerendering);
[email protected]3c2826852010-12-16 19:09:144428 return blocked_plugin->plugin();
[email protected]57b66d02010-09-30 11:24:514429}
4430
[email protected]40bd6582009-12-04 23:49:514431void RenderView::OnZoom(PageZoom::Function function) {
4432 if (!webview()) // Not sure if this can happen, but no harm in being safe.
4433 return;
4434
[email protected]258d31122010-05-09 10:59:414435 webview()->hidePopups();
[email protected]b03794d2010-03-26 19:57:524436
[email protected]b75b8292010-10-01 07:28:254437 double old_zoom_level = webview()->zoomLevel();
4438 double zoom_level;
4439 if (function == PageZoom::RESET) {
4440 zoom_level = 0;
4441 } else if (static_cast<int>(old_zoom_level) == old_zoom_level) {
4442 // Previous zoom level is a whole number, so just increment/decrement.
4443 zoom_level = old_zoom_level + function;
4444 } else {
4445 // Either the user hit the zoom factor limit and thus the zoom level is now
4446 // not a whole number, or a plugin changed it to a custom value. We want
4447 // to go to the next whole number so that the user can always get back to
4448 // 100% with the keyboard/menu.
4449 if ((old_zoom_level > 1 && function > 0) ||
4450 (old_zoom_level < 1 && function < 0)) {
[email protected]3209e7112010-10-01 23:53:454451 zoom_level = static_cast<int>(old_zoom_level + function);
[email protected]b75b8292010-10-01 07:28:254452 } else {
4453 // We're going towards 100%, so first go to the next whole number.
4454 zoom_level = static_cast<int>(old_zoom_level);
4455 }
4456 }
[email protected]40bd6582009-12-04 23:49:514457
[email protected]b75b8292010-10-01 07:28:254458 webview()->setZoomLevel(false, zoom_level);
4459 zoomLevelChanged();
[email protected]40bd6582009-12-04 23:49:514460}
4461
[email protected]d0b8d092010-10-25 04:05:174462void RenderView::OnSetZoomLevel(double zoom_level) {
4463 // Don't set zoom level for full-page plugin since they don't use the same
4464 // zoom settings.
4465 if (webview()->mainFrame()->document().isPluginDocument())
4466 return;
4467
4468 webview()->hidePopups();
4469 webview()->setZoomLevel(false, zoom_level);
4470 zoomLevelChanged();
4471}
4472
[email protected]9d797f32010-04-23 07:17:544473void RenderView::OnSetContentSettingsForLoadingURL(
4474 const GURL& url,
[email protected]f85f0702010-01-30 09:31:014475 const ContentSettings& content_settings) {
[email protected]9d797f32010-04-23 07:17:544476 host_content_settings_[url] = content_settings;
[email protected]f85f0702010-01-30 09:31:014477}
4478
[email protected]9d797f32010-04-23 07:17:544479void RenderView::OnSetZoomLevelForLoadingURL(const GURL& url,
[email protected]b75b8292010-10-01 07:28:254480 double zoom_level) {
[email protected]9d797f32010-04-23 07:17:544481 host_zoom_levels_[url] = zoom_level;
initial.commit09911bf2008-07-26 23:55:294482}
4483
[email protected]41fc0322009-09-04 22:23:404484void RenderView::OnSetPageEncoding(const std::string& encoding_name) {
[email protected]26aa0482009-09-30 16:55:274485 webview()->setPageEncoding(WebString::fromUTF8(encoding_name));
initial.commit09911bf2008-07-26 23:55:294486}
4487
[email protected]a697f4c2009-09-14 22:30:184488void RenderView::OnResetPageEncodingToDefault() {
[email protected]26aa0482009-09-30 16:55:274489 WebString no_encoding;
4490 webview()->setPageEncoding(no_encoding);
[email protected]a697f4c2009-09-14 22:30:184491}
4492
[email protected]20ad2692009-11-20 18:27:204493bool RenderView::GetAllChildFrames(
4494 WebFrame* parent_frame,
4495 std::vector<WebFrame*>* frames_vector) const {
4496 if (!parent_frame)
4497 return false;
4498 for (WebFrame* child_frame = parent_frame->firstChild(); child_frame;
4499 child_frame = child_frame->nextSibling()) {
4500 frames_vector->push_back(child_frame);
4501 GetAllChildFrames(child_frame, frames_vector);
4502 }
4503 return true;
4504}
4505
[email protected]dd7daa82009-08-10 05:46:454506WebFrame* RenderView::GetChildFrame(const std::wstring& xpath) const {
4507 if (xpath.empty())
[email protected]26aa0482009-09-30 16:55:274508 return webview()->mainFrame();
[email protected]dd7daa82009-08-10 05:46:454509
4510 // xpath string can represent a frame deep down the tree (across multiple
4511 // frame DOMs).
4512 // Example, /html/body/table/tbody/tr/td/iframe\n/frameset/frame[0]
4513 // should break into 2 xpaths
4514 // /html/body/table/tbody/tr/td/iframe & /frameset/frame[0]
4515
[email protected]26aa0482009-09-30 16:55:274516 WebFrame* frame = webview()->mainFrame();
[email protected]dd7daa82009-08-10 05:46:454517
4518 std::wstring xpath_remaining = xpath;
4519 while (!xpath_remaining.empty()) {
4520 std::wstring::size_type delim_pos = xpath_remaining.find_first_of(L'\n');
4521 std::wstring xpath_child;
4522 if (delim_pos != std::wstring::npos) {
4523 xpath_child = xpath_remaining.substr(0, delim_pos);
4524 xpath_remaining.erase(0, delim_pos + 1);
4525 } else {
4526 xpath_remaining.swap(xpath_child);
4527 }
4528 frame = frame->findChildByExpression(WideToUTF16Hack(xpath_child));
initial.commit09911bf2008-07-26 23:55:294529 }
4530
[email protected]dd7daa82009-08-10 05:46:454531 return frame;
initial.commit09911bf2008-07-26 23:55:294532}
4533
[email protected]13a1e4c3c2011-02-03 21:07:094534WebNode RenderView::GetFocusedNode() const {
4535 if (!webview())
4536 return WebNode();
4537 WebFrame* focused_frame = webview()->focusedFrame();
4538 if (focused_frame) {
4539 WebDocument doc = focused_frame->document();
4540 if (!doc.isNull())
4541 return doc.focusedNode();
4542 }
4543
4544 return WebNode();
4545}
4546
[email protected]882b7b22010-10-05 03:34:534547void RenderView::EvaluateScript(const string16& frame_xpath,
4548 const string16& script,
4549 int id,
4550 bool notify_result) {
4551 v8::Handle<v8::Value> result;
4552 WebFrame* web_frame = GetChildFrame(UTF16ToWideHack(frame_xpath));
4553 if (web_frame)
4554 result = web_frame->executeScriptAndReturnValue(WebScriptSource(script));
4555 if (notify_result) {
[email protected]81f9fe0b2010-12-07 00:35:294556 ListValue list;
4557 if (web_frame) {
4558 v8::HandleScope handle_scope;
4559 v8::Local<v8::Context> context = web_frame->mainWorldScriptContext();
4560 v8::Context::Scope context_scope(context);
4561 list.Set(0, ConvertV8Value(result));
4562 } else {
4563 list.Set(0, Value::CreateNullValue());
4564 }
4565 Send(new ViewHostMsg_ScriptEvalResponse(routing_id_, id, list));
[email protected]882b7b22010-10-05 03:34:534566 }
initial.commit09911bf2008-07-26 23:55:294567}
4568
[email protected]1810e132009-03-24 23:35:484569void RenderView::InsertCSS(const std::wstring& frame_xpath,
[email protected]ffaef0c2009-09-15 17:08:084570 const std::string& css,
4571 const std::string& id) {
[email protected]1810e132009-03-24 23:35:484572 WebFrame* web_frame = GetChildFrame(frame_xpath);
4573 if (!web_frame)
4574 return;
4575
[email protected]ffaef0c2009-09-15 17:08:084576 web_frame->insertStyleText(WebString::fromUTF8(css), WebString::fromUTF8(id));
[email protected]1810e132009-03-24 23:35:484577}
4578
[email protected]00c39612010-03-06 02:53:284579void RenderView::OnPepperPluginDestroy(
4580 WebPluginDelegatePepper* pepper_plugin) {
4581 std::set<WebPluginDelegatePepper*>::iterator found_pepper =
[email protected]53900d52010-06-16 04:25:014582 current_oldstyle_pepper_plugins_.find(pepper_plugin);
4583 if (found_pepper == current_oldstyle_pepper_plugins_.end()) {
[email protected]00c39612010-03-06 02:53:284584 NOTREACHED();
4585 return;
4586 }
[email protected]53900d52010-06-16 04:25:014587 current_oldstyle_pepper_plugins_.erase(found_pepper);
[email protected]cdaf8d02010-03-30 19:52:474588
4589 // The plugin could have been destroyed while it was waiting for a file
4590 // choose callback, so check all pending completion callbacks and NULL them.
4591 for (std::deque< linked_ptr<PendingFileChooser> >::iterator i =
4592 file_chooser_completions_.begin();
4593 i != file_chooser_completions_.end(); /* nothing */) {
4594 if ((*i)->completion == pepper_plugin) {
4595 // We NULL the first one instead of deleting it because the plugin might
4596 // be the one waiting for a file choose callback. If the callback later
4597 // comes, we don't want to send the result to the next callback in line.
4598 if (i == file_chooser_completions_.begin())
4599 (*i)->completion = NULL;
4600 else
4601 i = file_chooser_completions_.erase(i);
4602 } else {
4603 ++i;
4604 }
4605 }
[email protected]00c39612010-03-06 02:53:284606}
4607
[email protected]882b7b22010-10-05 03:34:534608void RenderView::OnScriptEvalRequest(const string16& frame_xpath,
4609 const string16& jscript,
4610 int id,
4611 bool notify_result) {
4612 EvaluateScript(frame_xpath, jscript, id, notify_result);
initial.commit09911bf2008-07-26 23:55:294613}
4614
[email protected]1810e132009-03-24 23:35:484615void RenderView::OnCSSInsertRequest(const std::wstring& frame_xpath,
[email protected]ffaef0c2009-09-15 17:08:084616 const std::string& css,
4617 const std::string& id) {
4618 InsertCSS(frame_xpath, css, id);
[email protected]ae461542009-06-19 19:03:414619
4620 // Notify RenderViewHost that css has been inserted into the frame.
4621 Send(new ViewHostMsg_OnCSSInserted(routing_id_));
[email protected]1810e132009-03-24 23:35:484622}
4623
[email protected]7ea066a2009-04-06 20:21:594624void RenderView::OnAddMessageToConsole(
4625 const string16& frame_xpath,
4626 const string16& message,
4627 const WebConsoleMessage::Level& level) {
4628 WebFrame* web_frame = GetChildFrame(UTF16ToWideHack(frame_xpath));
[email protected]0dea3ea2009-03-31 23:30:594629 if (web_frame)
[email protected]dd7daa82009-08-10 05:46:454630 web_frame->addMessageToConsole(WebConsoleMessage(level, message));
initial.commit09911bf2008-07-26 23:55:294631}
4632
[email protected]81e63782009-02-27 19:35:094633void RenderView::OnAllowBindings(int enabled_bindings_flags) {
4634 enabled_bindings_ |= enabled_bindings_flags;
initial.commit09911bf2008-07-26 23:55:294635}
4636
[email protected]d0980792011-02-13 19:41:404637void RenderView::OnSetWebUIProperty(const std::string& name,
initial.commit09911bf2008-07-26 23:55:294638 const std::string& value) {
[email protected]c09163a2011-02-15 00:05:554639 DCHECK(BindingsPolicy::is_web_ui_enabled(enabled_bindings_));
[email protected]c50008512011-02-03 01:17:274640 GetWebUIBindings()->SetProperty(name, value);
initial.commit09911bf2008-07-26 23:55:294641}
4642
4643void RenderView::OnReservePageIDRange(int size_of_range) {
4644 next_page_id_ += size_of_range + 1;
4645}
4646
[email protected]e80c73b2009-04-07 23:24:584647void RenderView::OnDragSourceEndedOrMoved(const gfx::Point& client_point,
4648 const gfx::Point& screen_point,
[email protected]1d9f4132009-09-08 17:29:254649 bool ended,
4650 WebDragOperation op) {
[email protected]5f9ae6c2009-07-08 02:38:034651 if (ended) {
[email protected]26aa0482009-09-30 16:55:274652 webview()->dragSourceEndedAt(client_point, screen_point, op);
[email protected]daec5d62010-06-04 09:14:204653 } else {
4654 webview()->dragSourceMovedTo(client_point, screen_point, op);
[email protected]5f9ae6c2009-07-08 02:38:034655 }
initial.commit09911bf2008-07-26 23:55:294656}
4657
4658void RenderView::OnDragSourceSystemDragEnded() {
[email protected]26aa0482009-09-30 16:55:274659 webview()->dragSourceSystemDragEnded();
initial.commit09911bf2008-07-26 23:55:294660}
4661
initial.commit09911bf2008-07-26 23:55:294662void RenderView::OnDragTargetDragEnter(const WebDropData& drop_data,
[email protected]e80c73b2009-04-07 23:24:584663 const gfx::Point& client_point,
[email protected]1d9f4132009-09-08 17:29:254664 const gfx::Point& screen_point,
4665 WebDragOperationsMask ops) {
[email protected]26aa0482009-09-30 16:55:274666 WebDragOperation operation = webview()->dragTargetDragEnter(
[email protected]e80c73b2009-04-07 23:24:584667 drop_data.ToDragData(),
4668 drop_data.identity,
4669 client_point,
[email protected]1d9f4132009-09-08 17:29:254670 screen_point,
4671 ops);
initial.commit09911bf2008-07-26 23:55:294672
[email protected]1d9f4132009-09-08 17:29:254673 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, operation));
initial.commit09911bf2008-07-26 23:55:294674}
4675
[email protected]e80c73b2009-04-07 23:24:584676void RenderView::OnDragTargetDragOver(const gfx::Point& client_point,
[email protected]1d9f4132009-09-08 17:29:254677 const gfx::Point& screen_point,
4678 WebDragOperationsMask ops) {
[email protected]26aa0482009-09-30 16:55:274679 WebDragOperation operation = webview()->dragTargetDragOver(
[email protected]1d9f4132009-09-08 17:29:254680 client_point,
4681 screen_point,
4682 ops);
initial.commit09911bf2008-07-26 23:55:294683
[email protected]1d9f4132009-09-08 17:29:254684 Send(new ViewHostMsg_UpdateDragCursor(routing_id_, operation));
initial.commit09911bf2008-07-26 23:55:294685}
4686
4687void RenderView::OnDragTargetDragLeave() {
[email protected]26aa0482009-09-30 16:55:274688 webview()->dragTargetDragLeave();
initial.commit09911bf2008-07-26 23:55:294689}
4690
[email protected]e80c73b2009-04-07 23:24:584691void RenderView::OnDragTargetDrop(const gfx::Point& client_point,
4692 const gfx::Point& screen_point) {
[email protected]26aa0482009-09-30 16:55:274693 webview()->dragTargetDrop(client_point, screen_point);
initial.commit09911bf2008-07-26 23:55:294694}
4695
4696void RenderView::OnUpdateWebPreferences(const WebPreferences& prefs) {
[email protected]2fab253a2009-08-17 23:00:594697 webkit_preferences_ = prefs;
4698 webkit_preferences_.Apply(webview());
initial.commit09911bf2008-07-26 23:55:294699}
4700
4701void RenderView::OnSetAltErrorPageURL(const GURL& url) {
4702 alternate_error_page_url_ = url;
4703}
4704
[email protected]b29aa74b2011-01-31 21:41:084705void RenderView::OnCustomContextMenuAction(
4706 const webkit_glue::CustomContextMenuContext& custom_context,
4707 unsigned action) {
4708 if (custom_context.is_pepper_menu)
4709 pepper_delegate_.OnCustomContextMenuAction(custom_context, action);
4710 else
4711 webview()->performCustomContextMenuAction(action);
[email protected]a0c7153e2009-12-09 14:36:334712}
4713
initial.commit09911bf2008-07-26 23:55:294714void RenderView::OnInstallMissingPlugin() {
4715 // This could happen when the first default plugin is deleted.
[email protected]f103ab72009-09-02 17:10:594716 if (first_default_plugin_)
4717 first_default_plugin_->InstallMissingPlugin();
initial.commit09911bf2008-07-26 23:55:294718}
4719
[email protected]90dba072011-01-20 20:10:204720void RenderView::OnDisplayPrerenderedPage() {
[email protected]987d51af2011-02-24 17:50:184721 DCHECK(is_prerendering_);
4722 is_prerendering_ = false;
[email protected]90dba072011-01-20 20:10:204723
[email protected]987d51af2011-02-24 17:50:184724 // Update NavigationState for histograms.
4725 WebDataSource* ds = webview()->mainFrame()->dataSource();
4726 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
[email protected]e0b181752011-02-13 23:56:434727 navigation_state->set_prerendered_page_display_time(Time::Now());
[email protected]987d51af2011-02-24 17:50:184728
4729 // If there is a provisional data source, update its NavigationState, too.
4730 WebDataSource* provisional_ds =
4731 webview()->mainFrame()->provisionalDataSource();
4732 if (provisional_ds) {
4733 NavigationState* provisional_navigation_state =
4734 NavigationState::FromDataSource(provisional_ds);
4735 if (provisional_navigation_state) {
4736 provisional_navigation_state->set_prerendered_page_display_time(
4737 Time::Now());
4738 }
4739 }
[email protected]90dba072011-01-20 20:10:204740}
4741
[email protected]cdaf8d02010-03-30 19:52:474742void RenderView::OnFileChooserResponse(const std::vector<FilePath>& paths) {
[email protected]8029f5672009-03-20 22:33:364743 // This could happen if we navigated to a different page before the user
4744 // closed the chooser.
[email protected]cdaf8d02010-03-30 19:52:474745 if (file_chooser_completions_.empty())
[email protected]8029f5672009-03-20 22:33:364746 return;
4747
[email protected]cdaf8d02010-03-30 19:52:474748 WebVector<WebString> ws_file_names(paths.size());
4749 for (size_t i = 0; i < paths.size(); ++i)
4750 ws_file_names[i] = webkit_glue::FilePathToWebString(paths[i]);
[email protected]a1128322009-10-06 18:38:464751
[email protected]cdaf8d02010-03-30 19:52:474752 if (file_chooser_completions_.front()->completion)
4753 file_chooser_completions_.front()->completion->didChooseFile(ws_file_names);
4754 file_chooser_completions_.pop_front();
4755
4756 // If there are more pending file chooser requests, schedule one now.
4757 if (!file_chooser_completions_.empty()) {
4758 Send(new ViewHostMsg_RunFileChooser(routing_id_,
4759 file_chooser_completions_.front()->params));
4760 }
initial.commit09911bf2008-07-26 23:55:294761}
4762
4763void RenderView::OnEnableViewSourceMode() {
4764 if (!webview())
4765 return;
[email protected]26aa0482009-09-30 16:55:274766 WebFrame* main_frame = webview()->mainFrame();
initial.commit09911bf2008-07-26 23:55:294767 if (!main_frame)
4768 return;
4769
[email protected]dd7daa82009-08-10 05:46:454770 main_frame->enableViewSourceMode(true);
initial.commit09911bf2008-07-26 23:55:294771}
4772
[email protected]770dd8b2010-05-24 18:11:394773void RenderView::OnEnablePreferredSizeChangedMode(int flags) {
4774 DCHECK(flags != kPreferredSizeNothing);
[email protected]9fb325e2010-05-06 18:23:244775 if (send_preferred_size_changes_)
4776 return;
[email protected]9fb325e2010-05-06 18:23:244777 send_preferred_size_changes_ = true;
[email protected]770dd8b2010-05-24 18:11:394778
4779 // WebKit doesn't send a notification of the effective height of the page
4780 // changes, so poll for it.
4781 // TODO: Add a notification for this to WebKit, remove polling. After that's
4782 // done, rename kPreferredSizeHeightThisIsSlow to kPreferredSizeHeight.
4783 // http://crbug.com/44850
4784 if (flags & kPreferredSizeHeightThisIsSlow) {
4785 preferred_size_change_timer_.Start(TimeDelta::FromMilliseconds(10), this,
4786 &RenderView::CheckPreferredSize);
4787 }
[email protected]0666aef2009-05-13 19:48:084788}
4789
[email protected]cda45c02010-02-25 19:28:104790void RenderView::OnDisableScrollbarsForSmallWindows(
4791 const gfx::Size& disable_scrollbar_size_limit) {
4792 disable_scrollbars_size_limit_ = disable_scrollbar_size_limit;
4793}
4794
[email protected]80d96fa2009-06-10 22:34:514795void RenderView::OnSetRendererPrefs(const RendererPreferences& renderer_prefs) {
4796 renderer_preferences_ = renderer_prefs;
[email protected]6e282c92009-07-24 01:19:374797 UpdateFontRenderingFromRendererPrefs();
[email protected]0dd6f9b52010-10-14 16:39:134798#if defined(TOOLKIT_USES_GTK)
[email protected]1c83eb42009-09-11 21:08:414799 WebColorName name = WebKit::WebColorWebkitFocusRingColor;
4800 WebKit::setNamedColors(&name, &renderer_prefs.focus_ring_color, 1);
[email protected]39cd64ed2010-02-05 02:18:464801 WebKit::setCaretBlinkInterval(renderer_prefs.caret_blink_interval);
[email protected]8d1b864d12010-10-10 00:04:344802 gfx::NativeThemeLinux::instance()->SetScrollbarColors(
4803 renderer_prefs.thumb_inactive_color,
4804 renderer_prefs.thumb_active_color,
4805 renderer_prefs.track_color);
[email protected]93623c5d2009-12-10 21:40:324806
[email protected]644d77e2010-01-27 01:03:104807 if (webview()) {
[email protected]93623c5d2009-12-10 21:40:324808 webview()->setScrollbarColors(
4809 renderer_prefs.thumb_inactive_color,
4810 renderer_prefs.thumb_active_color,
4811 renderer_prefs.track_color);
[email protected]644d77e2010-01-27 01:03:104812 webview()->setSelectionColors(
4813 renderer_prefs.active_selection_bg_color,
4814 renderer_prefs.active_selection_fg_color,
4815 renderer_prefs.inactive_selection_bg_color,
4816 renderer_prefs.inactive_selection_fg_color);
[email protected]f98d7e3c2010-09-13 22:30:464817 webview()->themeChanged();
[email protected]644d77e2010-01-27 01:03:104818 }
[email protected]7a74e102009-09-03 00:16:564819#endif
[email protected]80d96fa2009-06-10 22:34:514820}
4821
[email protected]952cb702009-10-07 05:50:284822void RenderView::OnMediaPlayerActionAt(const gfx::Point& location,
4823 const WebMediaPlayerAction& action) {
4824 if (webview())
4825 webview()->performMediaPlayerAction(action, location);
[email protected]581b87eb2009-07-23 23:06:564826}
4827
[email protected]7b291f92009-08-14 05:43:534828void RenderView::OnNotifyRendererViewType(ViewType::Type type) {
4829 view_type_ = type;
4830}
4831
4832void RenderView::OnUpdateBrowserWindowId(int window_id) {
4833 browser_window_id_ = window_id;
4834}
4835
[email protected]dea2d372010-09-25 06:41:144836void RenderView::OnEnableAccessibility() {
4837 if (WebAccessibilityCache::accessibilityEnabled())
4838 return;
[email protected]9f4db512010-05-10 20:21:414839
[email protected]dea2d372010-09-25 06:41:144840 WebAccessibilityCache::enableAccessibility();
4841
4842 if (webview()) {
4843 // It's possible that the webview has already loaded a webpage without
4844 // accessibility being enabled. Initialize the browser's cached
4845 // accessibility tree by sending it a 'load complete' notification.
4846 postAccessibilityNotification(
4847 webview()->accessibilityObject(),
4848 WebKit::WebAccessibilityNotificationLoadComplete);
4849 }
[email protected]266eb6f2008-09-30 23:56:504850}
4851
[email protected]aef92842010-05-21 16:54:364852void RenderView::OnSetAccessibilityFocus(int acc_obj_id) {
4853 if (!accessibility_.get())
4854 return;
[email protected]02ea2f312010-09-27 17:03:364855
4856 WebAccessibilityObject obj = accessibility_->getObjectById(acc_obj_id);
4857 WebAccessibilityObject root = webview()->accessibilityObject();
4858 if (!obj.isValid() || !root.isValid())
4859 return;
4860
4861 // By convention, calling SetFocus on the root of the tree should clear the
4862 // current focus. Otherwise set the focus to the new node.
4863 if (accessibility_->addOrGetId(obj) == accessibility_->addOrGetId(root))
4864 webview()->clearFocusedNode();
4865 else
4866 obj.setFocused(true);
[email protected]aef92842010-05-21 16:54:364867}
4868
4869void RenderView::OnAccessibilityDoDefaultAction(int acc_obj_id) {
4870 if (!accessibility_.get())
4871 return;
[email protected]02ea2f312010-09-27 17:03:364872
4873 WebAccessibilityObject obj = accessibility_->getObjectById(acc_obj_id);
4874 if (!obj.isValid())
4875 return;
4876
4877 obj.performDefaultAction();
[email protected]aef92842010-05-21 16:54:364878}
4879
[email protected]9892b472010-09-16 00:23:424880void RenderView::OnAccessibilityNotificationsAck() {
[email protected]54ec7f82010-10-21 22:32:514881 DCHECK(accessibility_ack_pending_);
4882 accessibility_ack_pending_ = false;
4883 SendPendingAccessibilityNotifications();
[email protected]520cb7d72010-08-31 11:54:314884}
4885
initial.commit09911bf2008-07-26 23:55:294886void RenderView::OnGetAllSavableResourceLinksForCurrentPage(
4887 const GURL& page_url) {
4888 // Prepare list to storage all savable resource links.
4889 std::vector<GURL> resources_list;
4890 std::vector<GURL> referrers_list;
4891 std::vector<GURL> frames_list;
4892 webkit_glue::SavableResourcesResult result(&resources_list,
4893 &referrers_list,
4894 &frames_list);
4895
[email protected]dbeb3952009-10-13 18:01:184896 if (!webkit_glue::GetAllSavableResourceLinksForCurrentPage(
4897 webview(),
4898 page_url,
4899 &result,
4900 chrome::kSavableSchemes)) {
initial.commit09911bf2008-07-26 23:55:294901 // If something is wrong when collecting all savable resource links,
4902 // send empty list to embedder(browser) to tell it failed.
4903 referrers_list.clear();
4904 resources_list.clear();
4905 frames_list.clear();
4906 }
4907
4908 // Send result of all savable resource links to embedder.
4909 Send(new ViewHostMsg_SendCurrentPageAllSavableResourceLinks(routing_id_,
4910 resources_list,
4911 referrers_list,
4912 frames_list));
4913}
4914
4915void RenderView::OnGetSerializedHtmlDataForCurrentPageWithLocalLinks(
[email protected]f6b48532009-02-12 01:56:324916 const std::vector<GURL>& links,
[email protected]fde6714d12009-02-18 22:39:314917 const std::vector<FilePath>& local_paths,
4918 const FilePath& local_directory_name) {
[email protected]d9ec5c0f2009-12-23 11:55:074919
4920 // Convert std::vector of GURLs to WebVector<WebURL>
4921 WebVector<WebURL> weburl_links(links);
4922
4923 // Convert std::vector of std::strings to WebVector<WebString>
4924 WebVector<WebString> webstring_paths(local_paths.size());
4925 for (size_t i = 0; i < local_paths.size(); i++)
4926 webstring_paths[i] = webkit_glue::FilePathToWebString(local_paths[i]);
4927
4928 WebPageSerializer::serialize(webview()->mainFrame(),
4929 true, this, weburl_links, webstring_paths,
4930 webkit_glue::FilePathToWebString(
4931 local_directory_name));
initial.commit09911bf2008-07-26 23:55:294932}
4933
[email protected]d9ec5c0f2009-12-23 11:55:074934void RenderView::didSerializeDataForFrame(const WebURL& frame_url,
4935 const WebCString& data,
4936 WebPageSerializerClient::PageSerializationStatus status) {
4937 Send(new ViewHostMsg_SendSerializedHtmlData(
4938 routing_id_,
4939 frame_url,
4940 data.data(),
4941 static_cast<int32>(status)));
initial.commit09911bf2008-07-26 23:55:294942}
4943
[email protected]9b18a84f2010-06-10 15:54:044944void RenderView::OnShouldClose() {
[email protected]26aa0482009-09-30 16:55:274945 bool should_close = webview()->dispatchBeforeUnloadEvent();
[email protected]04b4a6c2008-08-02 00:44:474946 Send(new ViewHostMsg_ShouldClose_ACK(routing_id_, should_close));
initial.commit09911bf2008-07-26 23:55:294947}
4948
[email protected]eb6b87a2009-07-24 15:57:394949void RenderView::OnClosePage(const ViewMsg_ClosePage_Params& params) {
initial.commit09911bf2008-07-26 23:55:294950 // TODO(creis): We'd rather use webview()->Close() here, but that currently
4951 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs
4952 // in the onunload handler from appearing. For now, we're bypassing that and
4953 // calling the FrameLoader's CloseURL method directly. This should be
4954 // revisited to avoid having two ways to close a page. Having a single way
4955 // to close that can run onunload is also useful for fixing
4956 // http://b/issue?id=753080.
[email protected]a5a65ac2010-11-05 18:14:364957 // TODO(davemoore) This code should be removed once willClose() gets
4958 // called when a page is destroyed. page_load_histograms_.Dump() is safe
4959 // to call multiple times for the same frame, but it will simplify things.
4960 page_load_histograms_.Dump(webview()->mainFrame());
4961 page_load_histograms_.ResetCrossFramePropertyAccess();
[email protected]26aa0482009-09-30 16:55:274962 webview()->dispatchUnloadEvent();
initial.commit09911bf2008-07-26 23:55:294963
[email protected]eb6b87a2009-07-24 15:57:394964 // Just echo back the params in the ACK.
4965 Send(new ViewHostMsg_ClosePage_ACK(routing_id_, params));
initial.commit09911bf2008-07-26 23:55:294966}
4967
4968void RenderView::OnThemeChanged() {
[email protected]6c8afae52009-01-22 02:24:574969#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:294970 gfx::NativeTheme::instance()->CloseHandles();
[email protected]f98d7e3c2010-09-13 22:30:464971 if (webview())
4972 webview()->themeChanged();
[email protected]6c8afae52009-01-22 02:24:574973#else // defined(OS_WIN)
4974 // TODO(port): we don't support theming on non-Windows platforms yet
4975 NOTIMPLEMENTED();
4976#endif
initial.commit09911bf2008-07-26 23:55:294977}
4978
[email protected]9b18a84f2010-06-10 15:54:044979void RenderView::OnHandleMessageFromExternalHost(const std::string& message,
4980 const std::string& origin,
4981 const std::string& target) {
[email protected]3ac14a052008-08-15 21:22:154982 if (message.empty())
4983 return;
[email protected]c091c2c2010-09-17 19:05:464984 GetExternalHostBindings()->ForwardMessageFromExternalHost(message, origin,
4985 target);
[email protected]3ac14a052008-08-15 21:22:154986}
4987
[email protected]0aa55312008-10-17 21:53:084988void RenderView::OnDisassociateFromPopupCount() {
4989 if (decrement_shared_popup_at_destruction_)
4990 shared_popup_counter_->data--;
4991 shared_popup_counter_ = new SharedRenderViewCounter(0);
4992 decrement_shared_popup_at_destruction_ = false;
4993}
4994
[email protected]15d79e12009-08-02 19:23:454995bool RenderView::MaybeLoadAlternateErrorPage(WebFrame* frame,
4996 const WebURLError& error,
4997 bool replace) {
4998 // We only show alternate error pages in the main frame. They are
4999 // intended to assist the user when navigating, so there is not much
5000 // value in showing them for failed subframes. Ideally, we would be
5001 // able to use the TYPED transition type for this, but that flag is
5002 // not preserved across page reloads.
[email protected]dd7daa82009-08-10 05:46:455003 if (frame->parent())
[email protected]15d79e12009-08-02 19:23:455004 return false;
5005
5006 // Use the alternate error page service if this is a DNS failure or
[email protected]c53976d52009-08-07 18:58:375007 // connection failure.
[email protected]15d79e12009-08-02 19:23:455008 int ec = error.reason;
5009 if (ec != net::ERR_NAME_NOT_RESOLVED &&
5010 ec != net::ERR_CONNECTION_FAILED &&
5011 ec != net::ERR_CONNECTION_REFUSED &&
5012 ec != net::ERR_ADDRESS_UNREACHABLE &&
[email protected]c53976d52009-08-07 18:58:375013 ec != net::ERR_CONNECTION_TIMED_OUT)
[email protected]15d79e12009-08-02 19:23:455014 return false;
5015
5016 const GURL& error_page_url = GetAlternateErrorPageURL(error.unreachableURL,
[email protected]7ccddb8c2009-08-04 17:36:555017 ec == net::ERR_NAME_NOT_RESOLVED ? DNS_ERROR : CONNECTION_ERROR);
[email protected]15d79e12009-08-02 19:23:455018 if (!error_page_url.is_valid())
5019 return false;
5020
5021 // Load an empty page first so there is an immediate response to the error,
5022 // and then kick off a request for the alternate error page.
[email protected]dd7daa82009-08-10 05:46:455023 frame->loadHTMLString(std::string(),
[email protected]144143c2010-10-28 08:17:365024 GURL(chrome::kUnreachableWebDataURL),
[email protected]15d79e12009-08-02 19:23:455025 error.unreachableURL,
5026 replace);
5027
5028 // Now, create a fetcher for the error page and associate it with the data
5029 // source we just created via the LoadHTMLString call. That way if another
5030 // navigation occurs, the fetcher will get destroyed.
5031 NavigationState* navigation_state =
[email protected]dd7daa82009-08-10 05:46:455032 NavigationState::FromDataSource(frame->provisionalDataSource());
[email protected]15d79e12009-08-02 19:23:455033 navigation_state->set_alt_error_page_fetcher(
5034 new AltErrorPageResourceFetcher(
5035 error_page_url, frame, error,
5036 NewCallback(this, &RenderView::AltErrorPageFinished)));
5037 return true;
5038}
5039
initial.commit09911bf2008-07-26 23:55:295040std::string RenderView::GetAltHTMLForTemplate(
5041 const DictionaryValue& error_strings, int template_resource_id) const {
[email protected]8a16266e2009-09-10 21:08:395042 const base::StringPiece template_html(
initial.commit09911bf2008-07-26 23:55:295043 ResourceBundle::GetSharedInstance().GetRawDataResource(
5044 template_resource_id));
5045
5046 if (template_html.empty()) {
5047 NOTREACHED() << "unable to load template. ID: " << template_resource_id;
5048 return "";
5049 }
[email protected]7cd22a52009-07-14 00:40:255050
initial.commit09911bf2008-07-26 23:55:295051 // "t" is the id of the templates root node.
[email protected]7cd22a52009-07-14 00:40:255052 return jstemplate_builder::GetTemplatesHtml(
initial.commit09911bf2008-07-26 23:55:295053 template_html, &error_strings, "t");
5054}
[email protected]0e79b9e2009-02-13 04:20:485055
[email protected]15d79e12009-08-02 19:23:455056void RenderView::AltErrorPageFinished(WebFrame* frame,
5057 const WebURLError& original_error,
5058 const std::string& html) {
5059 // Here, we replace the blank page we loaded previously.
[email protected]06333afe2011-02-24 14:55:095060 // If we failed to download the alternate error page, LoadNavigationErrorPage
[email protected]7ccddb8c2009-08-04 17:36:555061 // will simply display a default error page.
[email protected]06333afe2011-02-24 14:55:095062 LoadNavigationErrorPage(frame, WebURLRequest(), original_error, html, true);
[email protected]15d79e12009-08-02 19:23:455063}
5064
[email protected]30f75e62009-02-25 22:01:005065void RenderView::OnMoveOrResizeStarted() {
5066 if (webview())
[email protected]a72a1fa2010-05-03 22:18:475067 webview()->hidePopups();
[email protected]30f75e62009-02-25 22:01:005068}
5069
[email protected]30f75e62009-02-25 22:01:005070void RenderView::OnResize(const gfx::Size& new_size,
5071 const gfx::Rect& resizer_rect) {
[email protected]cda45c02010-02-25 19:28:105072 if (webview()) {
[email protected]a72a1fa2010-05-03 22:18:475073 webview()->hidePopups();
[email protected]cda45c02010-02-25 19:28:105074 if (send_preferred_size_changes_) {
[email protected]7339cd22010-10-27 00:11:205075 webview()->mainFrame()->setCanHaveScrollbars(
5076 should_display_scrollbars(new_size.width(), new_size.height()));
[email protected]cda45c02010-02-25 19:28:105077 }
5078 }
5079
[email protected]30f75e62009-02-25 22:01:005080 RenderWidget::OnResize(new_size, resizer_rect);
5081}
[email protected]0aa477bd2009-03-23 22:21:435082
[email protected]00c39612010-03-06 02:53:285083void RenderView::DidInitiatePaint() {
[email protected]53900d52010-06-16 04:25:015084 // Notify the pepper plugins that we started painting.
5085 pepper_delegate_.ViewInitiatedPaint();
5086
5087 // Notify any "old-style" pepper plugins that we started painting. This is
5088 // used for internal bookkeeping only, so we know that the set can not change
5089 // under us.
[email protected]00c39612010-03-06 02:53:285090 for (std::set<WebPluginDelegatePepper*>::iterator i =
[email protected]53900d52010-06-16 04:25:015091 current_oldstyle_pepper_plugins_.begin();
5092 i != current_oldstyle_pepper_plugins_.end(); ++i)
[email protected]00c39612010-03-06 02:53:285093 (*i)->RenderViewInitiatedPaint();
5094}
5095
5096void RenderView::DidFlushPaint() {
5097 // Notify any pepper plugins that we painted. This will call into the plugin,
5098 // and we it may ask to close itself as a result. This will, in turn, modify
5099 // our set, possibly invalidating the iterator. So we iterate on a copy that
5100 // won't change out from under us.
[email protected]53900d52010-06-16 04:25:015101 pepper_delegate_.ViewFlushedPaint();
5102
5103 // Notify any old-style pepper plugins that we painted. This will call into
5104 // the plugin, and we it may ask to close itself as a result. This will, in
5105 // turn, modify our set, possibly invalidating the iterator. So we iterate on
5106 // a copy that won't change out from under us.
5107 // This should be deleted when we don't support old Pepper anymore.
5108 std::set<WebPluginDelegatePepper*> plugins = current_oldstyle_pepper_plugins_;
[email protected]00c39612010-03-06 02:53:285109 for (std::set<WebPluginDelegatePepper*>::iterator i = plugins.begin();
5110 i != plugins.end(); ++i) {
5111 // The copy above makes sure our iterator is never invalid if some plugins
5112 // are destroyed. But some plugin may decide to close all of its views in
5113 // response to a paint in one of them, so we need to make sure each one is
5114 // still "current" before using it.
[email protected]53900d52010-06-16 04:25:015115 if (current_oldstyle_pepper_plugins_.find(*i) !=
5116 current_oldstyle_pepper_plugins_.end())
[email protected]00c39612010-03-06 02:53:285117 (*i)->RenderViewFlushedPaint();
5118 }
5119
5120 WebFrame* main_frame = webview()->mainFrame();
5121
5122 // If we have a provisional frame we are between the start and commit stages
5123 // of loading and we don't want to save stats.
5124 if (!main_frame->provisionalDataSource()) {
5125 WebDataSource* ds = main_frame->dataSource();
5126 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
5127 DCHECK(navigation_state);
5128
[email protected]05c8e502010-08-15 15:13:525129 // TODO(jar): The following code should all be inside a method, probably in
5130 // NavigatorState.
[email protected]00c39612010-03-06 02:53:285131 Time now = Time::Now();
5132 if (navigation_state->first_paint_time().is_null()) {
5133 navigation_state->set_first_paint_time(now);
5134 }
5135 if (navigation_state->first_paint_after_load_time().is_null() &&
5136 !navigation_state->finish_load_time().is_null()) {
5137 navigation_state->set_first_paint_after_load_time(now);
5138 }
5139 }
5140}
5141
[email protected]719b36f2010-12-22 20:36:465142webkit::ppapi::PluginInstance* RenderView::GetBitmapForOptimizedPluginPaint(
[email protected]ca4847f2010-09-24 05:39:155143 const gfx::Rect& paint_bounds,
5144 TransportDIB** dib,
5145 gfx::Rect* location,
5146 gfx::Rect* clip) {
5147 return pepper_delegate_.GetBitmapForOptimizedPluginPaint(
5148 paint_bounds, dib, location, clip);
5149}
5150
[email protected]bcaf2272011-02-15 15:29:435151gfx::Point RenderView::GetScrollOffset() {
[email protected]d54169e92011-01-21 09:19:525152 WebKit::WebSize scroll_offset = webview()->mainFrame()->scrollOffset();
[email protected]bcaf2272011-02-15 15:29:435153 return gfx::Point(scroll_offset.width, scroll_offset.height);
[email protected]d54169e92011-01-21 09:19:525154}
5155
[email protected]05d478752009-04-08 23:38:165156void RenderView::OnClearFocusedNode() {
5157 if (webview())
[email protected]26aa0482009-09-30 16:55:275158 webview()->clearFocusedNode();
[email protected]05d478752009-04-08 23:38:165159}
5160
[email protected]699ab0d2009-04-23 23:19:145161void RenderView::OnSetBackground(const SkBitmap& background) {
5162 if (webview())
[email protected]b4bb2502009-10-01 22:35:275163 webview()->setIsTransparent(!background.empty());
[email protected]699ab0d2009-04-23 23:19:145164
5165 SetBackground(background);
5166}
5167
[email protected]8c66c5a2009-07-22 17:26:345168void RenderView::OnSetActive(bool active) {
5169 if (webview())
[email protected]b4bb2502009-10-01 22:35:275170 webview()->setIsActive(active);
[email protected]d8fd6fa2010-02-01 15:54:265171
5172#if defined(OS_MACOSX)
5173 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5174 for (plugin_it = plugin_delegates_.begin();
5175 plugin_it != plugin_delegates_.end(); ++plugin_it) {
5176 (*plugin_it)->SetWindowFocus(active);
5177 }
5178#endif
[email protected]8c66c5a2009-07-22 17:26:345179}
5180
[email protected]6ce7abc52010-02-02 18:40:145181#if defined(OS_MACOSX)
5182void RenderView::OnSetWindowVisibility(bool visible) {
5183 // Inform plugins that their container has changed visibility.
5184 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5185 for (plugin_it = plugin_delegates_.begin();
5186 plugin_it != plugin_delegates_.end(); ++plugin_it) {
5187 (*plugin_it)->SetContainerVisibility(visible);
5188 }
5189}
[email protected]1e6e3c992010-02-08 15:52:135190
[email protected]4d51d5bf2010-07-26 18:48:265191void RenderView::OnWindowFrameChanged(const gfx::Rect& window_frame,
5192 const gfx::Rect& view_frame) {
[email protected]1e6e3c992010-02-08 15:52:135193 // Inform plugins that their window's frame has changed.
5194 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5195 for (plugin_it = plugin_delegates_.begin();
5196 plugin_it != plugin_delegates_.end(); ++plugin_it) {
5197 (*plugin_it)->WindowFrameChanged(window_frame, view_frame);
5198 }
5199}
[email protected]935d63d2010-10-15 23:31:555200
[email protected]b7f75862011-01-21 21:15:135201void RenderView::OnPluginImeCompositionCompleted(const string16& text,
[email protected]935d63d2010-10-15 23:31:555202 int plugin_id) {
[email protected]b7f75862011-01-21 21:15:135203 // WebPluginDelegateProxy is responsible for figuring out if this event
[email protected]935d63d2010-10-15 23:31:555204 // applies to it or not, so inform all the delegates.
5205 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5206 for (plugin_it = plugin_delegates_.begin();
5207 plugin_it != plugin_delegates_.end(); ++plugin_it) {
[email protected]b7f75862011-01-21 21:15:135208 (*plugin_it)->ImeCompositionCompleted(text, plugin_id);
[email protected]935d63d2010-10-15 23:31:555209 }
5210}
[email protected]6ce7abc52010-02-02 18:40:145211#endif // OS_MACOSX
5212
[email protected]8b8e7c92010-08-19 18:05:565213void RenderView::SendExtensionRequest(
5214 const ViewHostMsg_DomMessage_Params& params) {
5215 Send(new ViewHostMsg_ExtensionRequest(routing_id_, params));
[email protected]309d7a282009-03-24 09:18:275216}
5217
[email protected]c6619182009-05-12 14:59:325218void RenderView::OnExtensionResponse(int request_id,
5219 bool success,
5220 const std::string& response,
5221 const std::string& error) {
[email protected]0f6053962009-07-09 19:26:355222 ExtensionProcessBindings::HandleResponse(
5223 request_id, success, response, error);
[email protected]309d7a282009-03-24 09:18:275224}
[email protected]c20210e62009-04-03 21:39:265225
[email protected]a7ab1b782010-10-21 23:24:165226void RenderView::OnExtensionMessageInvoke(const std::string& extension_id,
5227 const std::string& function_name,
[email protected]d7259472010-03-24 08:40:495228 const ListValue& args,
[email protected]a807bbe2010-04-14 10:51:195229 const GURL& event_url) {
[email protected]d7259472010-03-24 08:40:495230 RendererExtensionBindings::Invoke(
[email protected]a7ab1b782010-10-21 23:24:165231 extension_id, function_name, args, this, event_url);
[email protected]7120f132009-07-20 21:05:375232}
5233
[email protected]9892b472010-09-16 00:23:425234void RenderView::postAccessibilityNotification(
5235 const WebAccessibilityObject& obj,
5236 WebAccessibilityNotification notification) {
[email protected]dea2d372010-09-25 06:41:145237 if (!accessibility_.get() && webview()) {
5238 // Load complete should be our first notification sent.
5239 // TODO(ctguil): Investigate if a different notification is a WebCore bug.
5240 if (notification != WebKit::WebAccessibilityNotificationLoadComplete)
5241 return;
5242
5243 // Create and initialize our accessibility cache
5244 accessibility_.reset(WebAccessibilityCache::create());
5245 accessibility_->initialize(webview());
5246 }
5247
[email protected]a3fa4f92010-09-30 22:19:335248 if (!accessibility_->isCached(obj)) {
5249 // The browser doesn't know about objects that are not in the cache. Send a
5250 // children change for the first accestor that actually is in the cache.
5251 WebAccessibilityObject parent = obj;
5252 while (parent.isValid() && !accessibility_->isCached(parent))
5253 parent = parent.parentObject();
5254
5255 DCHECK(parent.isValid() && accessibility_->isCached(parent));
5256 if (!parent.isValid())
5257 return;
5258 postAccessibilityNotification(
5259 parent, WebKit::WebAccessibilityNotificationChildrenChanged);
5260
5261 // The parent's children change takes care of the child's children change.
5262 if (notification == WebKit::WebAccessibilityNotificationChildrenChanged)
5263 return;
5264 }
5265
[email protected]dea2d372010-09-25 06:41:145266 // Add the accessibility object to our cache and ensure it's valid.
[email protected]54ec7f82010-10-21 22:32:515267 RendererAccessibilityNotification acc_notification;
5268 acc_notification.id = accessibility_->addOrGetId(obj);
[email protected]a527a022011-02-10 02:32:365269 acc_notification.type = notification;
[email protected]54ec7f82010-10-21 22:32:515270 if (acc_notification.id < 0)
[email protected]a3018be2010-03-09 04:28:485271 return;
5272
[email protected]a527a022011-02-10 02:32:365273 ViewHostMsg_AccessibilityNotification_Params::NotificationType temp;
5274 if (!WebAccessibilityNotificationToViewHostMsg(notification, &temp))
[email protected]54ec7f82010-10-21 22:32:515275 return;
[email protected]54ec7f82010-10-21 22:32:515276
5277 // Discard duplicate accessibility notifications.
5278 for (uint32 i = 0; i < pending_accessibility_notifications_.size(); i++) {
5279 if (pending_accessibility_notifications_[i].id == acc_notification.id &&
5280 pending_accessibility_notifications_[i].type == acc_notification.type) {
[email protected]9892b472010-09-16 00:23:425281 return;
[email protected]54ec7f82010-10-21 22:32:515282 }
[email protected]9892b472010-09-16 00:23:425283 }
[email protected]54ec7f82010-10-21 22:32:515284 pending_accessibility_notifications_.push_back(acc_notification);
[email protected]a3018be2010-03-09 04:28:485285
[email protected]54ec7f82010-10-21 22:32:515286 if (!accessibility_ack_pending_ && accessibility_method_factory_.empty()) {
5287 // When no accessibility notifications are in-flight post a task to send
5288 // the notifications to the browser. We use PostTask so that we can queue
5289 // up additional notifications.
5290 MessageLoop::current()->PostTask(
5291 FROM_HERE,
5292 accessibility_method_factory_.NewRunnableMethod(
5293 &RenderView::SendPendingAccessibilityNotifications));
[email protected]520cb7d72010-08-31 11:54:315294 }
[email protected]520cb7d72010-08-31 11:54:315295}
5296
[email protected]446705872009-09-10 07:22:485297void RenderView::OnSetEditCommandsForNextKeyEvent(
5298 const EditCommands& edit_commands) {
5299 edit_commands_ = edit_commands;
5300}
5301
[email protected]61f5a7b2009-12-22 22:21:205302void RenderView::OnExecuteCode(const ViewMsg_ExecuteCode_Params& params) {
[email protected]26aa0482009-09-30 16:55:275303 WebFrame* main_frame = webview() ? webview()->mainFrame() : NULL;
[email protected]912256b32009-09-18 09:47:355304 if (!main_frame) {
[email protected]61f5a7b2009-12-22 22:21:205305 Send(new ViewMsg_ExecuteCodeFinished(routing_id_, params.request_id,
5306 false));
[email protected]912256b32009-09-18 09:47:355307 return;
5308 }
5309
[email protected]fa7b6b542009-11-03 05:02:305310 WebDataSource* ds = main_frame->dataSource();
5311 NavigationState* navigation_state = NavigationState::FromDataSource(ds);
5312 if (!navigation_state->user_script_idle_scheduler()->has_run()) {
[email protected]61f5a7b2009-12-22 22:21:205313 pending_code_execution_queue_.push(
5314 linked_ptr<ViewMsg_ExecuteCode_Params>(
5315 new ViewMsg_ExecuteCode_Params(params)));
[email protected]fa7b6b542009-11-03 05:02:305316 return;
5317 }
5318
[email protected]61f5a7b2009-12-22 22:21:205319 ExecuteCodeImpl(main_frame, params);
[email protected]fa7b6b542009-11-03 05:02:305320}
5321
5322void RenderView::ExecuteCodeImpl(WebFrame* frame,
[email protected]61f5a7b2009-12-22 22:21:205323 const ViewMsg_ExecuteCode_Params& params) {
[email protected]20ad2692009-11-20 18:27:205324 std::vector<WebFrame*> frame_vector;
5325 frame_vector.push_back(frame);
[email protected]61f5a7b2009-12-22 22:21:205326 if (params.all_frames)
[email protected]20ad2692009-11-20 18:27:205327 GetAllChildFrames(frame, &frame_vector);
5328
5329 for (std::vector<WebFrame*>::iterator frame_it = frame_vector.begin();
5330 frame_it != frame_vector.end(); ++frame_it) {
5331 WebFrame* frame = *frame_it;
[email protected]61f5a7b2009-12-22 22:21:205332 if (params.is_javascript) {
[email protected]2a521c52011-01-26 18:45:215333 const Extension* extension =
5334 render_thread_->GetExtensions()->GetByID(params.extension_id);
[email protected]be7e5cb2010-10-04 12:53:175335
[email protected]1f6228c2010-10-21 03:19:445336 // Since extension info is sent separately from user script info, they can
5337 // be out of sync. We just ignore this situation.
5338 if (!extension)
5339 continue;
5340
[email protected]2a521c52011-01-26 18:45:215341 if (!extension->CanExecuteScriptOnPage(frame->url(), NULL, NULL))
[email protected]61f5a7b2009-12-22 22:21:205342 continue;
5343
[email protected]20ad2692009-11-20 18:27:205344 std::vector<WebScriptSource> sources;
5345 sources.push_back(
[email protected]61f5a7b2009-12-22 22:21:205346 WebScriptSource(WebString::fromUTF8(params.code)));
5347 UserScriptSlave::InsertInitExtensionCode(&sources, params.extension_id);
[email protected]20ad2692009-11-20 18:27:205348 frame->executeScriptInIsolatedWorld(
[email protected]61f5a7b2009-12-22 22:21:205349 UserScriptSlave::GetIsolatedWorldId(params.extension_id),
[email protected]20ad2692009-11-20 18:27:205350 &sources.front(), sources.size(), EXTENSION_GROUP_CONTENT_SCRIPTS);
5351 } else {
[email protected]61f5a7b2009-12-22 22:21:205352 frame->insertStyleText(WebString::fromUTF8(params.code), WebString());
[email protected]20ad2692009-11-20 18:27:205353 }
[email protected]912256b32009-09-18 09:47:355354 }
5355
[email protected]61f5a7b2009-12-22 22:21:205356 Send(new ViewMsg_ExecuteCodeFinished(routing_id_, params.request_id, true));
[email protected]912256b32009-09-18 09:47:355357}
5358
[email protected]60c42a8c72009-10-09 04:08:595359void RenderView::Close() {
5360 // We need to grab a pointer to the doomed WebView before we destroy it.
5361 WebView* doomed = webview();
5362 RenderWidget::Close();
[email protected]625332e02010-12-14 07:48:495363 g_view_map.Get().erase(doomed);
[email protected]60c42a8c72009-10-09 04:08:595364}
5365
[email protected]446705872009-09-10 07:22:485366void RenderView::DidHandleKeyEvent() {
5367 edit_commands_.clear();
5368}
5369
[email protected]6a8ddba52010-09-05 04:38:065370void RenderView::DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {
[email protected]676126f72011-01-15 00:03:515371 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidHandleMouseEvent(event));
[email protected]6a8ddba52010-09-05 04:38:065372}
5373
[email protected]941e4552010-02-01 21:23:435374void RenderView::OnWasHidden() {
5375 RenderWidget::OnWasHidden();
5376
[email protected]a6939ca42011-02-18 17:58:075377 if (webview()) {
5378 webview()->settings()->setMinimumTimerInterval(
5379 webkit_glue::kBackgroundTabTimerInterval);
5380 }
5381
5382#if defined(OS_MACOSX)
[email protected]941e4552010-02-01 21:23:435383 // Inform plugins that their container is no longer visible.
5384 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5385 for (plugin_it = plugin_delegates_.begin();
5386 plugin_it != plugin_delegates_.end(); ++plugin_it) {
5387 (*plugin_it)->SetContainerVisibility(false);
5388 }
[email protected]a6939ca42011-02-18 17:58:075389#endif // OS_MACOSX
[email protected]941e4552010-02-01 21:23:435390}
5391
5392void RenderView::OnWasRestored(bool needs_repainting) {
5393 RenderWidget::OnWasRestored(needs_repainting);
5394
[email protected]a6939ca42011-02-18 17:58:075395 if (webview()) {
5396 webview()->settings()->setMinimumTimerInterval(
5397 webkit_glue::kForegroundTabTimerInterval);
5398 }
5399
5400#if defined(OS_MACOSX)
[email protected]941e4552010-02-01 21:23:435401 // Inform plugins that their container is now visible.
5402 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5403 for (plugin_it = plugin_delegates_.begin();
5404 plugin_it != plugin_delegates_.end(); ++plugin_it) {
5405 (*plugin_it)->SetContainerVisibility(true);
5406 }
[email protected]784ea1ab2010-09-18 00:02:345407#endif // OS_MACOSX
[email protected]a6939ca42011-02-18 17:58:075408}
[email protected]1e6e3c992010-02-08 15:52:135409
5410void RenderView::OnSetFocus(bool enable) {
5411 RenderWidget::OnSetFocus(enable);
5412
[email protected]7d3c02c2010-05-05 23:10:315413 if (webview() && webview()->isActive()) {
[email protected]589621b2010-09-23 22:01:075414 // Notify all NPAPI plugins.
[email protected]1e6e3c992010-02-08 15:52:135415 std::set<WebPluginDelegateProxy*>::iterator plugin_it;
5416 for (plugin_it = plugin_delegates_.begin();
5417 plugin_it != plugin_delegates_.end(); ++plugin_it) {
[email protected]784ea1ab2010-09-18 00:02:345418#if defined(OS_MACOSX)
[email protected]7d3c02c2010-05-05 23:10:315419 // RenderWidget's call to setFocus can cause the underlying webview's
5420 // activation state to change just like a call to setIsActive.
5421 if (enable)
5422 (*plugin_it)->SetWindowFocus(true);
[email protected]784ea1ab2010-09-18 00:02:345423#endif
[email protected]7d3c02c2010-05-05 23:10:315424 (*plugin_it)->SetContentAreaFocus(enable);
[email protected]1e6e3c992010-02-08 15:52:135425 }
[email protected]589621b2010-09-23 22:01:075426
5427 // Notify all Pepper plugins.
5428 pepper_delegate_.OnSetFocus(enable);
[email protected]1e6e3c992010-02-08 15:52:135429 }
5430}
[email protected]941e4552010-02-01 21:23:435431
[email protected]83dde542009-09-11 20:59:555432void RenderView::EnsureDocumentTag() {
5433 // TODO(darin): There's actually no reason for this to be here. We should
5434 // have the browser side manage the document tag.
5435#if defined(OS_MACOSX)
5436 if (!has_document_tag_) {
5437 // Make the call to get the tag.
5438 Send(new ViewHostMsg_GetDocumentTag(routing_id_, &document_tag_));
5439 has_document_tag_ = true;
5440 }
5441#endif
5442}
[email protected]12636df2009-09-28 22:32:215443
[email protected]43f28f832010-02-03 02:28:485444#if defined(OS_MACOSX)
[email protected]b7f75862011-01-21 21:15:135445void RenderView::PluginFocusChanged(bool focused, int plugin_id) {
5446 IPC::Message* msg = new ViewHostMsg_PluginFocusChanged(routing_id(),
5447 focused, plugin_id);
5448 Send(msg);
5449}
5450
5451void RenderView::StartPluginIme() {
5452 IPC::Message* msg = new ViewHostMsg_StartPluginIme(routing_id());
[email protected]935d63d2010-10-15 23:31:555453 // This message can be sent during event-handling, and needs to be delivered
5454 // within that context.
5455 msg->set_unblock(true);
5456 Send(msg);
5457}
5458
[email protected]ea04a4e12010-04-15 00:58:035459gfx::PluginWindowHandle RenderView::AllocateFakePluginWindowHandle(
[email protected]77e74db2010-08-04 17:46:235460 bool opaque, bool root) {
[email protected]43f28f832010-02-03 02:28:485461 gfx::PluginWindowHandle window = NULL;
5462 Send(new ViewHostMsg_AllocateFakePluginWindowHandle(
[email protected]77e74db2010-08-04 17:46:235463 routing_id(), opaque, root, &window));
[email protected]c36a9b62010-10-14 00:41:115464 if (window) {
5465 fake_plugin_window_handles_.insert(window);
5466 }
[email protected]43f28f832010-02-03 02:28:485467 return window;
5468}
5469
5470void RenderView::DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window) {
[email protected]c36a9b62010-10-14 00:41:115471 if (window && fake_plugin_window_handles_.find(window) !=
5472 fake_plugin_window_handles_.end()) {
[email protected]43f28f832010-02-03 02:28:485473 Send(new ViewHostMsg_DestroyFakePluginWindowHandle(routing_id(), window));
[email protected]c36a9b62010-10-14 00:41:115474 fake_plugin_window_handles_.erase(window);
5475 }
[email protected]43f28f832010-02-03 02:28:485476}
5477
[email protected]44ce0b12010-03-12 16:45:335478void RenderView::AcceleratedSurfaceSetIOSurface(gfx::PluginWindowHandle window,
5479 int32 width,
5480 int32 height,
5481 uint64 io_surface_identifier) {
5482 Send(new ViewHostMsg_AcceleratedSurfaceSetIOSurface(
[email protected]43f28f832010-02-03 02:28:485483 routing_id(), window, width, height, io_surface_identifier));
5484}
5485
[email protected]44ce0b12010-03-12 16:45:335486void RenderView::AcceleratedSurfaceSetTransportDIB(
5487 gfx::PluginWindowHandle window,
5488 int32 width,
5489 int32 height,
5490 TransportDIB::Handle transport_dib) {
5491 Send(new ViewHostMsg_AcceleratedSurfaceSetTransportDIB(
[email protected]1aef98132010-02-23 18:00:075492 routing_id(), window, width, height, transport_dib));
5493}
5494
[email protected]44ce0b12010-03-12 16:45:335495TransportDIB::Handle RenderView::AcceleratedSurfaceAllocTransportDIB(
5496 size_t size) {
[email protected]1aef98132010-02-23 18:00:075497 TransportDIB::Handle dib_handle;
5498 // Assume this is a synchronous RPC.
[email protected]ada848b12010-04-08 22:35:385499 if (Send(new ViewHostMsg_AllocTransportDIB(size, true, &dib_handle)))
[email protected]1aef98132010-02-23 18:00:075500 return dib_handle;
5501 // Return an invalid handle if Send() fails.
5502 return TransportDIB::DefaultHandleValue();
5503}
5504
[email protected]44ce0b12010-03-12 16:45:335505void RenderView::AcceleratedSurfaceFreeTransportDIB(TransportDIB::Id dib_id) {
[email protected]1aef98132010-02-23 18:00:075506 Send(new ViewHostMsg_FreeTransportDIB(dib_id));
5507}
5508
[email protected]44ce0b12010-03-12 16:45:335509void RenderView::AcceleratedSurfaceBuffersSwapped(
[email protected]f35d6672010-10-28 21:39:145510 gfx::PluginWindowHandle window, uint64 surface_id) {
5511 Send(new ViewHostMsg_AcceleratedSurfaceBuffersSwapped(
5512 routing_id(), window, surface_id));
[email protected]43f28f832010-02-03 02:28:485513}
5514#endif
[email protected]58c321d2010-02-19 12:11:285515
[email protected]cdaf8d02010-03-30 19:52:475516bool RenderView::ScheduleFileChooser(
5517 const ViewHostMsg_RunFileChooser_Params& params,
5518 WebFileChooserCompletion* completion) {
5519 static const size_t kMaximumPendingFileChooseRequests = 4;
5520 if (file_chooser_completions_.size() > kMaximumPendingFileChooseRequests) {
5521 // This sanity check prevents too many file choose requests from getting
5522 // queued which could DoS the user. Getting these is most likely a
5523 // programming error (there are many ways to DoS the user so it's not
5524 // considered a "real" security check), either in JS requesting many file
5525 // choosers to pop up, or in a plugin.
5526 //
5527 // TODO(brettw) we might possibly want to require a user gesture to open
5528 // a file picker, which will address this issue in a better way.
5529 return false;
5530 }
5531
5532 file_chooser_completions_.push_back(linked_ptr<PendingFileChooser>(
5533 new PendingFileChooser(params, completion)));
5534 if (file_chooser_completions_.size() == 1) {
5535 // Actually show the browse dialog when this is the first request.
5536 Send(new ViewHostMsg_RunFileChooser(routing_id_, params));
5537 }
5538 return true;
5539}
5540
[email protected]290838a2010-04-27 17:37:015541void RenderView::OnPageTranslated() {
5542 WebFrame* frame = webview()->mainFrame();
5543 if (!frame)
5544 return;
5545
[email protected]676126f72011-01-15 00:03:515546 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameTranslated(frame));
[email protected]290838a2010-04-27 17:37:015547}
5548
[email protected]0ff0ff32010-12-21 19:34:425549WebKit::WebGeolocationClient* RenderView::geolocationClient() {
[email protected]676126f72011-01-15 00:03:515550 if (!geolocation_dispatcher_)
5551 geolocation_dispatcher_ = new GeolocationDispatcher(this);
5552 return geolocation_dispatcher_;
[email protected]7e0c4702010-12-31 14:06:255553}
[email protected]61c9f032010-03-31 23:04:195554
[email protected]638694c2010-08-04 22:24:115555WebKit::WebSpeechInputController* RenderView::speechInputController(
5556 WebKit::WebSpeechInputListener* listener) {
[email protected]676126f72011-01-15 00:03:515557 if (!speech_input_dispatcher_)
5558 speech_input_dispatcher_ = new SpeechInputDispatcher(this, listener);
5559 return speech_input_dispatcher_;
[email protected]638694c2010-08-04 22:24:115560}
5561
[email protected]57ead352010-08-11 14:42:535562WebKit::WebDeviceOrientationClient* RenderView::deviceOrientationClient() {
[email protected]676126f72011-01-15 00:03:515563 if (!device_orientation_dispatcher_)
5564 device_orientation_dispatcher_ = new DeviceOrientationDispatcher(this);
5565 return device_orientation_dispatcher_;
[email protected]57ead352010-08-11 14:42:535566}
5567
[email protected]b75b8292010-10-01 07:28:255568void RenderView::zoomLimitsChanged(double minimum_level, double maximum_level) {
5569 // For now, don't remember plugin zoom values. We don't want to mix them with
5570 // normal web content (i.e. a fixed layout plugin would usually want them
5571 // different).
5572 bool remember = !webview()->mainFrame()->document().isPluginDocument();
5573
[email protected]b75b8292010-10-01 07:28:255574 int minimum_percent = static_cast<int>(
5575 WebView::zoomLevelToZoomFactor(minimum_level) * 100);
5576 int maximum_percent = static_cast<int>(
5577 WebView::zoomLevelToZoomFactor(maximum_level) * 100);
[email protected]b75b8292010-10-01 07:28:255578
5579 Send(new ViewHostMsg_UpdateZoomLimits(
5580 routing_id_, minimum_percent, maximum_percent, remember));
5581}
5582
5583void RenderView::zoomLevelChanged() {
5584 bool remember = !webview()->mainFrame()->document().isPluginDocument();
5585
[email protected]b75b8292010-10-01 07:28:255586 // Tell the browser which url got zoomed so it can update the menu and the
5587 // saved values if necessary
5588 Send(new ViewHostMsg_DidZoomURL(
[email protected]1cc58eb62010-10-01 22:38:415589 routing_id_, webview()->zoomLevel(), remember,
5590 GURL(webview()->mainFrame()->url())));
[email protected]b75b8292010-10-01 07:28:255591}
5592
[email protected]a6d36cc2011-02-23 00:39:485593void RenderView::registerProtocolHandler(const WebString& scheme,
5594 const WebString& base_url,
5595 const WebString& url,
5596 const WebString& title) {
5597 GURL base(base_url);
5598 GURL absolute_url = base.Resolve(UTF16ToUTF8(url));
5599 if (base.GetOrigin() != absolute_url.GetOrigin()) {
5600 return;
5601 }
5602 RenderThread::current()->Send(
5603 new ViewHostMsg_RegisterProtocolHandler(routing_id_,
5604 UTF16ToUTF8(scheme),
5605 absolute_url,
5606 title));
5607}
5608
[email protected]8079b362010-05-07 18:37:455609bool RenderView::IsNonLocalTopLevelNavigation(
[email protected]61c9f032010-03-31 23:04:195610 const GURL& url, WebKit::WebFrame* frame, WebKit::WebNavigationType type) {
[email protected]8079b362010-05-07 18:37:455611 // Must be a top level frame.
[email protected]61c9f032010-03-31 23:04:195612 if (frame->parent() != NULL)
5613 return false;
5614
[email protected]f0a3d0b2010-08-06 22:51:535615 // Navigations initiated within Webkit are not sent out to the external host
5616 // in the following cases.
[email protected]900eb2f12010-08-23 22:36:275617 // 1. The url scheme is not http/https
5618 // 2. There is no opener and this is not the first url being opened by this
5619 // RenderView.
5620 // 3. The origin of the url and the opener is the same in which case the
[email protected]f0a3d0b2010-08-06 22:51:535621 // opener relationship is maintained.
[email protected]f0a3d0b2010-08-06 22:51:535622 // 4. Reloads/form submits/back forward navigations
5623 if (!url.SchemeIs("http") && !url.SchemeIs("https"))
5624 return false;
5625
[email protected]2fc22d12010-12-02 23:08:165626 // Not interested in reloads/form submits/resubmits/back forward navigations.
[email protected]d0ed50d2010-06-22 01:01:325627 if (type != WebKit::WebNavigationTypeReload &&
[email protected]070c49c2010-07-13 22:22:015628 type != WebKit::WebNavigationTypeFormSubmitted &&
[email protected]2fc22d12010-12-02 23:08:165629 type != WebKit::WebNavigationTypeFormResubmitted &&
[email protected]070c49c2010-07-13 22:22:015630 type != WebKit::WebNavigationTypeBackForward) {
[email protected]d0ed50d2010-06-22 01:01:325631 // The opener relationship between the new window and the parent allows the
5632 // new window to script the parent and vice versa. This is not allowed if
5633 // the origins of the two domains are different. This can be treated as a
5634 // top level navigation and routed back to the host.
5635 WebKit::WebFrame* opener = frame->opener();
[email protected]900eb2f12010-08-23 22:36:275636 if (!opener) {
[email protected]fe9eb4f92010-08-27 23:16:475637 // Force link click navigations to always be routed to the host as they
5638 // may update session state on the server.
5639 if (type == WebKit::WebNavigationTypeLinkClicked)
5640 return true;
[email protected]900eb2f12010-08-23 22:36:275641 // If this is the first page being loaded by this RenderView instance then
5642 // it should stay here.
5643 if (page_id_ == -1) {
5644 return false;
5645 } else {
[email protected]d0ed50d2010-06-22 01:01:325646 return true;
[email protected]900eb2f12010-08-23 22:36:275647 }
[email protected]d0ed50d2010-06-22 01:01:325648 }
[email protected]900eb2f12010-08-23 22:36:275649
5650 if (url.GetOrigin() != GURL(opener->url()).GetOrigin())
5651 return true;
[email protected]d0ed50d2010-06-22 01:01:325652 }
[email protected]61c9f032010-03-31 23:04:195653 return false;
5654}
[email protected]2b06a992010-08-21 05:48:225655
[email protected]27a9ef32010-09-10 04:06:245656void RenderView::OnAsyncFileOpened(base::PlatformFileError error_code,
5657 IPC::PlatformFileForTransit file_for_transit,
5658 int message_id) {
5659 pepper_delegate_.OnAsyncFileOpened(
5660 error_code,
5661 IPC::PlatformFileForTransitToPlatformFile(file_for_transit),
5662 message_id);
5663}
[email protected]caf706f2010-10-26 17:54:085664
5665#if defined(OS_MACOSX)
5666void RenderView::OnSelectPopupMenuItem(int selected_index) {
[email protected]68dc3ba2010-12-06 21:43:155667 if (external_popup_menu_ == NULL) {
5668 // Crash reports from the field indicate that we can be notified with a
5669 // NULL external popup menu (we probably get notified twice).
5670 // If you hit this please file a bug against jcivelli and include the page
5671 // and steps to repro.
5672 NOTREACHED();
5673 return;
5674 }
[email protected]caf706f2010-10-26 17:54:085675 external_popup_menu_->DidSelectItem(selected_index);
5676 external_popup_menu_.reset();
5677}
5678#endif
[email protected]bb461532010-11-26 21:50:235679
5680void RenderView::AddErrorToRootConsole(const string16& message) {
5681 if (webview() && webview()->mainFrame()) {
5682 webview()->mainFrame()->addMessageToConsole(
5683 WebConsoleMessage(WebConsoleMessage::LevelError, message));
5684 }
5685}
[email protected]1b4209f2011-01-07 00:25:405686
5687#if defined(ENABLE_FLAPPER_HACKS)
5688void RenderView::OnConnectTcpACK(
5689 int request_id,
5690 IPC::PlatformFileForTransit socket_for_transit,
5691 const PP_Flash_NetAddress& local_addr,
5692 const PP_Flash_NetAddress& remote_addr) {
5693 pepper_delegate_.OnConnectTcpACK(
5694 request_id,
5695 IPC::PlatformFileForTransitToPlatformFile(socket_for_transit),
5696 local_addr,
5697 remote_addr);
5698}
5699#endif
[email protected]a6097f42011-01-10 08:50:515700
5701void RenderView::OnJavaScriptStressTestControl(int cmd, int param) {
5702 if (cmd == kJavaScriptStressTestSetStressRunType) {
5703 v8::Testing::SetStressRunType(static_cast<v8::Testing::StressType>(param));
5704 } else if (cmd == kJavaScriptStressTestPrepareStressRun) {
5705 v8::Testing::PrepareStressRun(param);
5706 }
5707}
[email protected]521b2482011-01-15 00:10:105708
[email protected]b29aa74b2011-01-31 21:41:085709void RenderView::OnContextMenuClosed(
5710 const webkit_glue::CustomContextMenuContext& custom_context) {
5711 if (custom_context.is_pepper_menu)
5712 pepper_delegate_.OnContextMenuClosed(custom_context);
5713 else
5714 context_menu_node_.reset();
[email protected]521b2482011-01-15 00:10:105715}
[email protected]232a5812011-03-04 22:42:085716
5717void RenderView::OnNetworkStateChanged(bool online) {
5718 WebNetworkStateNotifier::setOnLine(online);
5719}