summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-18 17:00:15 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-18 17:00:15 +0000
commit5e56df8fb10f7aca72c51184ea66e4d5462d31e3 (patch)
treed49606d0e1af4ec568dfa8f03c778c7ae0780d06
parentf3f4d7fc63d2e686208de341e01c559a2f0a4487 (diff)
downloadchromium_src-5e56df8fb10f7aca72c51184ea66e4d5462d31e3.zip
chromium_src-5e56df8fb10f7aca72c51184ea66e4d5462d31e3.tar.gz
chromium_src-5e56df8fb10f7aca72c51184ea66e4d5462d31e3.tar.bz2
Move the content settings code out of RenderView, since it belongs in the Chrome layer.
BUG=76793 Review URL: http://codereview.chromium.org/6873040 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81955 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/chrome_renderer.gypi2
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc9
-rw-r--r--chrome/renderer/chrome_render_process_observer.cc7
-rw-r--r--chrome/renderer/content_settings_observer.cc184
-rw-r--r--chrome/renderer/content_settings_observer.h74
-rw-r--r--chrome/renderer/content_settings_observer_browsertest.cc61
-rw-r--r--content/renderer/render_view.cc137
-rw-r--r--content/renderer/render_view.h47
-rw-r--r--content/renderer/render_view_browsertest.cc50
-rw-r--r--content/renderer/render_view_observer.cc17
-rw-r--r--content/renderer/render_view_observer.h6
11 files changed, 399 insertions, 195 deletions
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index 9bd1bac..dd3929e 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -99,6 +99,8 @@
'renderer/chrome_render_process_observer.h',
'renderer/chrome_render_view_observer.cc',
'renderer/chrome_render_view_observer.h',
+ 'renderer/content_settings_observer.cc',
+ 'renderer/content_settings_observer.h',
'renderer/devtools_agent.cc',
'renderer/devtools_agent.h',
'renderer/devtools_agent_filter.cc',
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 1bdf1b5..76bd2da 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -30,6 +30,7 @@
#include "chrome/renderer/blocked_plugin.h"
#include "chrome/renderer/chrome_render_process_observer.h"
#include "chrome/renderer/chrome_render_view_observer.h"
+#include "chrome/renderer/content_settings_observer.h"
#include "chrome/renderer/devtools_agent.h"
#include "chrome/renderer/devtools_agent_filter.h"
#include "chrome/renderer/extensions/bindings_utils.h"
@@ -281,6 +282,7 @@ void ChromeContentRendererClient::RenderViewCreated(RenderView* render_view) {
}
#endif
+ new ContentSettingsObserver(render_view);
new DevToolsAgent(render_view);
new ExtensionHelper(render_view, extension_dispatcher_.get());
new PageLoadHistograms(render_view, histogram_snapshots_.get());
@@ -381,8 +383,9 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
}
}
- ContentSetting host_setting = render_view->current_content_settings_.
- settings[CONTENT_SETTINGS_TYPE_PLUGINS];
+ ContentSettingsObserver* observer = ContentSettingsObserver::Get(render_view);
+ ContentSetting host_setting =
+ observer->GetContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS);
if (group->RequiresAuthorization() &&
!cmd->HasSwitch(switches::kAlwaysAuthorizePlugins) &&
@@ -425,7 +428,7 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
std::string resource;
if (cmd->HasSwitch(switches::kEnableResourceContentSettings))
resource = group->identifier();
- render_view->DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, resource);
+ observer->DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, resource);
if (plugin_setting == CONTENT_SETTING_ASK) {
return CreatePluginPlaceholder(
render_view, frame, params, *group, IDR_CLICK_TO_PLAY_PLUGIN_HTML,
diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc
index 5a3d89a..4d7672b 100644
--- a/chrome/renderer/chrome_render_process_observer.cc
+++ b/chrome/renderer/chrome_render_process_observer.cc
@@ -12,6 +12,7 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/render_messages.h"
+#include "chrome/renderer/content_settings_observer.h"
#include "content/common/view_messages.h"
#include "content/renderer/render_thread.h"
#include "content/renderer/render_view.h"
@@ -83,8 +84,10 @@ class RenderViewContentSettingsSetter : public RenderViewVisitor {
}
virtual bool Visit(RenderView* render_view) {
- if (GURL(render_view->webview()->mainFrame()->url()) == url_)
- render_view->SetContentSettings(content_settings_);
+ if (GURL(render_view->webview()->mainFrame()->url()) == url_) {
+ ContentSettingsObserver::Get(render_view)->SetContentSettings(
+ content_settings_);
+ }
return true;
}
diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc
new file mode 100644
index 0000000..b752f9b
--- /dev/null
+++ b/chrome/renderer/content_settings_observer.cc
@@ -0,0 +1,184 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/content_settings_observer.h"
+
+#include "chrome/common/render_messages.h"
+#include "chrome/common/url_constants.h"
+#include "content/renderer/render_view.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
+
+using WebKit::WebDataSource;
+using WebKit::WebFrame;
+using WebKit::WebFrameClient;
+using WebKit::WebSecurityOrigin;
+using WebKit::WebURLRequest;
+using WebKit::WebView;
+
+namespace {
+
+// True if |frame| contains content that is white-listed for content settings.
+static bool IsWhitelistedForContentSettings(WebFrame* frame) {
+ WebSecurityOrigin origin = frame->securityOrigin();
+ if (origin.isEmpty())
+ return false; // Uninitialized document?
+
+ if (EqualsASCII(origin.protocol(), chrome::kChromeUIScheme))
+ return true; // Browser UI elements should still work.
+
+ // If the scheme is ftp: or file:, an empty file name indicates a directory
+ // listing, which requires JavaScript to function properly.
+ GURL frame_url = frame->url();
+ const char* kDirProtocols[] = { "ftp", "file" };
+ for (size_t i = 0; i < arraysize(kDirProtocols); ++i) {
+ if (EqualsASCII(origin.protocol(), kDirProtocols[i])) {
+ return frame_url.SchemeIs(kDirProtocols[i]) &&
+ frame_url.ExtractFileName().empty();
+ }
+ }
+
+ return false;
+}
+
+} // namespace
+
+ContentSettingsObserver::ContentSettingsObserver(RenderView* render_view)
+ : RenderViewObserver(render_view),
+ RenderViewObserverTracker<ContentSettingsObserver>(render_view) {
+ ClearBlockedContentSettings();
+}
+
+ContentSettingsObserver::~ContentSettingsObserver() {
+}
+
+
+void ContentSettingsObserver::SetContentSettings(
+ const ContentSettings& settings) {
+ current_content_settings_ = settings;
+}
+
+ContentSetting ContentSettingsObserver::GetContentSetting(
+ ContentSettingsType type) {
+ return current_content_settings_.settings[type];
+}
+
+void ContentSettingsObserver::DidBlockContentType(
+ ContentSettingsType settings_type,
+ const std::string& resource_identifier) {
+ if (!content_blocked_[settings_type]) {
+ content_blocked_[settings_type] = true;
+ Send(new ViewHostMsg_ContentBlocked(routing_id(), settings_type,
+ resource_identifier));
+ }
+}
+
+bool ContentSettingsObserver::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(ContentSettingsObserver, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetContentSettingsForLoadingURL,
+ OnSetContentSettingsForLoadingURL)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void ContentSettingsObserver::DidCommitProvisionalLoad(
+ WebFrame* frame, bool is_new_navigation) {
+ if (frame->parent())
+ return; // Not a top-level navigation.
+
+ WebDataSource* ds = frame->dataSource();
+ const WebURLRequest& request = ds->request();
+
+ // Clear "block" flags for the new page. This needs to happen before any of
+ // allowScripts(), allowImages(), allowPlugins() is called for the new page
+ // so that these functions can correctly detect that a piece of content
+ // flipped from "not blocked" to "blocked".
+ ClearBlockedContentSettings();
+
+ // Set content settings. Default them from the parent window if one exists.
+ // This makes sure about:blank windows work as expected.
+ HostContentSettings::iterator host_content_settings =
+ host_content_settings_.find(GURL(request.url()));
+ if (host_content_settings != host_content_settings_.end()) {
+ SetContentSettings(host_content_settings->second);
+
+ // These content settings were merely recorded transiently for this load.
+ // We can erase them now. If at some point we reload this page, the
+ // browser will send us new, up-to-date content settings.
+ host_content_settings_.erase(host_content_settings);
+ } else if (frame->opener()) {
+ // The opener's view is not guaranteed to be non-null (it could be
+ // detached from its page but not yet destructed).
+ if (WebView* opener_view = frame->opener()->view()) {
+ RenderView* opener = RenderView::FromWebView(opener_view);
+ ContentSettingsObserver* observer = ContentSettingsObserver::Get(opener);
+ SetContentSettings(observer->current_content_settings_);
+ }
+ }
+}
+
+bool ContentSettingsObserver::AllowImages(WebFrame* frame,
+ bool enabled_per_settings) {
+ if (enabled_per_settings &&
+ AllowContentType(CONTENT_SETTINGS_TYPE_IMAGES)) {
+ return true;
+ }
+
+ if (IsWhitelistedForContentSettings(frame))
+ return true;
+
+ DidBlockContentType(CONTENT_SETTINGS_TYPE_IMAGES, std::string());
+ return false; // Other protocols fall through here.
+}
+
+bool ContentSettingsObserver::AllowPlugins(WebFrame* frame,
+ bool enabled_per_settings) {
+ return render_view()->WebFrameClient::allowPlugins(
+ frame, enabled_per_settings);
+}
+
+bool ContentSettingsObserver::AllowScript(WebFrame* frame,
+ bool enabled_per_settings) {
+ if (enabled_per_settings &&
+ AllowContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT)) {
+ return true;
+ }
+
+ if (IsWhitelistedForContentSettings(frame))
+ return true;
+
+ return false; // Other protocols fall through here.
+}
+
+void ContentSettingsObserver::DidNotAllowPlugins(WebFrame* frame) {
+ DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, std::string());
+}
+
+void ContentSettingsObserver::DidNotAllowScript(WebFrame* frame) {
+ DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string());
+}
+
+void ContentSettingsObserver::OnSetContentSettingsForLoadingURL(
+ const GURL& url,
+ const ContentSettings& content_settings) {
+ host_content_settings_[url] = content_settings;
+}
+
+bool ContentSettingsObserver::AllowContentType(
+ ContentSettingsType settings_type) {
+ // CONTENT_SETTING_ASK is only valid for cookies.
+ return current_content_settings_.settings[settings_type] !=
+ CONTENT_SETTING_BLOCK;
+}
+
+void ContentSettingsObserver::ClearBlockedContentSettings() {
+ for (size_t i = 0; i < arraysize(content_blocked_); ++i)
+ content_blocked_[i] = false;
+}
diff --git a/chrome/renderer/content_settings_observer.h b/chrome/renderer/content_settings_observer.h
new file mode 100644
index 0000000..52d89f5
--- /dev/null
+++ b/chrome/renderer/content_settings_observer.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_RENDERER_CONTENT_SETTINGS_OBSERVER_H_
+#define CHROME_RENDERER_CONTENT_SETTINGS_OBSERVER_H_
+#pragma once
+
+#include <map>
+
+#include "chrome/common/content_settings.h"
+#include "content/renderer/render_view_observer.h"
+#include "content/renderer/render_view_observer_tracker.h"
+
+class GURL;
+
+// Handles blocking content per content settings for each RenderView.
+class ContentSettingsObserver
+ : public RenderViewObserver,
+ public RenderViewObserverTracker<ContentSettingsObserver> {
+ public:
+ explicit ContentSettingsObserver(RenderView* render_view);
+ virtual ~ContentSettingsObserver();
+
+ // Sets the content settings that back allowScripts(), allowImages(), and
+ // allowPlugins().
+ void SetContentSettings(const ContentSettings& settings);
+
+ // Returns the setting for the given type.
+ ContentSetting GetContentSetting(ContentSettingsType type);
+
+ // Sends an IPC notification that the specified content type was blocked.
+ // If the content type requires it, |resource_identifier| names the specific
+ // resource that was blocked (the plugin path in the case of plugins),
+ // otherwise it's the empty string.
+ void DidBlockContentType(ContentSettingsType settings_type,
+ const std::string& resource_identifier);
+
+ private:
+ // RenderViewObserver implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message);
+ virtual void DidCommitProvisionalLoad(WebKit::WebFrame* frame,
+ bool is_new_navigation);
+ virtual bool AllowImages(WebKit::WebFrame* frame, bool enabled_per_settings);
+ virtual bool AllowPlugins(WebKit::WebFrame* frame, bool enabled_per_settings);
+ virtual bool AllowScript(WebKit::WebFrame* frame, bool enabled_per_settings);
+ virtual void DidNotAllowPlugins(WebKit::WebFrame* frame);
+ virtual void DidNotAllowScript(WebKit::WebFrame* frame);
+
+ // Message handlers.
+ void OnSetContentSettingsForLoadingURL(
+ const GURL& url,
+ const ContentSettings& content_settings);
+
+ // Helper method that returns if the user wants to block content of type
+ // |content_type|.
+ bool AllowContentType(ContentSettingsType settings_type);
+
+ // Resets the |content_blocked_| array.
+ void ClearBlockedContentSettings();
+
+ typedef std::map<GURL, ContentSettings> HostContentSettings;
+ HostContentSettings host_content_settings_;
+
+ // Stores if loading of images, scripts, and plugins is allowed.
+ ContentSettings current_content_settings_;
+
+ // Stores if images, scripts, and plugins have actually been blocked.
+ bool content_blocked_[CONTENT_SETTINGS_NUM_TYPES];
+
+ DISALLOW_COPY_AND_ASSIGN(ContentSettingsObserver);
+};
+
+#endif // CHROME_RENDERER_CONTENT_SETTINGS_OBSERVER_H_
diff --git a/chrome/renderer/content_settings_observer_browsertest.cc b/chrome/renderer/content_settings_observer_browsertest.cc
new file mode 100644
index 0000000..c65592d
--- /dev/null
+++ b/chrome/renderer/content_settings_observer_browsertest.cc
@@ -0,0 +1,61 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/content_settings.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/renderer/content_settings_observer.h"
+#include "chrome/test/render_view_test.h"
+#include "content/common/view_messages.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// Regression test for http://crbug.com/35011
+TEST_F(RenderViewTest, JSBlockSentAfterPageLoad) {
+ // 1. Load page with JS.
+ std::string html = "<html>"
+ "<head>"
+ "<script>document.createElement('div');</script>"
+ "</head>"
+ "<body>"
+ "</body>"
+ "</html>";
+ render_thread_.sink().ClearMessages();
+ LoadHTML(html.c_str());
+
+ // 2. Block JavaScript.
+ ContentSettings settings;
+ for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i)
+ settings.settings[i] = CONTENT_SETTING_ALLOW;
+ settings.settings[CONTENT_SETTINGS_TYPE_JAVASCRIPT] = CONTENT_SETTING_BLOCK;
+ ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
+ observer->SetContentSettings(settings);
+
+ // Make sure no pending messages are in the queue.
+ ProcessPendingMessages();
+ render_thread_.sink().ClearMessages();
+
+ // 3. Reload page.
+ ViewMsg_Navigate_Params params;
+ std::string url_str = "data:text/html;charset=utf-8,";
+ url_str.append(html);
+ GURL url(url_str);
+ params.url = url;
+ params.navigation_type = ViewMsg_Navigate_Type::RELOAD;
+ view_->OnNavigate(params);
+ ProcessPendingMessages();
+
+ // 4. Verify that the notification that javascript was blocked is sent after
+ // the navigation notifiction is sent.
+ int navigation_index = -1;
+ int block_index = -1;
+ for (size_t i = 0; i < render_thread_.sink().message_count(); ++i) {
+ const IPC::Message* msg = render_thread_.sink().GetMessageAt(i);
+ if (msg->type() == ViewHostMsg_FrameNavigate::ID)
+ navigation_index = i;
+ if (msg->type() == ViewHostMsg_ContentBlocked::ID)
+ block_index = i;
+ }
+ EXPECT_NE(-1, navigation_index);
+ EXPECT_NE(-1, block_index);
+ EXPECT_LT(navigation_index, block_index);
+}
diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc
index 58f5cfc..a8c30e5 100644
--- a/content/renderer/render_view.cc
+++ b/content/renderer/render_view.cc
@@ -261,29 +261,6 @@ static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
result->push_back(urls[i]);
}
-// True if |frame| contains content that is white-listed for content settings.
-static bool IsWhitelistedForContentSettings(WebFrame* frame) {
- WebSecurityOrigin origin = frame->securityOrigin();
- if (origin.isEmpty())
- return false; // Uninitialized document?
-
- if (EqualsASCII(origin.protocol(), chrome::kChromeUIScheme))
- return true; // Browser UI elements should still work.
-
- // If the scheme is ftp: or file:, an empty file name indicates a directory
- // listing, which requires JavaScript to function properly.
- GURL frame_url = frame->url();
- const char* kDirProtocols[] = { "ftp", "file" };
- for (size_t i = 0; i < arraysize(kDirProtocols); ++i) {
- if (EqualsASCII(origin.protocol(), kDirProtocols[i])) {
- return frame_url.SchemeIs(kDirProtocols[i]) &&
- frame_url.ExtractFileName().empty();
- }
- }
-
- return false;
-}
-
static bool WebAccessibilityNotificationToViewHostMsg(
WebAccessibilityNotification notification,
ViewHostMsg_AccessibilityNotification_Type::Value* type) {
@@ -400,9 +377,6 @@ RenderView::RenderView(RenderThreadBase* render_thread,
accessibility_ack_pending_(false),
p2p_socket_dispatcher_(NULL),
session_storage_namespace_id_(session_storage_namespace_id) {
-
- ClearBlockedContentSettings();
-
routing_id_ = routing_id;
if (opener_id != MSG_ROUTING_NONE)
opener_id_ = opener_id;
@@ -655,8 +629,6 @@ bool RenderView::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
IPC_MESSAGE_HANDLER(ViewMsg_FindReplyACK, OnFindReplyAck)
IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
- IPC_MESSAGE_HANDLER(ViewMsg_SetContentSettingsForLoadingURL,
- OnSetContentSettingsForLoadingURL)
IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevel, OnSetZoomLevel)
IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForLoadingURL,
OnSetZoomLevelForLoadingURL)
@@ -971,10 +943,6 @@ void RenderView::OnScrollFocusedEditableNodeIntoView() {
///////////////////////////////////////////////////////////////////////////////
-void RenderView::SetContentSettings(const ContentSettings& settings) {
- current_content_settings_ = settings;
-}
-
// Tell the embedding application that the URL of the active page has changed
void RenderView::UpdateURL(WebFrame* frame) {
WebDataSource* ds = frame->dataSource();
@@ -1043,32 +1011,6 @@ void RenderView::UpdateURL(WebFrame* frame) {
if (!frame->parent()) {
// Top-level navigation.
- // Clear "block" flags for the new page. This needs to happen before any of
- // allowScripts(), allowImages(), allowPlugins() is called for the new page
- // so that these functions can correctly detect that a piece of content
- // flipped from "not blocked" to "blocked".
- ClearBlockedContentSettings();
-
- // Set content settings. Default them from the parent window if one exists.
- // This makes sure about:blank windows work as expected.
- HostContentSettings::iterator host_content_settings =
- host_content_settings_.find(GURL(request.url()));
- if (host_content_settings != host_content_settings_.end()) {
- SetContentSettings(host_content_settings->second);
-
- // These content settings were merely recorded transiently for this load.
- // We can erase them now. If at some point we reload this page, the
- // browser will send us new, up-to-date content settings.
- host_content_settings_.erase(host_content_settings);
- } else if (frame->opener()) {
- // The opener's view is not guaranteed to be non-null (it could be
- // detached from its page but not yet destructed).
- if (WebView* opener_view = frame->opener()->view()) {
- RenderView* opener = FromWebView(opener_view);
- SetContentSettings(opener->current_content_settings_);
- }
- }
-
// Set zoom level, but don't do it for full-page plugin since they don't use
// the same zoom settings.
HostZoomLevels::iterator host_zoom =
@@ -1992,22 +1934,6 @@ void RenderView::willClose(WebFrame* frame) {
FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame));
}
-bool RenderView::allowImages(WebFrame* frame, bool enabled_per_settings) {
- if (enabled_per_settings &&
- AllowContentType(CONTENT_SETTINGS_TYPE_IMAGES))
- return true;
-
- if (IsWhitelistedForContentSettings(frame))
- return true;
-
- DidBlockContentType(CONTENT_SETTINGS_TYPE_IMAGES, std::string());
- return false; // Other protocols fall through here.
-}
-
-bool RenderView::allowPlugins(WebFrame* frame, bool enabled_per_settings) {
- return WebFrameClient::allowPlugins(frame, enabled_per_settings);
-}
-
void RenderView::loadURLExternally(
WebFrame* frame, const WebURLRequest& request,
WebNavigationPolicy policy) {
@@ -2749,15 +2675,34 @@ void RenderView::didRunInsecureContent(
target));
}
-bool RenderView::allowScript(WebFrame* frame, bool enabled_per_settings) {
- if (enabled_per_settings &&
- AllowContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT))
- return true;
+bool RenderView::allowImages(WebFrame* frame, bool enabled_per_settings) {
+ ObserverListBase<RenderViewObserver>::Iterator it(observers_);
+ RenderViewObserver* observer;
+ while ((observer = it.GetNext()) != NULL)
+ if (!observer->AllowImages(frame, enabled_per_settings))
+ return false;
- if (IsWhitelistedForContentSettings(frame))
- return true;
+ return true;
+}
+
+bool RenderView::allowPlugins(WebFrame* frame, bool enabled_per_settings) {
+ ObserverListBase<RenderViewObserver>::Iterator it(observers_);
+ RenderViewObserver* observer;
+ while ((observer = it.GetNext()) != NULL)
+ if (!observer->AllowPlugins(frame, enabled_per_settings))
+ return false;
+
+ return true;
+}
- return false; // Other protocols fall through here.
+bool RenderView::allowScript(WebFrame* frame, bool enabled_per_settings) {
+ ObserverListBase<RenderViewObserver>::Iterator it(observers_);
+ RenderViewObserver* observer;
+ while ((observer = it.GetNext()) != NULL)
+ if (!observer->AllowScript(frame, enabled_per_settings))
+ return false;
+
+ return true;
}
bool RenderView::allowDatabase(
@@ -2780,11 +2725,11 @@ bool RenderView::allowDatabase(
return result;
}
void RenderView::didNotAllowScript(WebKit::WebFrame* frame) {
- DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string());
+ FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidNotAllowScript(frame));
}
void RenderView::didNotAllowPlugins(WebKit::WebFrame* frame) {
- DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, std::string());
+ FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidNotAllowPlugins(frame));
}
void RenderView::didExhaustMemoryAvailableForScript(WebFrame* frame) {
@@ -3260,26 +3205,6 @@ void RenderView::OnFindReplyAck() {
}
}
-bool RenderView::AllowContentType(ContentSettingsType settings_type) {
- // CONTENT_SETTING_ASK is only valid for cookies.
- return current_content_settings_.settings[settings_type] !=
- CONTENT_SETTING_BLOCK;
-}
-
-void RenderView::DidBlockContentType(ContentSettingsType settings_type,
- const std::string& resource_identifier) {
- if (!content_blocked_[settings_type]) {
- content_blocked_[settings_type] = true;
- Send(new ViewHostMsg_ContentBlocked(routing_id_, settings_type,
- resource_identifier));
- }
-}
-
-void RenderView::ClearBlockedContentSettings() {
- for (size_t i = 0; i < arraysize(content_blocked_); ++i)
- content_blocked_[i] = false;
-}
-
WebPlugin* RenderView::CreatePepperPlugin(
WebFrame* frame,
const WebPluginParams& params,
@@ -3340,12 +3265,6 @@ void RenderView::OnSetZoomLevel(double zoom_level) {
zoomLevelChanged();
}
-void RenderView::OnSetContentSettingsForLoadingURL(
- const GURL& url,
- const ContentSettings& content_settings) {
- host_content_settings_[url] = content_settings;
-}
-
void RenderView::OnSetZoomLevelForLoadingURL(const GURL& url,
double zoom_level) {
host_zoom_levels_[url] = zoom_level;
diff --git a/content/renderer/render_view.h b/content/renderer/render_view.h
index 8d846468..3292a37 100644
--- a/content/renderer/render_view.h
+++ b/content/renderer/render_view.h
@@ -21,7 +21,6 @@
#include "base/observer_list.h"
#include "base/timer.h"
#include "build/build_config.h"
-#include "chrome/common/content_settings.h"
#include "content/renderer/renderer_webcookiejar_impl.h"
#include "content/common/edit_command.h"
#include "content/common/navigation_gesture.h"
@@ -251,10 +250,6 @@ class RenderView : public RenderWidget,
bool ScheduleFileChooser(const ViewHostMsg_RunFileChooser_Params& params,
WebKit::WebFileChooserCompletion* completion);
- // Sets the content settings that back allowScripts(), allowImages(), and
- // allowPlugins().
- void SetContentSettings(const ContentSettings& settings);
-
// Sets whether the renderer should report load progress to the browser.
void SetReportLoadProgressEnabled(bool enabled);
@@ -446,8 +441,6 @@ class RenderView : public RenderWidget,
virtual WebKit::WebCookieJar* cookieJar(WebKit::WebFrame* frame);
virtual void frameDetached(WebKit::WebFrame* frame);
virtual void willClose(WebKit::WebFrame* frame);
- virtual bool allowImages(WebKit::WebFrame* frame, bool enabled_per_settings);
- virtual bool allowPlugins(WebKit::WebFrame* frame, bool enabled_per_settings);
virtual void loadURLExternally(WebKit::WebFrame* frame,
const WebKit::WebURLRequest& request,
WebKit::WebNavigationPolicy policy);
@@ -531,6 +524,8 @@ class RenderView : public RenderWidget,
const WebKit::WebSecurityOrigin& origin,
const WebKit::WebURL& target);
+ virtual bool allowImages(WebKit::WebFrame* frame, bool enabled_per_settings);
+ virtual bool allowPlugins(WebKit::WebFrame* frame, bool enabled_per_settings);
virtual bool allowScript(WebKit::WebFrame* frame, bool enabled_per_settings);
virtual bool allowDatabase(WebKit::WebFrame* frame,
const WebKit::WebString& name,
@@ -644,7 +639,6 @@ class RenderView : public RenderWidget,
FRIEND_TEST_ALL_PREFIXES(RenderViewTest, MacTestCmdUp);
#endif
- typedef std::map<GURL, ContentSettings> HostContentSettings;
typedef std::map<GURL, double> HostZoomLevels;
// Identifies an accessibility notification from webkit.
@@ -803,9 +797,6 @@ class RenderView : public RenderWidget,
void OnSetActive(bool active);
void OnSetAltErrorPageURL(const GURL& gurl);
void OnSetBackground(const SkBitmap& background);
- void OnSetContentSettingsForLoadingURL(
- const GURL& url,
- const ContentSettings& content_settings);
void OnSetWebUIProperty(const std::string& name, const std::string& value);
void OnSetEditCommandsForNextKeyEvent(const EditCommands& edit_commands);
void OnSetInitialFocus(bool reverse);
@@ -836,10 +827,6 @@ class RenderView : public RenderWidget,
// Misc private functions ----------------------------------------------------
- // Helper method that returns if the user wants to block content of type
- // |content_type|.
- bool AllowContentType(ContentSettingsType settings_type);
-
void AltErrorPageFinished(WebKit::WebFrame* frame,
const WebKit::WebURLError& original_error,
const std::string& html);
@@ -848,15 +835,20 @@ class RenderView : public RenderWidget,
// by preferred_size_change_timer_.
void CheckPreferredSize();
- // Resets the |content_blocked_| array.
- void ClearBlockedContentSettings();
-
- // Sends an IPC notification that the specified content type was blocked.
- // If the content type requires it, |resource_identifier| names the specific
- // resource that was blocked (the plugin path in the case of plugins),
- // otherwise it's the empty string.
- void DidBlockContentType(ContentSettingsType settings_type,
- const std::string& resource_identifier);
+ // This callback is triggered when DownloadFavicon completes, either
+ // succesfully or with a failure. See DownloadFavicon for more
+ // details.
+ void DidDownloadFavicon(webkit_glue::ImageResourceFetcher* fetcher,
+ const SkBitmap& image);
+
+ // Requests to download a favicon image. When done, the RenderView
+ // is notified by way of DidDownloadFavicon. Returns true if the
+ // request was successfully started, false otherwise. id is used to
+ // uniquely identify the request and passed back to the
+ // DidDownloadFavicon method. If the image has multiple frames, the
+ // frame whose size is image_size is returned. If the image doesn't
+ // have a frame at the specified size, the first is returned.
+ bool DownloadFavicon(int id, const GURL& image_url, int image_size);
GURL GetAlternateErrorPageURL(const GURL& failed_url,
ErrorPageType error_type);
@@ -912,7 +904,6 @@ class RenderView : public RenderWidget,
WebPreferences webkit_preferences_;
RendererPreferences renderer_preferences_;
- HostContentSettings host_content_settings_;
HostZoomLevels host_zoom_levels_;
// Whether content state (such as form state, scroll position and page
@@ -920,9 +911,6 @@ class RenderView : public RenderWidget,
// false, but set to true by some tests.
bool send_content_state_immediately_;
- // Stores if loading of images, scripts, and plugins is allowed.
- ContentSettings current_content_settings_;
-
// Bitwise-ORed set of extra bindings that have been enabled. See
// BindingsPolicy for details.
int enabled_bindings_;
@@ -967,9 +955,6 @@ class RenderView : public RenderWidget,
// It is empty if there is no top-level client-side redirect.
GURL completed_client_redirect_src_;
- // Stores if images, scripts, and plugins have actually been blocked.
- bool content_blocked_[CONTENT_SETTINGS_NUM_TYPES];
-
// Holds state pertaining to a navigation that we initiated. This is held by
// the WebDataSource::ExtraData attribute. We use pending_navigation_state_
// as a temporary holder for the state until the WebDataSource corresponding
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index afce5c3..3f8eb92 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -771,56 +771,6 @@ TEST_F(RenderViewTest, DidFailProvisionalLoadWithErrorForCancellation) {
EXPECT_TRUE(web_frame->isViewSourceModeEnabled());
}
-// Regression test for http://crbug.com/35011
-TEST_F(RenderViewTest, JSBlockSentAfterPageLoad) {
- // 1. Load page with JS.
- std::string html = "<html>"
- "<head>"
- "<script>document.createElement('div');</script>"
- "</head>"
- "<body>"
- "</body>"
- "</html>";
- render_thread_.sink().ClearMessages();
- LoadHTML(html.c_str());
-
- // 2. Block JavaScript.
- ContentSettings settings;
- for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i)
- settings.settings[i] = CONTENT_SETTING_ALLOW;
- settings.settings[CONTENT_SETTINGS_TYPE_JAVASCRIPT] = CONTENT_SETTING_BLOCK;
- view_->SetContentSettings(settings);
-
- // Make sure no pending messages are in the queue.
- ProcessPendingMessages();
- render_thread_.sink().ClearMessages();
-
- // 3. Reload page.
- ViewMsg_Navigate_Params params;
- std::string url_str = "data:text/html;charset=utf-8,";
- url_str.append(html);
- GURL url(url_str);
- params.url = url;
- params.navigation_type = ViewMsg_Navigate_Type::RELOAD;
- view_->OnNavigate(params);
- ProcessPendingMessages();
-
- // 4. Verify that the notification that javascript was blocked is sent after
- // the navigation notifiction is sent.
- int navigation_index = -1;
- int block_index = -1;
- for (size_t i = 0; i < render_thread_.sink().message_count(); ++i) {
- const IPC::Message* msg = render_thread_.sink().GetMessageAt(i);
- if (msg->type() == ViewHostMsg_FrameNavigate::ID)
- navigation_index = i;
- if (msg->type() == ViewHostMsg_ContentBlocked::ID)
- block_index = i;
- }
- EXPECT_NE(-1, navigation_index);
- EXPECT_NE(-1, block_index);
- EXPECT_LT(navigation_index, block_index);
-}
-
// Regression test for http://crbug.com/41562
TEST_F(RenderViewTest, UpdateTargetURLWithInvalidURL) {
const GURL invalid_gurl("http://");
diff --git a/content/renderer/render_view_observer.cc b/content/renderer/render_view_observer.cc
index b13f4c2..e74c503 100644
--- a/content/renderer/render_view_observer.cc
+++ b/content/renderer/render_view_observer.cc
@@ -6,6 +6,8 @@
#include "content/renderer/render_view.h"
+using WebKit::WebFrame;
+
RenderViewObserver::RenderViewObserver(RenderView* render_view)
: render_view_(render_view),
routing_id_(render_view ? render_view->routing_id() : 0) {
@@ -34,3 +36,18 @@ bool RenderViewObserver::Send(IPC::Message* message) {
delete message;
return false;
}
+
+bool RenderViewObserver::AllowImages(WebFrame* frame,
+ bool enabled_per_settings) {
+ return true;
+}
+
+bool RenderViewObserver::AllowPlugins(WebFrame* frame,
+ bool enabled_per_settings) {
+ return true;
+}
+
+bool RenderViewObserver::AllowScript(WebFrame* frame,
+ bool enabled_per_settings) {
+ return true;
+}
diff --git a/content/renderer/render_view_observer.h b/content/renderer/render_view_observer.h
index cdb0b51..a5c0130 100644
--- a/content/renderer/render_view_observer.h
+++ b/content/renderer/render_view_observer.h
@@ -66,6 +66,12 @@ class RenderViewObserver : public IPC::Channel::Listener,
const WebKit::WebString& property_name,
unsigned long long event_id) {}
virtual void FocusedNodeChanged(const WebKit::WebNode& node) {}
+ // If any observer returns false, then the request will be denied.
+ virtual bool AllowImages(WebKit::WebFrame* frame, bool enabled_per_settings);
+ virtual bool AllowPlugins(WebKit::WebFrame* frame, bool enabled_per_settings);
+ virtual bool AllowScript(WebKit::WebFrame* frame, bool enabled_per_settings);
+ virtual void DidNotAllowPlugins(WebKit::WebFrame* frame) {}
+ virtual void DidNotAllowScript(WebKit::WebFrame* frame) {}
// These match the RenderView methods.
virtual void DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {}