summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-23 18:31:25 +0000
committertony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-23 18:31:25 +0000
commit156ed27bc42a66a694e243f3ecb0ad80f0c83351 (patch)
tree999d33767f2c2a2b41a97daa2c1ea65a7045f10a
parenta1dc714c599af4971dfe74a71c73a2be0ff3033b (diff)
downloadchromium_src-156ed27bc42a66a694e243f3ecb0ad80f0c83351.zip
chromium_src-156ed27bc42a66a694e243f3ecb0ad80f0c83351.tar.gz
chromium_src-156ed27bc42a66a694e243f3ecb0ad80f0c83351.tar.bz2
Take 2 at moving NTP CSS resources into the NTP resource cache.
Moving the HTML to the cache saved 8ms on New Tab Warm on Windows, maybe we can shave a few more ms off by moving the CSS. The last change had a regression on the mac new tab perf, so I suspect it's the extra round trip to the UI thread when trying to load the CSS (the UI thread is probably just busy at that time). Instead, I'm moving the generation of the CSS to the time the object is constructed, rather than when the resource is requested. This is like the code before, except sometimes we'll hit the cache. BUG=26228 Review URL: http://codereview.chromium.org/427003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@32815 0039d316-1c4b-4281-b951-d872f2087c98
-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_;