summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/cocoa/bug_report_window_controller_unittest.mm1
-rw-r--r--chrome/browser/dom_ui/chrome_url_data_manager.h2
-rw-r--r--chrome/browser/dom_ui/dom_ui_theme_source.cc243
-rw-r--r--chrome/browser/dom_ui/dom_ui_theme_source.h32
-rw-r--r--chrome/browser/dom_ui/dom_ui_theme_source_unittest.cc6
-rw-r--r--chrome/browser/dom_ui/dom_ui_unittest.cc4
-rw-r--r--chrome/browser/dom_ui/ntp_resource_cache.cc257
-rw-r--r--chrome/browser/dom_ui/ntp_resource_cache.h11
-rw-r--r--chrome/browser/tab_contents/render_view_host_manager_unittest.cc3
-rw-r--r--chrome/test/testing_profile.cc7
-rw-r--r--chrome/test/testing_profile.h4
11 files changed, 301 insertions, 269 deletions
diff --git a/chrome/browser/cocoa/bug_report_window_controller_unittest.mm b/chrome/browser/cocoa/bug_report_window_controller_unittest.mm
index d46e58a..fe5b005 100644
--- a/chrome/browser/cocoa/bug_report_window_controller_unittest.mm
+++ b/chrome/browser/cocoa/bug_report_window_controller_unittest.mm
@@ -17,6 +17,7 @@ class BugReportWindowControllerUnittest : public RenderViewHostTestHarness {
};
TEST_F(BugReportWindowControllerUnittest, ReportBugWithNewTabPageOpen) {
+ ChromeThread ui_thread(ChromeThread::UI, MessageLoop::current());
// Create a "chrome://newtab" test tab. SiteInstance will be deleted when
// tabContents is deleted.
SiteInstance* instance =
diff --git a/chrome/browser/dom_ui/chrome_url_data_manager.h b/chrome/browser/dom_ui/chrome_url_data_manager.h
index 16f2239..0247a2b 100644
--- a/chrome/browser/dom_ui/chrome_url_data_manager.h
+++ b/chrome/browser/dom_ui/chrome_url_data_manager.h
@@ -59,7 +59,7 @@ class ChromeURLDataManager {
// Report that a request has resulted in the data |bytes|.
// If the request can't be satisfied, pass NULL for |bytes| to indicate
// the request is over.
- void SendResponse(int request_id, RefCountedMemory* bytes);
+ virtual void SendResponse(int request_id, RefCountedMemory* bytes);
// Returns the MessageLoop on which the DataSource wishes to have
// StartDataRequest called to handle the request for |path|. If the
diff --git a/chrome/browser/dom_ui/dom_ui_theme_source.cc b/chrome/browser/dom_ui/dom_ui_theme_source.cc
index 759033b..bc3a0aa 100644
--- a/chrome/browser/dom_ui/dom_ui_theme_source.cc
+++ b/chrome/browser/dom_ui/dom_ui_theme_source.cc
@@ -4,43 +4,19 @@
#include "chrome/browser/dom_ui/dom_ui_theme_source.h"
-#include "app/l10n_util.h"
-#include "app/resource_bundle.h"
#include "app/theme_provider.h"
#include "base/message_loop.h"
-#include "base/string_util.h"
-#include "base/time.h"
#include "chrome/browser/browser_theme_provider.h"
+#include "chrome/browser/dom_ui/ntp_resource_cache.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/theme_resources_util.h"
-#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "googleurl/src/gurl.h"
-#include "grit/browser_resources.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#if defined(OS_WIN) || defined(TOOLKIT_VIEWS)
-#include "chrome/browser/views/bookmark_bar_view.h"
-#elif defined(OS_LINUX)
-#include "chrome/browser/gtk/bookmark_bar_gtk.h"
-#elif defined(OS_MACOSX)
-#include "chrome/browser/cocoa/bookmark_bar_constants.h"
-#endif
-
-// Path for the New Tab CSS. When we get more than a few of these, we should
// use a resource map rather than hard-coded strings.
static const char* kNewTabCSSPath = "css/newtab.css";
static const char* kNewIncognitoTabCSSPath = "css/newincognitotab.css";
-static std::string SkColorToRGBAString(SkColor color) {
- // We convert the alpha using DoubleToString because StringPrintf will use
- // locale specific formatters (e.g., use , instead of . in German).
- return StringPrintf("rgba(%d,%d,%d,%s)", SkColorGetR(color),
- SkColorGetG(color), SkColorGetB(color),
- DoubleToString(SkColorGetA(color) / 255.0).c_str());
-}
-
static std::string StripQueryParams(const std::string& path) {
GURL path_url = GURL(std::string(chrome::kChromeUIScheme) + "://" +
std::string(chrome::kChromeUIThemePath) + "/" + path);
@@ -52,11 +28,9 @@ static std::string StripQueryParams(const std::string& path) {
DOMUIThemeSource::DOMUIThemeSource(Profile* profile)
: DataSource(chrome::kChromeUIThemePath, MessageLoop::current()),
- profile_(profile->GetOriginalProfile()) {
- if (profile->IsOffTheRecord())
- InitNewIncognitoTabCSS(profile);
- else
- InitNewTabCSS(profile);
+ profile_(profile) {
+ css_bytes_ = profile_->GetNTPResourceCache()->GetNewTabCSS(
+ profile->IsOffTheRecord());
}
void DOMUIThemeSource::StartDataRequest(const std::string& path,
@@ -64,11 +38,13 @@ void DOMUIThemeSource::StartDataRequest(const std::string& path,
// Our path may include cachebuster arguments, so trim them off.
std::string uncached_path = StripQueryParams(path);
- if (uncached_path == kNewTabCSSPath) {
- SendNewTabCSS(request_id, new_tab_css_);
- return;
- } else if (uncached_path == kNewIncognitoTabCSSPath) {
- SendNewTabCSS(request_id, new_incognito_tab_css_);
+ if (uncached_path == kNewTabCSSPath ||
+ uncached_path == kNewIncognitoTabCSSPath) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ DCHECK((uncached_path == kNewTabCSSPath && !is_off_the_record) ||
+ (uncached_path == kNewIncognitoTabCSSPath && is_off_the_record));
+
+ SendResponse(request_id, css_bytes_);
return;
} else {
int resource_id = ThemeResourcesUtil::GetId(uncached_path);
@@ -92,219 +68,28 @@ std::string DOMUIThemeSource::GetMimeType(const std::string& path) const {
return "image/png";
}
-void DOMUIThemeSource::SendResponse(int request_id, RefCountedMemory* data) {
- ChromeURLDataManager::DataSource::SendResponse(request_id, data);
-}
-
MessageLoop* DOMUIThemeSource::MessageLoopForRequestPath(
const std::string& path) const {
std::string uncached_path = StripQueryParams(path);
if (uncached_path == kNewTabCSSPath ||
uncached_path == kNewIncognitoTabCSSPath) {
- // All of the operations that need to be on the UI thread for these
- // requests are performed in InitNewTabCSS and InitNewIncognitoTabCSS,
- // called by the constructor. It is safe to call StartDataRequest for
- // these resources from any thread, so return NULL.
+ // We generated and cached this when we initialized the object. We don't
+ // have to go back to the UI thread to send the data.
return NULL;
}
- // Superclass
return DataSource::MessageLoopForRequestPath(path);
}
////////////////////////////////////////////////////////////////////////////////
// DOMUIThemeSource, private:
-void DOMUIThemeSource::InitNewTabCSS(Profile* profile) {
- ThemeProvider* tp = profile->GetThemeProvider();
- DCHECK(tp);
-
- // Get our theme colors
- SkColor color_background =
- tp->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND);
- SkColor color_text = tp->GetColor(BrowserThemeProvider::COLOR_NTP_TEXT);
- SkColor color_link = tp->GetColor(BrowserThemeProvider::COLOR_NTP_LINK);
- SkColor color_link_underline =
- tp->GetColor(BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE);
-
- SkColor color_section =
- tp->GetColor(BrowserThemeProvider::COLOR_NTP_SECTION);
- SkColor color_section_text =
- tp->GetColor(BrowserThemeProvider::COLOR_NTP_SECTION_TEXT);
- SkColor color_section_link =
- tp->GetColor(BrowserThemeProvider::COLOR_NTP_SECTION_LINK);
- SkColor color_section_link_underline =
- tp->GetColor(BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE);
-
- SkColor color_header =
- tp->GetColor(BrowserThemeProvider::COLOR_NTP_HEADER);
- // Generate a lighter color for the header gradients.
- color_utils::HSL header_lighter;
- color_utils::SkColorToHSL(color_header, &header_lighter);
- header_lighter.l += (1 - header_lighter.l) * 0.33;
- SkColor color_header_gradient_light =
- color_utils::HSLToSkColor(header_lighter, SkColorGetA(color_header));
-
- // Generate section border color from the header color. See
- // BookmarkBarView::Paint for how we do this for the bookmark bar
- // borders.
- SkColor color_section_border =
- SkColorSetARGB(80,
- SkColorGetR(color_header),
- SkColorGetG(color_header),
- SkColorGetB(color_header));
-
- // Generate the replacements.
- std::vector<std::string> subst;
- // A second list of replacements, each of which must be in $$x format,
- // where x is a digit from 1-9.
- std::vector<std::string> subst2;
-
- // Cache-buster for background.
- subst.push_back(WideToASCII(
- profile->GetPrefs()->GetString(prefs::kCurrentThemeID))); // $1
-
- // Colors.
- subst.push_back(SkColorToRGBAString(color_background)); // $2
- subst.push_back(GetNewTabBackgroundCSS(false)); // $3
- subst.push_back(GetNewTabBackgroundCSS(true)); // $4
- subst.push_back(GetNewTabBackgroundTilingCSS()); // $5
- subst.push_back(SkColorToRGBAString(color_header)); // $6
- subst.push_back(SkColorToRGBAString(color_header_gradient_light)); // $7
- subst.push_back(SkColorToRGBAString(color_text)); // $8
- subst.push_back(SkColorToRGBAString(color_link)); // $9
-
- subst2.push_back(SkColorToRGBAString(color_section)); // $$1
- subst2.push_back(SkColorToRGBAString(color_section_border)); // $$2
- subst2.push_back(SkColorToRGBAString(color_section_text)); // $$3
- subst2.push_back(SkColorToRGBAString(color_section_link)); // $$4
- subst2.push_back(
- tp->HasCustomImage(IDR_THEME_NTP_ATTRIBUTION) ? "block" : "none"); // $$5
- subst2.push_back(SkColorToRGBAString(color_link_underline)); // $$6
- subst2.push_back(SkColorToRGBAString(color_section_link_underline)); // $$7
-
-#if defined(OS_MACOSX)
- // No extensions available on Mac yet.
- subst2.push_back("none"); // $$8: display of lower right promo image
- subst2.push_back("none"); // $$9: display of butterbar footer promo line
-#else
- if (profile->GetPrefs()->GetInteger(prefs::kNTPPromoImageRemaining) > 0) {
- subst2.push_back("block"); // $$8
- } else {
- subst2.push_back("none"); // $$8
- }
- if (profile->GetPrefs()->GetInteger(prefs::kNTPPromoLineRemaining) > 0) {
- subst2.push_back("inline-block"); // $$9
- } else {
- subst2.push_back("none"); // $$9
- }
-#endif
-
- // Get our template.
- static const base::StringPiece new_tab_theme_css(
- ResourceBundle::GetSharedInstance().GetRawDataResource(
- IDR_NEW_TAB_THEME_CSS));
-
- // Create the string from our template and the replacements.
- const std::string css_string = ReplaceStringPlaceholders(
- new_tab_theme_css, subst, NULL);
- new_tab_css_ = ReplaceStringPlaceholders(
- css_string, subst2, NULL);
-}
-
-void DOMUIThemeSource::InitNewIncognitoTabCSS(Profile* profile) {
- ThemeProvider* tp = profile->GetThemeProvider();
- DCHECK(tp);
-
- // Get our theme colors
- SkColor color_background =
- tp->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND);
-
- // Generate the replacements.
- std::vector<std::string> subst;
-
- // Cache-buster for background.
- subst.push_back(WideToUTF8(
- profile->GetPrefs()->GetString(prefs::kCurrentThemeID))); // $1
-
- // Colors.
- subst.push_back(SkColorToRGBAString(color_background)); // $2
- subst.push_back(GetNewTabBackgroundCSS(false)); // $3
- subst.push_back(GetNewTabBackgroundCSS(true)); // $4
- subst.push_back(GetNewTabBackgroundTilingCSS()); // $5
-
- // Get our template.
- static const base::StringPiece new_tab_theme_css(
- ResourceBundle::GetSharedInstance().GetRawDataResource(
- IDR_NEW_INCOGNITO_TAB_THEME_CSS));
-
- // Create the string from our template and the replacements.
- new_incognito_tab_css_ = ReplaceStringPlaceholders(
- new_tab_theme_css, subst, NULL);
-}
-
-void DOMUIThemeSource::SendNewTabCSS(int request_id,
- const std::string& css_string) {
- // Convert to a format appropriate for sending.
- scoped_refptr<RefCountedBytes> css_bytes(new RefCountedBytes);
- css_bytes->data.resize(css_string.size());
- std::copy(css_string.begin(), css_string.end(), css_bytes->data.begin());
-
- // Send.
- SendResponse(request_id, css_bytes);
-}
-
void DOMUIThemeSource::SendThemeBitmap(int request_id, int resource_id) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
ThemeProvider* tp = profile_->GetThemeProvider();
DCHECK(tp);
scoped_refptr<RefCountedMemory> image_data(tp->GetRawData(resource_id));
SendResponse(request_id, image_data);
}
-
-std::string DOMUIThemeSource::GetNewTabBackgroundCSS(bool bar_attached) {
- int alignment;
- profile_->GetThemeProvider()->GetDisplayProperty(
- BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &alignment);
-
- // TODO(glen): This is a quick workaround to hide the notused.png image when
- // no image is provided - we don't have time right now to figure out why
- // this is painting as white.
- // http://crbug.com/17593
- if (!profile_->GetThemeProvider()->HasCustomImage(IDR_THEME_NTP_BACKGROUND)) {
- return "-64px";
- }
-
- if (bar_attached)
- return BrowserThemeProvider::AlignmentToString(alignment);
-
- // The bar is detached, so we must offset the background by the bar size
- // if it's a top-aligned bar.
-#if defined(OS_WIN) || defined(TOOLKIT_VIEWS)
- int offset = BookmarkBarView::kNewtabBarHeight;
-#elif defined(OS_LINUX)
- int offset = BookmarkBarGtk::kBookmarkBarNTPHeight;
-#elif defined(OS_MACOSX)
- int offset = bookmarks::kNTPBookmarkBarHeight;
-#else
- int offset = 0;
-#endif
-
- if (alignment & BrowserThemeProvider::ALIGN_TOP) {
- if (alignment & BrowserThemeProvider::ALIGN_LEFT)
- return "0% " + IntToString(-offset) + "px";
- else if (alignment & BrowserThemeProvider::ALIGN_RIGHT)
- return "100% " + IntToString(-offset) + "px";
- return "center " + IntToString(-offset) + "px";
- }
- return BrowserThemeProvider::AlignmentToString(alignment);
-}
-
-std::string DOMUIThemeSource::GetNewTabBackgroundTilingCSS() {
- int repeat_mode;
- profile_->GetThemeProvider()->GetDisplayProperty(
- BrowserThemeProvider::NTP_BACKGROUND_TILING, &repeat_mode);
- return BrowserThemeProvider::TilingToString(repeat_mode);
-}
-
diff --git a/chrome/browser/dom_ui/dom_ui_theme_source.h b/chrome/browser/dom_ui/dom_ui_theme_source.h
index be3a42a..5c74649 100644
--- a/chrome/browser/dom_ui/dom_ui_theme_source.h
+++ b/chrome/browser/dom_ui/dom_ui_theme_source.h
@@ -24,44 +24,22 @@ class DOMUIThemeSource : public ChromeURLDataManager::DataSource {
int request_id);
virtual std::string GetMimeType(const std::string& path) const;
- virtual void SendResponse(int request_id, RefCountedMemory* data);
-
+ // Used to tell ChromeURLDataManager which thread to handle the request on.
virtual MessageLoop* MessageLoopForRequestPath(const std::string& path) const;
protected:
virtual ~DOMUIThemeSource() {}
private:
- // Populate new_tab_css_ and new_incognito_tab_css. These must be called
- // from the UI thread because they involve profile and theme access.
- //
- // A new DOMUIThemeSource object is used for each new tab page instance
- // and each reload of an existing new tab page, so there is no concern about
- // cached data becoming stale.
- void InitNewTabCSS(Profile* profile);
- void InitNewIncognitoTabCSS(Profile* profile);
-
- // Send the CSS for the new tab or the new incognito tab.
- void SendNewTabCSS(int request_id, const std::string& css_string);
-
// Fetch and send the theme bitmap.
void SendThemeBitmap(int request_id, int resource_id);
- // Get the CSS string for the background position on the new tab page for the
- // states when the bar is attached or detached.
- std::string GetNewTabBackgroundCSS(bool bar_attached);
-
- // How the background image on the new tab page should be tiled (see tiling
- // masks in browser_theme_provider.h).
- std::string GetNewTabBackgroundTilingCSS();
-
- // The content to be served by SendNewTabCSS, stored by InitNewTabCSS and
- // InitNewIncognitoTabCSS.
- std::string new_tab_css_;
- std::string new_incognito_tab_css_;
-
// The original profile (never an OTR profile).
Profile* profile_;
+
+ // We grab the CSS early so we don't have to go back to the UI thread later.
+ scoped_refptr<RefCountedBytes> css_bytes_;
+
DISALLOW_COPY_AND_ASSIGN(DOMUIThemeSource);
};
diff --git a/chrome/browser/dom_ui/dom_ui_theme_source_unittest.cc b/chrome/browser/dom_ui/dom_ui_theme_source_unittest.cc
index ecbdfa7..0f1e9eb 100644
--- a/chrome/browser/dom_ui/dom_ui_theme_source_unittest.cc
+++ b/chrome/browser/dom_ui/dom_ui_theme_source_unittest.cc
@@ -33,6 +33,8 @@ class MockThemeSource : public DOMUIThemeSource {
class DOMUISourcesTest : public testing::Test {
public:
+ DOMUISourcesTest() : ui_thread_(ChromeThread::UI, MessageLoop::current()) {}
+
TestingProfile* profile() const { return profile_.get(); }
MockThemeSource* theme_source() const { return theme_source_.get(); }
private:
@@ -47,6 +49,9 @@ class DOMUISourcesTest : public testing::Test {
profile_.reset(NULL);
}
+ MessageLoop loop_;
+ ChromeThread ui_thread_;
+
scoped_ptr<TestingProfile> profile_;
scoped_refptr<MockThemeSource> theme_source_;
};
@@ -71,6 +76,7 @@ TEST_F(DOMUISourcesTest, ThemeSourceImages) {
}
TEST_F(DOMUISourcesTest, ThemeSourceCSS) {
+ ChromeThread io_thread(ChromeThread::IO, MessageLoop::current());
// Generating the test data for the NTP CSS would just involve copying the
// method, or being super brittle and hard-coding the result (requiring
// an update to the unittest every time the CSS template changes), so we
diff --git a/chrome/browser/dom_ui/dom_ui_unittest.cc b/chrome/browser/dom_ui/dom_ui_unittest.cc
index 712a2df..81df016 100644
--- a/chrome/browser/dom_ui/dom_ui_unittest.cc
+++ b/chrome/browser/dom_ui/dom_ui_unittest.cc
@@ -9,7 +9,7 @@
class DOMUITest : public RenderViewHostTestHarness {
public:
- DOMUITest() {}
+ DOMUITest() : ui_thread_(ChromeThread::UI, MessageLoop::current()) {}
// Tests navigating with a DOM UI from a fresh (nothing pending or committed)
// state, through pending, committed, then another navigation. The first page
@@ -75,6 +75,8 @@ class DOMUITest : public RenderViewHostTestHarness {
}
private:
+ ChromeThread ui_thread_;
+
DISALLOW_COPY_AND_ASSIGN(DOMUITest);
};
diff --git a/chrome/browser/dom_ui/ntp_resource_cache.cc b/chrome/browser/dom_ui/ntp_resource_cache.cc
index 7e83e31..5e56dde 100644
--- a/chrome/browser/dom_ui/ntp_resource_cache.cc
+++ b/chrome/browser/dom_ui/ntp_resource_cache.cc
@@ -11,7 +11,9 @@
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/ref_counted_memory.h"
+#include "base/string_util.h"
#include "base/values.h"
+#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/dom_ui/chrome_url_data_manager.h"
#include "chrome/browser/google_util.h"
#include "chrome/browser/profile.h"
@@ -31,6 +33,14 @@
#include "grit/locale_settings.h"
#include "grit/theme_resources.h"
+#if defined(OS_WIN) || defined(TOOLKIT_VIEWS)
+#include "chrome/browser/views/bookmark_bar_view.h"
+#elif defined(OS_LINUX)
+#include "chrome/browser/gtk/bookmark_bar_gtk.h"
+#elif defined(OS_MACOSX)
+#include "chrome/browser/cocoa/bookmark_bar_constants.h"
+#endif
+
namespace {
// The URL for the the Learn More page shown on incognito new tab.
@@ -66,17 +76,78 @@ std::string GetCustomNewTabPageFromCommandLine() {
return std::string();
}
+std::string SkColorToRGBAString(SkColor color) {
+ // We convert the alpha using DoubleToString because StringPrintf will use
+ // locale specific formatters (e.g., use , instead of . in German).
+ return StringPrintf("rgba(%d,%d,%d,%s)", SkColorGetR(color),
+ SkColorGetG(color), SkColorGetB(color),
+ DoubleToString(SkColorGetA(color) / 255.0).c_str());
+}
+
+// Get the CSS string for the background position on the new tab page for the
+// states when the bar is attached or detached.
+std::string GetNewTabBackgroundCSS(const ThemeProvider* theme_provider,
+ bool bar_attached) {
+ int alignment;
+ theme_provider->GetDisplayProperty(
+ BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, &alignment);
+
+ // TODO(glen): This is a quick workaround to hide the notused.png image when
+ // no image is provided - we don't have time right now to figure out why
+ // this is painting as white.
+ // http://crbug.com/17593
+ if (!theme_provider->HasCustomImage(IDR_THEME_NTP_BACKGROUND)) {
+ return "-64px";
+ }
+
+ if (bar_attached)
+ return BrowserThemeProvider::AlignmentToString(alignment);
+
+ // The bar is detached, so we must offset the background by the bar size
+ // if it's a top-aligned bar.
+#if defined(OS_WIN) || defined(TOOLKIT_VIEWS)
+ int offset = BookmarkBarView::kNewtabBarHeight;
+#elif defined(OS_LINUX)
+ int offset = BookmarkBarGtk::kBookmarkBarNTPHeight;
+#elif defined(OS_MACOSX)
+ int offset = bookmarks::kNTPBookmarkBarHeight;
+#else
+ int offset = 0;
+#endif
+
+ if (alignment & BrowserThemeProvider::ALIGN_TOP) {
+ if (alignment & BrowserThemeProvider::ALIGN_LEFT)
+ return "0% " + IntToString(-offset) + "px";
+ else if (alignment & BrowserThemeProvider::ALIGN_RIGHT)
+ return "100% " + IntToString(-offset) + "px";
+ return "center " + IntToString(-offset) + "px";
+ }
+ return BrowserThemeProvider::AlignmentToString(alignment);
+}
+
+// How the background image on the new tab page should be tiled (see tiling
+// masks in browser_theme_provider.h).
+std::string GetNewTabBackgroundTilingCSS(const ThemeProvider* theme_provider) {
+ int repeat_mode;
+ theme_provider->GetDisplayProperty(
+ BrowserThemeProvider::NTP_BACKGROUND_TILING, &repeat_mode);
+ return BrowserThemeProvider::TilingToString(repeat_mode);
}
+} // namespace
+
NTPResourceCache::NTPResourceCache(Profile* profile) : profile_(profile) {
registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
NotificationService::AllSources());
- // Watch for pref changes that cause us to need to invalidate the cache.
+ // Watch for pref changes that cause us to need to invalidate the HTML cache.
PrefService* pref_service = profile_->GetPrefs();
pref_service->AddPrefObserver(prefs::kShowBookmarkBar, this);
pref_service->AddPrefObserver(prefs::kHomePageIsNewTabPage, this);
pref_service->AddPrefObserver(prefs::kNTPShownSections, this);
+
+ // Watch for pref changes that cause us to need to invalidate the CSS cache.
+ pref_service->AddPrefObserver(prefs::kNTPPromoLineRemaining, this);
}
NTPResourceCache::~NTPResourceCache() {
@@ -84,28 +155,63 @@ NTPResourceCache::~NTPResourceCache() {
pref_service->RemovePrefObserver(prefs::kShowBookmarkBar, this);
pref_service->RemovePrefObserver(prefs::kHomePageIsNewTabPage, this);
pref_service->RemovePrefObserver(prefs::kNTPShownSections, this);
+
+ pref_service->RemovePrefObserver(prefs::kNTPPromoLineRemaining, this);
}
RefCountedBytes* NTPResourceCache::GetNewTabHTML(bool is_off_the_record) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
if (is_off_the_record) {
if (!new_tab_incognito_html_.get())
- CreateNewTabIncognitoHtml();
+ CreateNewTabIncognitoHTML();
} else {
if (!new_tab_html_.get())
- CreateNewTabHtml();
+ CreateNewTabHTML();
}
return is_off_the_record ? new_tab_incognito_html_.get()
: new_tab_html_.get();
}
+RefCountedBytes* NTPResourceCache::GetNewTabCSS(bool is_off_the_record) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ if (is_off_the_record) {
+ if (!new_tab_incognito_css_.get())
+ CreateNewTabIncognitoCSS();
+ } else {
+ if (!new_tab_css_.get())
+ CreateNewTabCSS();
+ }
+ return is_off_the_record ? new_tab_incognito_css_.get()
+ : new_tab_css_.get();
+}
+
void NTPResourceCache::Observe(NotificationType type,
const NotificationSource& source, const NotificationDetails& details) {
- new_tab_incognito_html_ = NULL;
- new_tab_html_ = NULL;
+ // Invalidate the cache.
+ if (NotificationType::BROWSER_THEME_CHANGED == type) {
+ new_tab_incognito_html_ = NULL;
+ new_tab_html_ = NULL;
+ new_tab_incognito_css_ = NULL;
+ new_tab_css_ = NULL;
+ } else if (NotificationType::PREF_CHANGED == type) {
+ std::wstring* pref_name = Details<std::wstring>(details).ptr();
+ if (*pref_name == prefs::kShowBookmarkBar ||
+ *pref_name == prefs::kHomePageIsNewTabPage ||
+ *pref_name == prefs::kNTPShownSections) {
+ new_tab_incognito_html_ = NULL;
+ new_tab_html_ = NULL;
+ } else if (*pref_name == prefs::kNTPPromoLineRemaining) {
+ new_tab_incognito_css_ = NULL;
+ new_tab_css_ = NULL;
+ } else {
+ NOTREACHED();
+ }
+ } else {
+ NOTREACHED();
+ }
}
-void NTPResourceCache::CreateNewTabIncognitoHtml() {
+void NTPResourceCache::CreateNewTabIncognitoHTML() {
DictionaryValue localized_strings;
localized_strings.SetString(L"title",
l10n_util::GetString(IDS_NEW_TAB_TITLE));
@@ -132,7 +238,7 @@ void NTPResourceCache::CreateNewTabIncognitoHtml() {
new_tab_incognito_html_->data.begin());
}
-void NTPResourceCache::CreateNewTabHtml() {
+void NTPResourceCache::CreateNewTabHTML() {
// Show the profile name in the title and most visited labels if the current
// profile is not the default.
std::wstring title;
@@ -309,3 +415,140 @@ void NTPResourceCache::CreateNewTabHtml() {
new_tab_html_->data.resize(full_html.size());
std::copy(full_html.begin(), full_html.end(), new_tab_html_->data.begin());
}
+
+void NTPResourceCache::CreateNewTabIncognitoCSS() {
+ ThemeProvider* tp = profile_->GetThemeProvider();
+ DCHECK(tp);
+
+ // Get our theme colors
+ SkColor color_background =
+ tp->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND);
+
+ // Generate the replacements.
+ std::vector<std::string> subst;
+
+ // Cache-buster for background.
+ subst.push_back(WideToUTF8(
+ profile_->GetPrefs()->GetString(prefs::kCurrentThemeID))); // $1
+
+ // Colors.
+ subst.push_back(SkColorToRGBAString(color_background)); // $2
+ subst.push_back(GetNewTabBackgroundCSS(tp, false)); // $3
+ subst.push_back(GetNewTabBackgroundCSS(tp, true)); // $4
+ subst.push_back(GetNewTabBackgroundTilingCSS(tp)); // $5
+
+ // Get our template.
+ static const base::StringPiece new_tab_theme_css(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_NEW_INCOGNITO_TAB_THEME_CSS));
+
+ // Create the string from our template and the replacements.
+ std::string full_css = ReplaceStringPlaceholders(
+ new_tab_theme_css, subst, NULL);
+
+ new_tab_incognito_css_ = new RefCountedBytes;
+ new_tab_incognito_css_->data.resize(full_css.size());
+ std::copy(full_css.begin(), full_css.end(),
+ new_tab_incognito_css_->data.begin());
+}
+
+void NTPResourceCache::CreateNewTabCSS() {
+ ThemeProvider* tp = profile_->GetThemeProvider();
+ DCHECK(tp);
+
+ // Get our theme colors
+ SkColor color_background =
+ tp->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND);
+ SkColor color_text = tp->GetColor(BrowserThemeProvider::COLOR_NTP_TEXT);
+ SkColor color_link = tp->GetColor(BrowserThemeProvider::COLOR_NTP_LINK);
+ SkColor color_link_underline =
+ tp->GetColor(BrowserThemeProvider::COLOR_NTP_LINK_UNDERLINE);
+
+ SkColor color_section =
+ tp->GetColor(BrowserThemeProvider::COLOR_NTP_SECTION);
+ SkColor color_section_text =
+ tp->GetColor(BrowserThemeProvider::COLOR_NTP_SECTION_TEXT);
+ SkColor color_section_link =
+ tp->GetColor(BrowserThemeProvider::COLOR_NTP_SECTION_LINK);
+ SkColor color_section_link_underline =
+ tp->GetColor(BrowserThemeProvider::COLOR_NTP_SECTION_LINK_UNDERLINE);
+
+ SkColor color_header =
+ tp->GetColor(BrowserThemeProvider::COLOR_NTP_HEADER);
+ // Generate a lighter color for the header gradients.
+ color_utils::HSL header_lighter;
+ color_utils::SkColorToHSL(color_header, &header_lighter);
+ header_lighter.l += (1 - header_lighter.l) * 0.33;
+ SkColor color_header_gradient_light =
+ color_utils::HSLToSkColor(header_lighter, SkColorGetA(color_header));
+
+ // Generate section border color from the header color. See
+ // BookmarkBarView::Paint for how we do this for the bookmark bar
+ // borders.
+ SkColor color_section_border =
+ SkColorSetARGB(80,
+ SkColorGetR(color_header),
+ SkColorGetG(color_header),
+ SkColorGetB(color_header));
+
+ // Generate the replacements.
+ std::vector<std::string> subst;
+ // A second list of replacements, each of which must be in $$x format,
+ // where x is a digit from 1-9.
+ std::vector<std::string> subst2;
+
+ // Cache-buster for background.
+ subst.push_back(WideToASCII(
+ profile_->GetPrefs()->GetString(prefs::kCurrentThemeID))); // $1
+
+ // Colors.
+ subst.push_back(SkColorToRGBAString(color_background)); // $2
+ subst.push_back(GetNewTabBackgroundCSS(tp, false)); // $3
+ subst.push_back(GetNewTabBackgroundCSS(tp, true)); // $4
+ subst.push_back(GetNewTabBackgroundTilingCSS(tp)); // $5
+ subst.push_back(SkColorToRGBAString(color_header)); // $6
+ subst.push_back(SkColorToRGBAString(color_header_gradient_light)); // $7
+ subst.push_back(SkColorToRGBAString(color_text)); // $8
+ subst.push_back(SkColorToRGBAString(color_link)); // $9
+
+ subst2.push_back(SkColorToRGBAString(color_section)); // $$1
+ subst2.push_back(SkColorToRGBAString(color_section_border)); // $$2
+ subst2.push_back(SkColorToRGBAString(color_section_text)); // $$3
+ subst2.push_back(SkColorToRGBAString(color_section_link)); // $$4
+ subst2.push_back(
+ tp->HasCustomImage(IDR_THEME_NTP_ATTRIBUTION) ? "block" : "none"); // $$5
+ subst2.push_back(SkColorToRGBAString(color_link_underline)); // $$6
+ subst2.push_back(SkColorToRGBAString(color_section_link_underline)); // $$7
+
+#if defined(OS_MACOSX)
+ // No extensions available on Mac yet.
+ subst2.push_back("none"); // $$8: display of lower right promo image
+ subst2.push_back("none"); // $$9: display of butterbar footer promo line
+#else
+ if (profile_->GetPrefs()->GetInteger(prefs::kNTPPromoImageRemaining) > 0) {
+ subst2.push_back("block"); // $$8
+ } else {
+ subst2.push_back("none"); // $$8
+ }
+ if (profile_->GetPrefs()->GetInteger(prefs::kNTPPromoLineRemaining) > 0) {
+ subst2.push_back("inline-block"); // $$9
+ } else {
+ subst2.push_back("none"); // $$9
+ }
+#endif
+
+ // Get our template.
+ static const base::StringPiece new_tab_theme_css(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_NEW_TAB_THEME_CSS));
+
+ // Create the string from our template and the replacements.
+ const std::string css_string = ReplaceStringPlaceholders(
+ new_tab_theme_css, subst, NULL);
+ std::string full_css = ReplaceStringPlaceholders(css_string, subst2, NULL);
+
+ new_tab_css_ = new RefCountedBytes;
+ new_tab_css_->data.resize(full_css.size());
+ std::copy(full_css.begin(), full_css.end(),
+ new_tab_css_->data.begin());
+}
diff --git a/chrome/browser/dom_ui/ntp_resource_cache.h b/chrome/browser/dom_ui/ntp_resource_cache.h
index a39b962..5f36b91 100644
--- a/chrome/browser/dom_ui/ntp_resource_cache.h
+++ b/chrome/browser/dom_ui/ntp_resource_cache.h
@@ -22,6 +22,7 @@ class NTPResourceCache : public NotificationObserver {
virtual ~NTPResourceCache();
RefCountedBytes* GetNewTabHTML(bool is_off_the_record);
+ RefCountedBytes* GetNewTabCSS(bool is_off_the_record);
// NotificationObserver interface.
virtual void Observe(NotificationType type,
@@ -31,12 +32,16 @@ class NTPResourceCache : public NotificationObserver {
private:
Profile* profile_;
- void CreateNewTabIncognitoHtml();
+ void CreateNewTabIncognitoHTML();
scoped_refptr<RefCountedBytes> new_tab_incognito_html_;
-
- void CreateNewTabHtml();
+ void CreateNewTabHTML();
scoped_refptr<RefCountedBytes> new_tab_html_;
+ void CreateNewTabIncognitoCSS();
+ scoped_refptr<RefCountedBytes> new_tab_incognito_css_;
+ void CreateNewTabCSS();
+ scoped_refptr<RefCountedBytes> new_tab_css_;
+
NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(NTPResourceCache);
diff --git a/chrome/browser/tab_contents/render_view_host_manager_unittest.cc b/chrome/browser/tab_contents/render_view_host_manager_unittest.cc
index 318be7d..1cf4e42 100644
--- a/chrome/browser/tab_contents/render_view_host_manager_unittest.cc
+++ b/chrome/browser/tab_contents/render_view_host_manager_unittest.cc
@@ -31,6 +31,7 @@ class RenderViewHostManagerTest : public RenderViewHostTestHarness {
// different SiteInstances, BrowsingInstances, and RenderProcessHosts. This is
// a regression test for bug 9364.
TEST_F(RenderViewHostManagerTest, NewTabPageProcesses) {
+ ChromeThread ui_thread(ChromeThread::UI, MessageLoop::current());
GURL ntp(chrome::kChromeUINewTabURL);
GURL dest("http://www.google.com/");
@@ -78,6 +79,7 @@ TEST_F(RenderViewHostManagerTest, NewTabPageProcesses) {
// EnableViewSourceMode message is sent on every navigation regardless
// RenderView is being newly created or reused.
TEST_F(RenderViewHostManagerTest, AlwaysSendEnableViewSourceMode) {
+ ChromeThread ui_thread(ChromeThread::UI, MessageLoop::current());
const GURL kNtpUrl(chrome::kChromeUINewTabURL);
const GURL kUrl("view-source:http://foo");
@@ -228,6 +230,7 @@ TEST_F(RenderViewHostManagerTest, Navigate) {
// Tests DOMUI creation.
TEST_F(RenderViewHostManagerTest, DOMUI) {
+ ChromeThread ui_thread(ChromeThread::UI, MessageLoop::current());
SiteInstance* instance = SiteInstance::CreateSiteInstance(profile_.get());
TestTabContents tab_contents(profile_.get(), instance);
diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc
index b718773..39e847a 100644
--- a/chrome/test/testing_profile.cc
+++ b/chrome/test/testing_profile.cc
@@ -7,6 +7,7 @@
#include "build/build_config.h"
#include "base/string_util.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
+#include "chrome/browser/dom_ui/ntp_resource_cache.h"
#include "chrome/browser/history/history_backend.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/common/chrome_constants.h"
@@ -201,6 +202,12 @@ void TestingProfile::InitThemes() {
}
}
+NTPResourceCache* TestingProfile::GetNTPResourceCache() {
+ if (!ntp_resource_cache_.get())
+ ntp_resource_cache_.reset(new NTPResourceCache(this));
+ return ntp_resource_cache_.get();
+}
+
void TestingProfile::BlockUntilHistoryProcessesPendingRequests() {
DCHECK(history_service_.get());
DCHECK(MessageLoop::current());
diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h
index 677bb7e..37c35ea 100644
--- a/chrome/test/testing_profile.h
+++ b/chrome/test/testing_profile.h
@@ -182,7 +182,7 @@ class TestingProfile : public Profile {
virtual void MarkAsCleanShutdown() {}
virtual void InitExtensions() {}
virtual void InitWebResources() {}
- virtual NTPResourceCache* GetNTPResourceCache() { return NULL; }
+ virtual NTPResourceCache* GetNTPResourceCache();
virtual DesktopNotificationService* GetDesktopNotificationService() {
return NULL;
}
@@ -220,6 +220,8 @@ class TestingProfile : public Profile {
// The TemplateURLFetcher. Only created if CreateTemplateURLModel is invoked.
scoped_ptr<TemplateURLModel> template_url_model_;
+ scoped_ptr<NTPResourceCache> ntp_resource_cache_;
+
// The SessionService. Defaults to NULL, but can be set using the setter.
scoped_refptr<SessionService> session_service_;