diff options
-rw-r--r-- | chrome/browser/cocoa/bug_report_window_controller_unittest.mm | 1 | ||||
-rw-r--r-- | chrome/browser/dom_ui/chrome_url_data_manager.h | 2 | ||||
-rw-r--r-- | chrome/browser/dom_ui/dom_ui_theme_source.cc | 243 | ||||
-rw-r--r-- | chrome/browser/dom_ui/dom_ui_theme_source.h | 32 | ||||
-rw-r--r-- | chrome/browser/dom_ui/dom_ui_theme_source_unittest.cc | 6 | ||||
-rw-r--r-- | chrome/browser/dom_ui/dom_ui_unittest.cc | 4 | ||||
-rw-r--r-- | chrome/browser/dom_ui/ntp_resource_cache.cc | 257 | ||||
-rw-r--r-- | chrome/browser/dom_ui/ntp_resource_cache.h | 11 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_host_manager_unittest.cc | 3 | ||||
-rw-r--r-- | chrome/test/testing_profile.cc | 7 | ||||
-rw-r--r-- | chrome/test/testing_profile.h | 4 |
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_; |