Commit a72da1c5 authored by Kristi Park's avatar Kristi Park Committed by Commit Bot

[NTP] Do not use dark mode chips if a background image is set

Do not use dark mode chips (i.e. Most Visited icons, Vasco, fakebox,
etc.) if a background image is applied to the NTP. This includes custom
backgrounds and images from themes.

In order to keep compatibility with M73 versions and Vasco, we use the
negation ":not(.light-chip)" instead of a positive selector such as
".dark-chip".

Bug: 928548
Change-Id: I0284e08485810ce3aad29a288ce4ad21042e7567
Reviewed-on: https://chromium-review.googlesource.com/c/1475207Reviewed-by: default avatarKyle Milka <kmilka@chromium.org>
Commit-Queue: Kristi Park <kristipark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#635847}
parent aa88ab28
......@@ -44,7 +44,7 @@ html {
height: 100%;
}
html[darkmode=true] {
html[darkmode=true] body:not(.light-chip) {
/* These can be overridden by themes. */
--text-color: rgb(var(--GG200-rgb));
--text-color-light: rgb(var(--GG200-rgb));
......@@ -148,7 +148,7 @@ body.remove-fakebox #fakebox-container {
transition: background-color 300ms ease-in-out, opacity 200ms
}
html[darkmode=true] #fakebox {
html[darkmode=true] body:not(.light-chip) #fakebox {
background-color: rgb(var(--GG900-rgb));
}
......@@ -156,7 +156,7 @@ html[darkmode=true] #fakebox {
background-color: rgb(var(--GG200-rgb));
}
html[darkmode=true] #fakebox:hover {
html[darkmode=true] body:not(.light-chip) #fakebox:hover {
background-color: rgb(42, 43, 46);
}
......@@ -199,7 +199,7 @@ html[dir=rtl] #fakebox > input {
white-space: nowrap;
}
html[darkmode=true] #fakebox-text {
html[darkmode=true] body:not(.light-chip) #fakebox-text {
color: rgb(var(--GG200-rgb));
}
......@@ -223,7 +223,7 @@ html[dir=rtl] #fakebox-cursor {
right: 20px;
}
html[darkmode=true] #fakebox-cursor {
html[darkmode=true] body:not(.light-chip) #fakebox-cursor {
background: rgb(var(--GB300-rgb));
}
......@@ -330,7 +330,7 @@ body.remove-fakebox #user-content {
width: 16px;
}
html[darkmode=true] #mv-notice-x {
html[darkmode=true] body:not(.light-chip) #mv-notice-x {
background-color: rgb(var(--GG200-rgb));
}
......@@ -342,8 +342,8 @@ html[darkmode=true] #mv-notice-x {
background-color: rgb(var(--GB500-rgb));
}
html[darkmode=true] #mv-notice-x:hover,
html[darkmode=true] #mv-notice-x:active {
html[darkmode=true] body:not(.light-chip) #mv-notice-x:hover,
html[darkmode=true] body:not(.light-chip) #mv-notice-x:active {
background-color: rgb(var(--GG400-rgb));
}
......@@ -403,7 +403,7 @@ html[darkmode=true] #mv-notice-x:active {
width: fit-content;
}
html[darkmode=true] .md-icons #mv-notice {
html[darkmode=true] body:not(.light-chip) .md-icons #mv-notice {
background-color: rgb(var(--GG900-rgb));
border-color: rgba(0, 0, 0, 0.1);
}
......@@ -423,7 +423,7 @@ html[darkmode=true] .md-icons #mv-notice {
vertical-align: unset;
}
html[darkmode=true] .md-icons #mv-notice span {
html[darkmode=true] body:not(.light-chip) .md-icons #mv-notice span {
color: rgb(var(--GG200-rgb));
}
......@@ -445,7 +445,7 @@ html[darkmode=true] .md-icons #mv-notice span {
position: relative;
}
html[darkmode=true] .md-icons #mv-notice-links span {
html[darkmode=true] body:not(.light-chip) .md-icons #mv-notice-links span {
color: rgb(var(--GB400-dark-rgb));
}
......@@ -461,8 +461,8 @@ html[darkmode=true] .md-icons #mv-notice-links span {
transition: background-color 200ms;
}
html[darkmode=true] .md-icons #mv-notice-links span:hover,
html[darkmode=true] .md-icons #mv-notice-links span:active {
html[darkmode=true] body:not(.light-chip) .md-icons #mv-notice-links span:hover,
html[darkmode=true] body:not(.light-chip) .md-icons #mv-notice-links span:active {
background-color: rgba(var(--GB400-dark-rgb), 0.1);
}
......@@ -482,8 +482,8 @@ html[darkmode=true] .md-icons #mv-notice-links span:active {
color: #fff;
}
html[darkmode=true] .default-theme.dark #mv-msg :not(.md-icons),
html[darkmode=true] .default-theme.dark #mv-notice-links :not(.md-icons) span {
html[darkmode=true] body:not(.light-chip) .default-theme.dark #mv-msg :not(.md-icons),
html[darkmode=true] body:not(.light-chip) .default-theme.dark #mv-notice-links :not(.md-icons) span {
color: rgb(var(--GG200-rgb));
}
......@@ -661,7 +661,7 @@ input:checked + .toggle::before {
width: fit-content;
}
html[darkmode=true] #error-notice {
html[darkmode=true] body:not(.light-chip) #error-notice {
background-color: rgb(var(--GG900-rgb));
border-color: rgba(0, 0, 0, 0.1);
color: rgb(var(--GR500-dark-rgb));
......@@ -709,7 +709,7 @@ html[dir=rtl] #error-notice.has-link #error-notice-msg {
position: relative;
}
html[darkmode=true] #error-notice-link {
html[darkmode=true] body:not(.light-chip) #error-notice-link {
color: rgb(var(--GB400-dark-rgb));
}
......@@ -729,8 +729,8 @@ html[darkmode=true] #error-notice-link {
transition: background-color 200ms;
}
html[darkmode=true] #error-notice-link:hover,
html[darkmode=true] #error-notice-link:active {
html[darkmode=true] body:not(.light-chip) #error-notice-link:hover,
html[darkmode=true] body:not(.light-chip) #error-notice-link:active {
background-color: rgba(var(--GB400-dark-rgb), 0.1);
}
......@@ -767,7 +767,7 @@ html[darkmode=true] #error-notice-link:active {
white-space: nowrap;
}
html[darkmode=true] #promo > div {
html[darkmode=true] body:not(.light-chip) #promo > div {
background-color: rgb(var(--GG900-rgb));
border-color: rgba(0, 0, 0, 0.1);
color: rgb(var(--GG200-rgb));
......@@ -794,8 +794,8 @@ html[darkmode=true] #promo > div {
color: rgb(51, 103, 214) !important;
}
html[darkmode=true] #promo > div > a,
html[darkmode=true] #promo > div > a:visited {
html[darkmode=true] body:not(.light-chip) #promo > div > a,
html[darkmode=true] body:not(.light-chip) #promo > div > a:visited {
color: rgb(var(--GB400-dark-rgb)) !important;
}
......@@ -808,7 +808,7 @@ html[darkmode=true] #promo > div > a:visited {
width: 24px;
}
html[darkmode=true] #promo > div > img {
html[darkmode=true] body:not(.light-chip) #promo > div > img {
background-color: rgb(var(--GG200-rgb));
}
......
......@@ -266,6 +266,13 @@ var ntpApiHandle;
let isDarkModeEnabled = false;
/**
* True if dark colored chips should be used instead of light mode chips when
* dark mode is enabled.
* @type {boolean}
*/
let useDarkChips = false;
/**
* Returns a timeout that can be executed early.
* @param {!Function} timeout The timeout function.
......@@ -341,6 +348,21 @@ function getIsThemeDark() {
return luminance >= 128;
}
/**
* Determine whether dark chips should be used if dark mode is enabled. This is
* is the case when dark mode is enabled and a background image (from a custom
* background or user theme) is not set.
*
* @param {ThemeBackgroundInfo|undefined} info Theme background information.
* @return {boolean} Whether the chips should be dark.
* @private
*/
function getUseDarkChips(info) {
return info.usingDarkMode && !info.imageUrl;
}
/**
* Updates the NTP based on the current theme.
* @private
......@@ -353,11 +375,11 @@ function renderTheme() {
return;
}
const useDarkMode = !!info.usingDarkMode;
if (isDarkModeEnabled != useDarkMode) {
document.documentElement.setAttribute('darkmode', useDarkMode);
isDarkModeEnabled = useDarkMode;
}
// Update dark mode styling.
isDarkModeEnabled = info.usingDarkMode;
useDarkChips = getUseDarkChips(info);
document.documentElement.setAttribute('darkmode', isDarkModeEnabled);
document.body.classList.toggle('light-chip', !useDarkChips);
var background = [
convertToRGBAColor(info.backgroundColorRgba), info.imageUrl,
......@@ -451,7 +473,7 @@ function sendThemeInfoToMostVisitedIframe() {
var message = {cmd: 'updateTheme'};
message.isThemeDark = isThemeDark;
message.isUsingTheme = !info.usingDefaultTheme;
message.isDarkMode = !!info.usingDarkMode;
message.isDarkMode = getUseDarkChips(info);
var titleColor = NTP_DESIGN.titleColor;
if (!info.usingDefaultTheme && info.textColorRgba) {
......@@ -480,7 +502,7 @@ function sendThemeInfoToEditCustomLinkIframe() {
}
let message = {cmd: 'updateTheme'};
message.isDarkMode = !!info.usingDarkMode;
message.isDarkMode = info.usingDarkMode;
$(IDS.CUSTOM_LINKS_EDIT_IFRAME).contentWindow.postMessage(message, '*');
}
......@@ -515,7 +537,7 @@ function renderOneGoogleBarTheme() {
*/
function onThemeChange() {
// Save the current dark mode state to check if dark mode has changed.
const usingDarkMode = isDarkModeEnabled;
const usingDarkChips = useDarkChips;
renderTheme();
renderOneGoogleBarTheme();
......@@ -524,7 +546,7 @@ function onThemeChange() {
// If dark mode has been changed, refresh the MV tiles to render the
// appropriate icon.
if (usingDarkMode != isDarkModeEnabled) {
if (usingDarkChips != useDarkChips) {
reloadTiles();
}
}
......@@ -636,7 +658,7 @@ function reloadTiles() {
let maxNumTiles = configData.isGooglePage ? MAX_NUM_TILES_CUSTOM_LINKS :
MAX_NUM_TILES_MOST_VISITED;
for (var i = 0; i < Math.min(maxNumTiles, pages.length); ++i) {
cmds.push({cmd: 'tile', rid: pages[i].rid, darkMode: isDarkModeEnabled});
cmds.push({cmd: 'tile', rid: pages[i].rid, darkMode: useDarkChips});
}
cmds.push({cmd: 'show'});
......
......@@ -89,6 +89,9 @@ struct ParsedNtpIconPath {
// The device scale factor of the requested icon.
float device_scale_factor = 1.0;
// True if a dark mode icon should be used.
bool is_dark_mode = false;
};
// Returns true if |search| is a substring of |path| which starts at
......@@ -135,9 +138,10 @@ const ParsedNtpIconPath ParseNtpIconPath(const std::string& path) {
parsed_index = slash + 1;
// Parse the dark mode spec (e.g. "dark"), if available. The value is not
// used, but is required to generate a new icon for dark mode.
// Parse the dark mode spec (e.g. "dark"). If present, render a dark mode
// icon.
if (HasSubstringAt(path, parsed_index, kDarkModeParameter)) {
parsed.is_dark_mode = true;
slash = path.find("/", parsed_index);
if (slash == std::string::npos)
return parsed;
......@@ -216,12 +220,13 @@ SkColor GetBackgroundColorForUrl(const GURL& icon_url) {
}
// For the given |icon_url|, will render |favicon| within a gray, circular
// background. If |favicon| is not specifed, will use a colored circular
// monogram instead.
// background (dark gray if |is_dark_mode|). If |favicon| is not specifed, will
// use a colored circular monogram instead.
std::vector<unsigned char> RenderIconBitmap(const GURL& icon_url,
const SkBitmap& favicon,
int icon_size,
int fallback_size) {
int fallback_size,
bool is_dark_mode) {
SkBitmap bitmap;
bitmap.allocN32Pixels(icon_size, icon_size, false);
cc::SkiaPaintCanvas paint_canvas(bitmap);
......@@ -229,10 +234,7 @@ std::vector<unsigned char> RenderIconBitmap(const GURL& icon_url,
canvas.DrawColor(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
// Draw the gray background.
SkColor favicon_bg =
ui::NativeTheme::GetInstanceForNativeUi()->SystemDarkModeEnabled()
? gfx::kGoogleGrey900
: gfx::kGoogleGrey100;
SkColor favicon_bg = is_dark_mode ? gfx::kGoogleGrey900 : gfx::kGoogleGrey100;
DrawCircleInCanvas(&canvas, icon_size, /*offset=*/0,
/*background_color=*/favicon_bg);
DrawFavicon(favicon, &canvas, icon_size);
......@@ -259,11 +261,13 @@ struct NtpIconSource::NtpIconRequest {
NtpIconRequest(const content::URLDataSource::GotDataCallback& cb,
const GURL& path,
int icon_size_in_pixels,
float scale)
float scale,
bool is_dark_mode)
: callback(cb),
path(path),
icon_size_in_pixels(icon_size_in_pixels),
device_scale_factor(scale) {}
device_scale_factor(scale),
is_dark_mode(is_dark_mode) {}
NtpIconRequest(const NtpIconRequest& other) = default;
~NtpIconRequest() {}
......@@ -271,6 +275,7 @@ struct NtpIconSource::NtpIconRequest {
GURL path;
int icon_size_in_pixels;
float device_scale_factor;
bool is_dark_mode;
};
NtpIconSource::NtpIconSource(Profile* profile)
......@@ -301,7 +306,7 @@ void NtpIconSource::StartDataRequest(
int icon_size_in_pixels =
std::ceil(parsed.size_in_dip * parsed.device_scale_factor);
NtpIconRequest request(callback, parsed.url, icon_size_in_pixels,
parsed.device_scale_factor);
parsed.device_scale_factor, parsed.is_dark_mode);
// Check if the requested URL is part of the prepopulated pages (currently,
// only the Web Store).
......@@ -471,6 +476,6 @@ void NtpIconSource::ReturnRenderedIconForRequest(const NtpIconRequest& request,
std::round(kFallbackSizeDip * request.device_scale_factor * 0.5) * 2.0;
std::vector<unsigned char> bitmap_data =
RenderIconBitmap(request.path, bitmap, desired_overall_size_in_pixel,
desired_fallback_size_in_pixel);
desired_fallback_size_in_pixel, request.is_dark_mode);
request.callback.Run(base::RefCountedBytes::TakeVector(&bitmap_data));
}
......@@ -194,8 +194,13 @@ v8::Local<v8::Object> GenerateThemeBackgroundInfo(
const ThemeBackgroundInfo& theme_info) {
gin::DataObjectBuilder builder(isolate);
// True if the theme is the system default and no custom theme has been
// applied.
// Value is always valid.
builder.Set("usingDefaultTheme", theme_info.using_default_theme);
// True if dark mode should be applied to the NTP.
// Value is always valid.
builder.Set("usingDarkMode", theme_info.using_dark_mode);
// The theme background color is in RGBA format "rgba(R,G,B,A)" where R, G and
......
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