summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authortony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-08 05:18:06 +0000
committertony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-08 05:18:06 +0000
commit6c32ce70d1b04d1b5982a5833ced60b92cda10fb (patch)
treea42fab74398b9b4d44eecc80326385a27d3664cd /chrome
parent31e9bb2767ccded0fe3f2af5c8f105af0eb97a01 (diff)
downloadchromium_src-6c32ce70d1b04d1b5982a5833ced60b92cda10fb.zip
chromium_src-6c32ce70d1b04d1b5982a5833ced60b92cda10fb.tar.gz
chromium_src-6c32ce70d1b04d1b5982a5833ced60b92cda10fb.tar.bz2
First cut at custom user style sheets.
Enabled with the --enable-user-stylesheet flag which causes chrome to read <user-data-dir>/<profile>/User StyleSheet/Custom.css at startup and set it as the user style sheet. This version never reloads the user style sheet, I'll have to bring back FileWatcher for that. I also put the user stylesheet in a subdir because the implementation of FileWatcher will watch the parent dir (this is what the OS apis give me) and watching the profile dir will cause lots of activity. BUG=2393 Review URL: http://codereview.chromium.org/660349 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40882 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/extensions/extension_host.cc4
-rw-r--r--chrome/browser/profile.cc13
-rw-r--r--chrome/browser/profile.h6
-rw-r--r--chrome/browser/tab_contents/render_view_host_delegate_helper.cc27
-rw-r--r--chrome/browser/tab_contents/render_view_host_delegate_helper.h2
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc11
-rw-r--r--chrome/browser/user_style_sheet_watcher.cc82
-rw-r--r--chrome/browser/user_style_sheet_watcher.h57
-rw-r--r--chrome/browser/user_style_sheet_watcher_unittest.cc43
-rwxr-xr-xchrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/common/notification_type.h5
-rw-r--r--chrome/test/testing_profile.h1
15 files changed, 242 insertions, 16 deletions
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index 5c01d69..f4ee926 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -469,10 +469,10 @@ RendererPreferences ExtensionHost::GetRendererPrefs(Profile* profile) const {
}
WebPreferences ExtensionHost::GetWebkitPrefs() {
- PrefService* prefs = render_view_host()->process()->profile()->GetPrefs();
+ Profile* profile = render_view_host()->process()->profile();
const bool kIsDomUI = true;
WebPreferences webkit_prefs =
- RenderViewHostDelegateHelper::GetWebkitPrefs(prefs, kIsDomUI);
+ RenderViewHostDelegateHelper::GetWebkitPrefs(profile, kIsDomUI);
if (extension_host_type_ == ViewType::EXTENSION_POPUP)
webkit_prefs.allow_scripts_to_close_windows = true;
return webkit_prefs;
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index 1e248e2..c78b64a 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -50,6 +50,7 @@
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_factory_impl.h"
#include "chrome/browser/thumbnail_store.h"
+#include "chrome/browser/user_style_sheet_watcher.h"
#include "chrome/browser/visitedlink_master.h"
#include "chrome/browser/visitedlink_event_listener.h"
#include "chrome/browser/webdata/web_data_service.h"
@@ -410,6 +411,10 @@ class OffTheRecordProfileImpl : public Profile,
return profile_->GetPrivacyBlacklist();
}
+ virtual UserStyleSheetWatcher* GetUserStyleSheetWatcher() {
+ return profile_->GetUserStyleSheetWatcher();
+ }
+
virtual SessionService* GetSessionService() {
// Don't save any sessions when off the record.
return NULL;
@@ -988,6 +993,14 @@ Blacklist* ProfileImpl::GetPrivacyBlacklist() {
return privacy_blacklist_.get();
}
+UserStyleSheetWatcher* ProfileImpl::GetUserStyleSheetWatcher() {
+ if (!user_style_sheet_watcher_.get()) {
+ user_style_sheet_watcher_ = new UserStyleSheetWatcher(GetPath());
+ user_style_sheet_watcher_->Init();
+ }
+ return user_style_sheet_watcher_.get();
+}
+
HistoryService* ProfileImpl::GetHistoryService(ServiceAccessType sat) {
if (!history_service_created_) {
history_service_created_ = true;
diff --git a/chrome/browser/profile.h b/chrome/browser/profile.h
index eaa05b6..5787716 100644
--- a/chrome/browser/profile.h
+++ b/chrome/browser/profile.h
@@ -66,6 +66,7 @@ class ThemeProvider;
class ThumbnailStore;
class URLRequestContextGetter;
class UserScriptMaster;
+class UserStyleSheetWatcher;
class VisitedLinkMaster;
class VisitedLinkEventListener;
class WebDataService;
@@ -299,6 +300,9 @@ class Profile {
// Returns the Privacy Blacklist for this profile.
virtual Blacklist* GetPrivacyBlacklist() = 0;
+ // Returns the user style sheet watcher.
+ virtual UserStyleSheetWatcher* GetUserStyleSheetWatcher() = 0;
+
// Returns the session service for this profile. This may return NULL. If
// this profile supports a session service (it isn't off the record), and
// the session service hasn't yet been created, this forces creation of
@@ -467,6 +471,7 @@ class ProfileImpl : public Profile,
virtual HostContentSettingsMap* GetHostContentSettingsMap();
virtual HostZoomMap* GetHostZoomMap();
virtual Blacklist* GetPrivacyBlacklist();
+ virtual UserStyleSheetWatcher* GetUserStyleSheetWatcher();
virtual SessionService* GetSessionService();
virtual void ShutdownSessionService();
virtual bool HasSessionService() const;
@@ -553,6 +558,7 @@ class ProfileImpl : public Profile,
scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
scoped_refptr<HostZoomMap> host_zoom_map_;
scoped_refptr<Blacklist> privacy_blacklist_;
+ scoped_refptr<UserStyleSheetWatcher> user_style_sheet_watcher_;
scoped_refptr<DownloadManager> download_manager_;
scoped_refptr<HistoryService> history_service_;
scoped_refptr<FaviconService> favicon_service_;
diff --git a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc
index 50c6771..64b62f6 100644
--- a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc
+++ b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc
@@ -17,6 +17,7 @@
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/browser/user_style_sheet_watcher.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
@@ -112,8 +113,8 @@ void RenderViewHostDelegateViewHelper::RenderWidgetHostDestroyed(
// static
WebPreferences RenderViewHostDelegateHelper::GetWebkitPrefs(
- PrefService* prefs, bool is_dom_ui) {
-
+ Profile* profile, bool is_dom_ui) {
+ PrefService* prefs = profile->GetPrefs();
WebPreferences web_prefs;
web_prefs.fixed_font_family =
@@ -180,17 +181,24 @@ WebPreferences RenderViewHostDelegateHelper::GetWebkitPrefs(
!command_line.HasSwitch(switches::kDisableApplicationCache);
web_prefs.local_storage_enabled =
- !command_line.HasSwitch(switches::kDisableLocalStorage);
+ !command_line.HasSwitch(switches::kDisableLocalStorage);
web_prefs.databases_enabled =
- !command_line.HasSwitch(switches::kDisableDatabases);
+ !command_line.HasSwitch(switches::kDisableDatabases);
web_prefs.experimental_webgl_enabled =
- command_line.HasSwitch(switches::kEnableExperimentalWebGL);
+ command_line.HasSwitch(switches::kEnableExperimentalWebGL);
web_prefs.site_specific_quirks_enabled =
- !command_line.HasSwitch(switches::kDisableSiteSpecificQuirks);
+ !command_line.HasSwitch(switches::kDisableSiteSpecificQuirks);
web_prefs.allow_file_access_from_file_urls =
- command_line.HasSwitch(switches::kAllowFileAccessFromFiles);
+ command_line.HasSwitch(switches::kAllowFileAccessFromFiles);
web_prefs.show_composited_layer_borders =
- command_line.HasSwitch(switches::kShowCompositedLayerBorders);
+ command_line.HasSwitch(switches::kShowCompositedLayerBorders);
+ web_prefs.user_style_sheet_enabled =
+ command_line.HasSwitch(switches::kEnableUserStyleSheet);
+ if (web_prefs.user_style_sheet_enabled) {
+ web_prefs.user_style_sheet_location =
+ profile->GetUserStyleSheetWatcher()->user_style_sheet();
+ }
+
}
web_prefs.uses_universal_detector =
@@ -198,9 +206,6 @@ WebPreferences RenderViewHostDelegateHelper::GetWebkitPrefs(
web_prefs.text_areas_are_resizable =
prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable);
- // User CSS is currently disabled because it crashes chrome. See
- // webkit/glue/webpreferences.h for more details.
-
// Make sure we will set the default_encoding with canonical encoding name.
web_prefs.default_encoding =
CharacterEncoding::GetCanonicalEncodingNameByAliasName(
diff --git a/chrome/browser/tab_contents/render_view_host_delegate_helper.h b/chrome/browser/tab_contents/render_view_host_delegate_helper.h
index 5078858..acca99e 100644
--- a/chrome/browser/tab_contents/render_view_host_delegate_helper.h
+++ b/chrome/browser/tab_contents/render_view_host_delegate_helper.h
@@ -60,7 +60,7 @@ class RenderViewHostDelegateViewHelper {
// RenderViewHostDelegate methods.
class RenderViewHostDelegateHelper {
public:
- static WebPreferences GetWebkitPrefs(PrefService* prefs, bool is_dom_ui);
+ static WebPreferences GetWebkitPrefs(Profile* profile, bool is_dom_ui);
private:
RenderViewHostDelegateHelper();
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index 891249a..2815391 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -319,6 +319,9 @@ TabContents::TabContents(Profile* profile,
NotificationService::AllSources());
#endif
+ registrar_.Add(this, NotificationType::USER_STYLE_SHEET_UPDATED,
+ NotificationService::AllSources());
+
// Register for notifications about content setting changes.
registrar_.Add(this, NotificationType::CONTENT_SETTINGS_CHANGED,
NotificationService::AllSources());
@@ -2561,9 +2564,9 @@ GURL TabContents::GetAlternateErrorPageURL() const {
}
WebPreferences TabContents::GetWebkitPrefs() {
- PrefService* prefs = render_view_host()->process()->profile()->GetPrefs();
+ Profile* profile = render_view_host()->process()->profile();
bool is_dom_ui = false;
- return RenderViewHostDelegateHelper::GetWebkitPrefs(prefs, is_dom_ui);
+ return RenderViewHostDelegateHelper::GetWebkitPrefs(profile, is_dom_ui);
}
void TabContents::OnIgnoredUIEvent() {
@@ -2779,6 +2782,10 @@ void TabContents::Observe(NotificationType type,
}
#endif
+ case NotificationType::USER_STYLE_SHEET_UPDATED:
+ UpdateWebPreferences();
+ break;
+
case NotificationType::CONTENT_SETTINGS_CHANGED: {
Details<HostContentSettingsMap::ContentSettingsDetails>
settings_details(details);
diff --git a/chrome/browser/user_style_sheet_watcher.cc b/chrome/browser/user_style_sheet_watcher.cc
new file mode 100644
index 0000000..2d3e945
--- /dev/null
+++ b/chrome/browser/user_style_sheet_watcher.cc
@@ -0,0 +1,82 @@
+// Copyright (c) 2010 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/browser/user_style_sheet_watcher.h"
+
+#include "base/base64.h"
+#include "base/file_util.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_type.h"
+
+UserStyleSheetWatcher::UserStyleSheetWatcher(const FilePath& profile_path)
+ : profile_path_(profile_path),
+ has_loaded_(false) {
+ // Listen for when the first render view host is created. If we load
+ // too fast, the first tab won't hear the notification and won't get
+ // the user style sheet.
+ registrar_.Add(this, NotificationType::RENDER_VIEW_HOST_CREATED_FOR_TAB,
+ NotificationService::AllSources());
+}
+
+void UserStyleSheetWatcher::Observe(NotificationType type,
+ const NotificationSource& source, const NotificationDetails& details) {
+ DCHECK(type == NotificationType::RENDER_VIEW_HOST_CREATED_FOR_TAB);
+
+ if (has_loaded_) {
+ NotificationService::current()->Notify(
+ NotificationType::USER_STYLE_SHEET_UPDATED,
+ Source<UserStyleSheetWatcher>(this),
+ NotificationService::NoDetails());
+ }
+
+ registrar_.RemoveAll();
+}
+
+void UserStyleSheetWatcher::Init() {
+ ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &UserStyleSheetWatcher::LoadStyleSheet,
+ profile_path_));
+}
+
+void UserStyleSheetWatcher::LoadStyleSheet(const FilePath& profile_path) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
+ // We keep the user style sheet in a subdir so we can watch for changes
+ // to the file.
+ FilePath style_sheet_dir = profile_path.AppendASCII("User StyleSheets");
+ if (!file_util::DirectoryExists(style_sheet_dir)) {
+ if (!file_util::CreateDirectory(style_sheet_dir))
+ return;
+ }
+ // Create the file if it doesn't exist.
+ FilePath css_file = style_sheet_dir.AppendASCII("Custom.css");
+ if (!file_util::PathExists(css_file))
+ file_util::WriteFile(css_file, "", 0);
+
+ std::string css;
+ bool rv = file_util::ReadFileToString(css_file, &css);
+ GURL style_sheet_url;
+ if (rv) {
+ std::string css_base64;
+ rv = base::Base64Encode(css, &css_base64);
+ if (rv) {
+ // WebKit knows about data urls, so convert the file to a data url.
+ const char kDataUrlPrefix[] = "data:text/css;charset=utf-8;base64,";
+ style_sheet_url = GURL(kDataUrlPrefix + css_base64);
+ }
+ }
+ ChromeThread::PostTask(ChromeThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &UserStyleSheetWatcher::SetStyleSheet,
+ style_sheet_url));
+}
+
+void UserStyleSheetWatcher::SetStyleSheet(const GURL& url) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+
+ has_loaded_ = true;
+ user_style_sheet_ = url;
+ NotificationService::current()->Notify(
+ NotificationType::USER_STYLE_SHEET_UPDATED,
+ Source<UserStyleSheetWatcher>(this),
+ NotificationService::NoDetails());
+}
diff --git a/chrome/browser/user_style_sheet_watcher.h b/chrome/browser/user_style_sheet_watcher.h
new file mode 100644
index 0000000..87fa5ce
--- /dev/null
+++ b/chrome/browser/user_style_sheet_watcher.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2010 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_BROWSER_USER_STYLE_SHEET_WATCHER_H_
+#define CHROME_BROWSER_USER_STYLE_SHEET_WATCHER_H_
+
+#include "base/file_path.h"
+#include "base/logging.h"
+#include "base/ref_counted.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
+#include "googleurl/src/gurl.h"
+
+// This loads the user style sheet on the file thread and sends a notification
+// when the style sheet is loaded.
+// TODO(tony): Watch for file changes and send a notification of the update.
+class UserStyleSheetWatcher
+ : public base::RefCountedThreadSafe<UserStyleSheetWatcher,
+ ChromeThread::DeleteOnUIThread>,
+ public NotificationObserver {
+ public:
+ explicit UserStyleSheetWatcher(const FilePath& profile_path);
+ virtual ~UserStyleSheetWatcher() {}
+
+ void Init();
+
+ GURL user_style_sheet() const {
+ return user_style_sheet_;
+ }
+
+ // NotificationObserver interface
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ // Load the user style sheet on the file thread and convert it to a
+ // base64 URL. Posts the base64 URL back to the UI thread.
+ void LoadStyleSheet(const FilePath& profile_path);
+
+ void SetStyleSheet(const GURL& url);
+
+ // The directory containing the User StyleSheet.
+ FilePath profile_path_;
+
+ // The user style sheet as a base64 data:// URL.
+ GURL user_style_sheet_;
+
+ NotificationRegistrar registrar_;
+ bool has_loaded_;
+
+ DISALLOW_COPY_AND_ASSIGN(UserStyleSheetWatcher);
+};
+
+#endif // CHROME_BROWSER_USER_STYLE_SHEET_WATCHER_H_
diff --git a/chrome/browser/user_style_sheet_watcher_unittest.cc b/chrome/browser/user_style_sheet_watcher_unittest.cc
new file mode 100644
index 0000000..3e5932e
--- /dev/null
+++ b/chrome/browser/user_style_sheet_watcher_unittest.cc
@@ -0,0 +1,43 @@
+// Copyright (c) 2010 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/browser/user_style_sheet_watcher.h"
+
+#include "base/base64.h"
+#include "base/file_util.h"
+#include "base/message_loop.h"
+#include "base/scoped_temp_dir.h"
+#include "base/string_util.h"
+#include "chrome/browser/chrome_thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(UserStyleSheetWatcherTest, StyleLoad) {
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+
+ std::string css_file_contents = "a { color: green; }";
+ FilePath style_sheet_file = dir.path().AppendASCII("User StyleSheets")
+ .AppendASCII("Custom.css");
+ file_util::CreateDirectory(style_sheet_file.DirName());
+ ASSERT_TRUE(file_util::WriteFile(style_sheet_file,
+ css_file_contents.data(), css_file_contents.length()));
+
+ scoped_refptr<UserStyleSheetWatcher> style_sheet_watcher =
+ new UserStyleSheetWatcher(dir.path());
+ MessageLoop loop;
+ ChromeThread ui_thread(ChromeThread::UI, &loop);
+ ChromeThread file_thread(ChromeThread::FILE, &loop);
+ style_sheet_watcher->Init();
+
+ loop.RunAllPending();
+
+ GURL result_url = style_sheet_watcher->user_style_sheet();
+ std::string result = result_url.spec();
+ std::string prefix = "data:text/css;charset=utf-8;base64,";
+ EXPECT_TRUE(StartsWithASCII(result, prefix, true));
+ result = result.substr(prefix.length());
+ std::string decoded;
+ EXPECT_TRUE(base::Base64Decode(result, &decoded));
+ EXPECT_EQ(css_file_contents, decoded);
+}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index d6e16d1..a6db2f2 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1932,6 +1932,8 @@
'browser/translate/translate_prefs.h',
'browser/user_data_manager.cc',
'browser/user_data_manager.h',
+ 'browser/user_style_sheet_watcher.cc',
+ 'browser/user_style_sheet_watcher.h',
'browser/utility_process_host.cc',
'browser/utility_process_host.h',
'browser/view_ids.h',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 2648ee7..aa07ec4 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -873,6 +873,7 @@
'browser/task_manager_unittest.cc',
'browser/translate/translate_manager_unittest.cc',
'browser/theme_resources_util_unittest.cc',
+ 'browser/user_style_sheet_watcher_unittest.cc',
'browser/views/bookmark_context_menu_test.cc',
'browser/views/bookmark_editor_view_unittest.cc',
'browser/views/extensions/browser_action_drag_data_unittest.cc',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 31e3ae3..ad82c6f 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -301,6 +301,9 @@ const char kEnableTabbedBookmarkManager[] = "enable-tabbed-bookmark-manager";
// enabled or not.
const char kEnableUserDataDirProfiles[] = "enable-udd-profiles";
+// Enable user style sheet (read from User Style Sheet in the profile dir).
+const char kEnableUserStyleSheet[] = "enable-user-stylesheet";
+
// Enables the option to show tabs as a vertical stack down the side of the
// browser window.
const char kEnableVerticalTabs[] = "enable-vertical-tabs";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 0e463a6..e7df656 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -102,6 +102,7 @@ extern const char kEnableSyncBookmarks[];
extern const char kEnableSyncPreferences[];
extern const char kEnableTabbedBookmarkManager[];
extern const char kEnableUserDataDirProfiles[];
+extern const char kEnableUserStyleSheet[];
extern const char kEnableVerticalTabs[];
extern const char kEnableVideoLayering[];
extern const char kEnableWatchdog[];
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index 700ffb1..2d288c9 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -662,6 +662,11 @@ class NotificationType {
// pointer to SharedMemory containing the new scripts.
USER_SCRIPTS_UPDATED,
+ // User Style Sheet --------------------------------------------------------
+
+ // Sent when the user style sheet has changed.
+ USER_STYLE_SHEET_UPDATED,
+
// Extensions --------------------------------------------------------------
// Sent when the known installed extensions have all been loaded. In
diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h
index 31711fe..214d70a 100644
--- a/chrome/test/testing_profile.h
+++ b/chrome/test/testing_profile.h
@@ -184,6 +184,7 @@ class TestingProfile : public Profile {
virtual net::SSLConfigService* GetSSLConfigService() { return NULL; }
virtual Blacklist* GetPrivacyBlacklist() { return NULL; }
+ virtual UserStyleSheetWatcher* GetUserStyleSheetWatcher() { return NULL; }
virtual HostContentSettingsMap* GetHostContentSettingsMap() {
if (!host_content_settings_map_.get())
host_content_settings_map_ = new HostContentSettingsMap(this);