Commit 2e32e74b authored by Aran Gilman's avatar Aran Gilman Committed by Commit Bot

Make DOM Distiller's font and theme code more resilient.

The existing code relies on the document body's class list following a
specific format. This CL allows for an arbitrary class list, which in
turn makes it easier to update the theme on other elements. (This will
be needed for the appearance settings, assuming the settings are put in
the web contents.)

This CL also reworks how the JS font/theme maps to the CSS font/theme.
The JS and CSS strings are always the same, so we can just verify that
the JS string is one of the expected ones before returning it.

The associated browser tests are also modified to no longer expect a
specific class order. Monospace is used instead of serif to make
substring matching less complicated.

Bug: 952034
Change-Id: I99d61dd3a3edcfe66f52169309105d1e235b937a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1684251Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Commit-Queue: Aran Gilman <gilmanmh@google.com>
Cr-Commit-Position: refs/heads/master@{#676064}
parent 0cb8577f
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
#include "content/public/common/isolated_world_ids.h" #include "content/public/common/isolated_world_ids.h"
#include "content/public/test/browser_test_utils.h" #include "content/public/test/browser_test_utils.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
...@@ -102,6 +103,16 @@ ArticleEntry CreateEntry(const std::string& entry_id, ...@@ -102,6 +103,16 @@ ArticleEntry CreateEntry(const std::string& entry_id,
return entry; return entry;
} }
void ExpectBodyHasThemeAndFont(content::WebContents* contents,
const std::string& expected_theme,
const std::string& expected_font) {
std::string result;
EXPECT_TRUE(
content::ExecuteScriptAndExtractString(contents, kGetBodyClass, &result));
EXPECT_THAT(result, HasSubstr(expected_theme));
EXPECT_THAT(result, HasSubstr(expected_font));
}
} // namespace } // namespace
class DomDistillerViewerSourceBrowserTest : public InProcessBrowserTest { class DomDistillerViewerSourceBrowserTest : public InProcessBrowserTest {
...@@ -557,10 +568,7 @@ void DomDistillerViewerSourceBrowserTest::PrefTest(bool is_error_page) { ...@@ -557,10 +568,7 @@ void DomDistillerViewerSourceBrowserTest::PrefTest(bool is_error_page) {
browser()->tab_strip_model()->GetActiveWebContents(); browser()->tab_strip_model()->GetActiveWebContents();
ViewSingleDistilledPage(url, "text/html"); ViewSingleDistilledPage(url, "text/html");
content::WaitForLoadStop(contents); content::WaitForLoadStop(contents);
std::string result; ExpectBodyHasThemeAndFont(contents, "light", "sans-serif");
EXPECT_TRUE(
content::ExecuteScriptAndExtractString(contents, kGetBodyClass, &result));
EXPECT_EQ("light sans-serif", result);
DistilledPagePrefs* distilled_page_prefs = DistilledPagePrefs* distilled_page_prefs =
DomDistillerServiceFactory::GetForBrowserContext(browser()->profile()) DomDistillerServiceFactory::GetForBrowserContext(browser()->profile())
...@@ -569,21 +577,19 @@ void DomDistillerViewerSourceBrowserTest::PrefTest(bool is_error_page) { ...@@ -569,21 +577,19 @@ void DomDistillerViewerSourceBrowserTest::PrefTest(bool is_error_page) {
// Test theme. // Test theme.
distilled_page_prefs->SetTheme(DistilledPagePrefs::THEME_DARK); distilled_page_prefs->SetTheme(DistilledPagePrefs::THEME_DARK);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_TRUE( ExpectBodyHasThemeAndFont(contents, "dark", "sans-serif");
content::ExecuteScriptAndExtractString(contents, kGetBodyClass, &result));
EXPECT_EQ("dark sans-serif", result);
// Verify that the theme color for the tab is updated as well. // Verify that the theme color for the tab is updated as well.
EXPECT_EQ(kDarkToolbarThemeColor, contents->GetThemeColor()); EXPECT_EQ(kDarkToolbarThemeColor, contents->GetThemeColor());
// Test font family. // Test font family.
distilled_page_prefs->SetFontFamily(DistilledPagePrefs::FONT_FAMILY_SERIF); distilled_page_prefs->SetFontFamily(
DistilledPagePrefs::FONT_FAMILY_MONOSPACE);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_TRUE( ExpectBodyHasThemeAndFont(contents, "dark", "monospace");
content::ExecuteScriptAndExtractString(contents, kGetBodyClass, &result));
EXPECT_EQ("dark serif", result);
// Test font scaling. // Test font scaling.
std::string result;
EXPECT_TRUE( EXPECT_TRUE(
content::ExecuteScriptAndExtractString(contents, kGetFontSize, &result)); content::ExecuteScriptAndExtractString(contents, kGetFontSize, &result));
double oldFontSize; double oldFontSize;
...@@ -621,13 +627,13 @@ IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, PrefPersist) { ...@@ -621,13 +627,13 @@ IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, PrefPersist) {
// Set preference. // Set preference.
const double kScale = 1.23; const double kScale = 1.23;
distilled_page_prefs->SetTheme(DistilledPagePrefs::THEME_DARK); distilled_page_prefs->SetTheme(DistilledPagePrefs::THEME_DARK);
distilled_page_prefs->SetFontFamily(DistilledPagePrefs::FONT_FAMILY_SERIF); distilled_page_prefs->SetFontFamily(
DistilledPagePrefs::FONT_FAMILY_MONOSPACE);
distilled_page_prefs->SetFontScaling(kScale); distilled_page_prefs->SetFontScaling(kScale);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_TRUE( ExpectBodyHasThemeAndFont(contents, "dark", "monospace");
content::ExecuteScriptAndExtractString(contents, kGetBodyClass, &result));
EXPECT_EQ("dark serif", result);
EXPECT_EQ(kDarkToolbarThemeColor, contents->GetThemeColor()); EXPECT_EQ(kDarkToolbarThemeColor, contents->GetThemeColor());
EXPECT_TRUE( EXPECT_TRUE(
content::ExecuteScriptAndExtractString(contents, kGetFontSize, &result)); content::ExecuteScriptAndExtractString(contents, kGetFontSize, &result));
...@@ -643,7 +649,7 @@ IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, PrefPersist) { ...@@ -643,7 +649,7 @@ IN_PROC_BROWSER_TEST_F(DomDistillerViewerSourceBrowserTest, PrefPersist) {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_TRUE( EXPECT_TRUE(
content::ExecuteScriptAndExtractString(contents, kGetBodyClass, &result)); content::ExecuteScriptAndExtractString(contents, kGetBodyClass, &result));
EXPECT_EQ("dark serif", result); ExpectBodyHasThemeAndFont(contents, "dark", "monospace");
EXPECT_EQ(kDarkToolbarThemeColor, contents->GetThemeColor()); EXPECT_EQ(kDarkToolbarThemeColor, contents->GetThemeColor());
EXPECT_TRUE( EXPECT_TRUE(
......
...@@ -58,46 +58,53 @@ function setTextDirection(direction) { ...@@ -58,46 +58,53 @@ function setTextDirection(direction) {
document.body.setAttribute('dir', direction); document.body.setAttribute('dir', direction);
} }
// Maps JS Font Family to CSS class and then changes body class name. function removeAll(source, elementsToRemove) {
// CSS classes must agree with distilledpage.css. elementsToRemove.forEach(function(element) {
function useFontFamily(fontFamily) { source.remove(element)
var cssClass; });
if (fontFamily == 'serif') { }
cssClass = 'serif';
} else if (fontFamily == 'monospace') { // These classes must agree with the font classes in distilledpage.css.
cssClass = 'monospace'; const fontFamilyClasses = ['sans-serif', 'serif', 'monospace'];
} else { function getFontFamilyClass(fontFamily) {
cssClass = 'sans-serif'; if (fontFamilyClasses.includes(fontFamily)) {
return fontFamily;
} }
// Relies on the classname order of the body being Theme class, then Font return fontFamilyClasses[0];
// Family class.
var themeClass = document.body.className.split(' ')[0];
document.body.className = themeClass + ' ' + cssClass;
} }
// Maps JS theme to CSS class and then changes body class name. function useFontFamily(fontFamily) {
// CSS classes must agree with distilledpage.css. removeAll(document.body.classList, fontFamilyClasses);
function useTheme(theme) { document.body.classList.add(getFontFamilyClass(fontFamily));
var cssClass; }
if (theme == 'sepia') {
cssClass = 'sepia'; // These classes must agree with the theme classes in distilledpage.css.
} else if (theme == 'dark') { const themeClasses = ['light', 'dark', 'sepia'];
cssClass = 'dark'; function getThemeClass(theme) {
} else { if (themeClasses.includes(theme)) {
cssClass = 'light'; return theme;
} }
// Relies on the classname order of the body being Theme class, then Font return themeClasses[0];
// Family class. }
var fontFamilyClass = document.body.className.split(' ')[1];
document.body.className = cssClass + ' ' + fontFamilyClass;
function useTheme(theme) {
removeAll(document.body.classList, themeClasses);
document.body.classList.add(getThemeClass(theme));
updateToolbarColor(); updateToolbarColor();
} }
function getThemeFromElement(element) {
var foundTheme = themeClasses[0];
themeClasses.forEach(function(theme) {
if (element.classList.contains(theme)) {
foundTheme = theme;
}
});
return foundTheme;
}
function updateToolbarColor() { function updateToolbarColor() {
// Relies on the classname order of the body being Theme class, then Font var themeClass = getThemeFromElement(document.body);
// Family class.
var themeClass = document.body.className.split(' ')[0];
var toolbarColor; var toolbarColor;
if (themeClass == 'sepia') { if (themeClass == 'sepia') {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment