Commit 754f0893 authored by Dan Beam's avatar Dan Beam Committed by Commit Bot

Local NTP: show favicons in the realbox

Bug: 1003210
Change-Id: I89ed4851798663207098743fd551a378fbd1060b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1834231Reviewed-by: default avatarMoe Ahmadi <mahmadi@chromium.org>
Commit-Queue: Dan Beam <dbeam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704049}
parent 6f7507f9
...@@ -217,6 +217,9 @@ body.hide-fakebox #fakebox { ...@@ -217,6 +217,9 @@ body.hide-fakebox #fakebox {
} }
#realbox-matches a { #realbox-matches a {
background-position: 16px center;
background-repeat: no-repeat;
background-size: 24px;
font-size: 16px; font-size: 16px;
overflow: hidden; overflow: hidden;
padding-bottom: 8px; padding-bottom: 8px;
...@@ -229,6 +232,10 @@ body.hide-fakebox #fakebox { ...@@ -229,6 +232,10 @@ body.hide-fakebox #fakebox {
white-space: nowrap; white-space: nowrap;
} }
[dir=rtl] #realbox-matches a {
background-position-x: calc(100% - 16px);
}
#realbox-matches a.removable { #realbox-matches a.removable {
padding-inline-end: 48px; padding-inline-end: 48px;
} }
...@@ -237,7 +244,8 @@ body.hide-fakebox #fakebox { ...@@ -237,7 +244,8 @@ body.hide-fakebox #fakebox {
-webkit-mask-size: 16px; -webkit-mask-size: 16px;
} }
#realbox-matches :-webkit-any(.clock-icon, .url-icon) { #realbox-matches .clock-icon {
-webkit-mask-image: url(icons/clock.svg);
-webkit-mask-position: center; -webkit-mask-position: center;
-webkit-mask-repeat: no-repeat; -webkit-mask-repeat: no-repeat;
-webkit-mask-size: 16px; -webkit-mask-size: 16px;
...@@ -249,24 +257,16 @@ body.hide-fakebox #fakebox { ...@@ -249,24 +257,16 @@ body.hide-fakebox #fakebox {
width: 24px; width: 24px;
} }
#realbox-matches .clock-icon { html[dir=rtl] #realbox-matches .clock-icon {
-webkit-mask-image: url(icons/clock.svg);
}
#realbox-matches .url-icon {
-webkit-mask-image: url(../../../../components/neterror/resources/images/generic-globe.svg);
}
html[dir=rtl] #realbox-matches :-webkit-any(.clock-icon, .url-icon) {
right: 16px; right: 16px;
} }
#realbox-matches a:hover { #realbox-matches a:hover {
background: rgb(var(--GG100-rgb)); background-color: rgb(var(--GG100-rgb));
} }
#realbox-matches a.selected { #realbox-matches a.selected {
background: rgb(var(--GG200-rgb)); background-color: rgb(var(--GG200-rgb));
} }
#realbox-matches .match { #realbox-matches .match {
...@@ -296,11 +296,11 @@ html[dir=rtl] #realbox-matches :-webkit-any(.clock-icon, .url-icon) { ...@@ -296,11 +296,11 @@ html[dir=rtl] #realbox-matches :-webkit-any(.clock-icon, .url-icon) {
} }
#realbox-matches .remove-match:hover { #realbox-matches .remove-match:hover {
background: rgba(var(--GG900-rgb), .08); background-color: rgba(var(--GG900-rgb), .08);
} }
#realbox-matches .remove-match:focus-within { #realbox-matches .remove-match:focus-within {
background: rgba(var(--GG900-rgb), .16); background-color: rgba(var(--GG900-rgb), .16);
} }
#realbox-matches .remove-icon { #realbox-matches .remove-icon {
......
...@@ -100,7 +100,6 @@ const CLASSES = { ...@@ -100,7 +100,6 @@ const CLASSES = {
SHOW_ELEMENT: 'show-element', SHOW_ELEMENT: 'show-element',
// When the realbox has matches to show. // When the realbox has matches to show.
SHOW_MATCHES: 'show-matches', SHOW_MATCHES: 'show-matches',
URL_ICON: 'url-icon', // Global/favicon/url icon.
// Applied when the doodle notifier should be shown instead of the doodle. // Applied when the doodle notifier should be shown instead of the doodle.
USE_NOTIFIER: 'use-notifier', USE_NOTIFIER: 'use-notifier',
}; };
...@@ -1400,17 +1399,20 @@ function populateAutocompleteMatches(matches) { ...@@ -1400,17 +1399,20 @@ function populateAutocompleteMatches(matches) {
matchEl.href = match.destinationUrl; matchEl.href = match.destinationUrl;
matchEl.role = 'option'; matchEl.role = 'option';
let iconClass;
if (match.isSearchType) { if (match.isSearchType) {
const icon = document.createElement('div');
const isSearchHistory = SEARCH_HISTORY_MATCH_TYPES.includes(match.type); const isSearchHistory = SEARCH_HISTORY_MATCH_TYPES.includes(match.type);
iconClass = isSearchHistory ? CLASSES.CLOCK_ICON : CLASSES.SEARCH_ICON; icon.classList.add(
isSearchHistory ? CLASSES.CLOCK_ICON : CLASSES.SEARCH_ICON);
matchEl.appendChild(icon);
} else { } else {
// TODO(crbug.com/997229): use chrome://favicon/<url> when perms allow. // TODO(crbug.com/997229): use chrome://favicon/<url> when perms allow.
iconClass = CLASSES.URL_ICON; const iconUrl = new URL('chrome-search://ntpicon/');
iconUrl.searchParams.set('show_fallback_monogram', 'false');
iconUrl.searchParams.set('size', '24@' + window.devicePixelRatio + 'x');
iconUrl.searchParams.set('url', match.destinationUrl);
matchEl.style.backgroundImage = 'url(' + iconUrl.toString() + ')';
} }
const icon = document.createElement('div');
icon.classList.add(assert(iconClass));
matchEl.appendChild(icon);
const contentsEls = const contentsEls =
renderMatchClassifications(match.contents, match.contentsClass); renderMatchClassifications(match.contents, match.contentsClass);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "cc/paint/skia_paint_canvas.h" #include "cc/paint/skia_paint_canvas.h"
#include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/favicon/favicon_utils.h"
#include "chrome/browser/history/top_sites_factory.h" #include "chrome/browser/history/top_sites_factory.h"
#include "chrome/browser/image_fetcher/image_decoder_impl.h" #include "chrome/browser/image_fetcher/image_decoder_impl.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -65,11 +66,13 @@ const char kIconSourceUmaClientName[] = "NtpIconSource"; ...@@ -65,11 +66,13 @@ const char kIconSourceUmaClientName[] = "NtpIconSource";
// changing the algorithm in RenderIconBitmap() that guarantees contrast. // changing the algorithm in RenderIconBitmap() that guarantees contrast.
constexpr SkColor kFallbackIconLetterColor = SK_ColorWHITE; constexpr SkColor kFallbackIconLetterColor = SK_ColorWHITE;
const char kShowFallbackMonogramParam[] = "show_fallback_monogram";
// The requested size of the icon. // The requested size of the icon.
const char kSizeParameter[] = "size"; const char kSizeParam[] = "size";
// The URL for which to create an icon. // The URL for which to create an icon.
const char kUrlParameter[] = "url"; const char kUrlParam[] = "url";
// Size of the icon background (gray circle), in dp. // Size of the icon background (gray circle), in dp.
const int kIconSizeDip = 48; const int kIconSizeDip = 48;
...@@ -95,6 +98,9 @@ struct ParsedNtpIconPath { ...@@ -95,6 +98,9 @@ struct ParsedNtpIconPath {
// The device scale factor of the requested icon. // The device scale factor of the requested icon.
float device_scale_factor = 1.0; float device_scale_factor = 1.0;
// Whether to show a circle + letter monogram if an icon is unable.
bool show_fallback_monogram = true;
}; };
float GetMaxDeviceScaleFactor() { float GetMaxDeviceScaleFactor() {
...@@ -107,8 +113,9 @@ float GetMaxDeviceScaleFactor() { ...@@ -107,8 +113,9 @@ float GetMaxDeviceScaleFactor() {
// "?size=24@2x&url=https%3A%2F%2Fcnn.com" // "?size=24@2x&url=https%3A%2F%2Fcnn.com"
const ParsedNtpIconPath ParseNtpIconPath(const std::string& path) { const ParsedNtpIconPath ParseNtpIconPath(const std::string& path) {
ParsedNtpIconPath parsed; ParsedNtpIconPath parsed;
parsed.url = GURL(); parsed.show_fallback_monogram = true;
parsed.size_in_dip = gfx::kFaviconSize; parsed.size_in_dip = gfx::kFaviconSize;
parsed.url = GURL();
if (path.empty()) if (path.empty())
return parsed; return parsed;
...@@ -121,7 +128,9 @@ const ParsedNtpIconPath ParseNtpIconPath(const std::string& path) { ...@@ -121,7 +128,9 @@ const ParsedNtpIconPath ParseNtpIconPath(const std::string& path) {
for (net::QueryIterator it(request); !it.IsAtEnd(); it.Advance()) { for (net::QueryIterator it(request); !it.IsAtEnd(); it.Advance()) {
std::string key = it.GetKey(); std::string key = it.GetKey();
if (key == kSizeParameter) { if (key == kShowFallbackMonogramParam) {
parsed.show_fallback_monogram = it.GetUnescapedValue() != "false";
} else if (key == kSizeParam) {
std::vector<std::string> pieces = std::vector<std::string> pieces =
base::SplitString(it.GetUnescapedValue(), "@", base::TRIM_WHITESPACE, base::SplitString(it.GetUnescapedValue(), "@", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY); base::SPLIT_WANT_NONEMPTY);
...@@ -138,7 +147,7 @@ const ParsedNtpIconPath ParseNtpIconPath(const std::string& path) { ...@@ -138,7 +147,7 @@ const ParsedNtpIconPath ParseNtpIconPath(const std::string& path) {
parsed.device_scale_factor = parsed.device_scale_factor =
std::min(scale_factor, GetMaxDeviceScaleFactor()); std::min(scale_factor, GetMaxDeviceScaleFactor());
} }
} else if (key == kUrlParameter) { } else if (key == kUrlParam) {
parsed.url = GURL(it.GetUnescapedValue()); parsed.url = GURL(it.GetUnescapedValue());
} }
} }
...@@ -218,17 +227,18 @@ SkColor GetBackgroundColorForUrl(const GURL& icon_url) { ...@@ -218,17 +227,18 @@ SkColor GetBackgroundColorForUrl(const GURL& icon_url) {
std::vector<unsigned char> RenderIconBitmap(const GURL& icon_url, std::vector<unsigned char> RenderIconBitmap(const GURL& icon_url,
const SkBitmap& favicon, const SkBitmap& favicon,
int icon_size, int icon_size,
int fallback_size) { int fallback_size,
bool show_fallback_monogram,
float device_scale_factor) {
SkBitmap bitmap; SkBitmap bitmap;
bitmap.allocN32Pixels(icon_size, icon_size, false); bitmap.allocN32Pixels(icon_size, icon_size, false);
cc::SkiaPaintCanvas paint_canvas(bitmap); cc::SkiaPaintCanvas paint_canvas(bitmap);
gfx::Canvas canvas(&paint_canvas, 1.f); gfx::Canvas canvas(&paint_canvas, 1.f);
canvas.DrawColor(SK_ColorTRANSPARENT, SkBlendMode::kSrc); canvas.DrawColor(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
DrawFavicon(favicon, &canvas, icon_size);
// If necessary, draw the colored fallback monogram. // If necessary, draw the colored fallback monogram.
if (favicon.empty()) { if (favicon.empty()) {
if (show_fallback_monogram) {
SkColor fallback_color = SkColor fallback_color =
color_utils::BlendForMinContrast(GetBackgroundColorForUrl(icon_url), color_utils::BlendForMinContrast(GetBackgroundColorForUrl(icon_url),
kFallbackIconLetterColor) kFallbackIconLetterColor)
...@@ -237,6 +247,17 @@ std::vector<unsigned char> RenderIconBitmap(const GURL& icon_url, ...@@ -237,6 +247,17 @@ std::vector<unsigned char> RenderIconBitmap(const GURL& icon_url,
int offset = (icon_size - fallback_size) / 2; int offset = (icon_size - fallback_size) / 2;
DrawCircleInCanvas(&canvas, fallback_size, offset, fallback_color); DrawCircleInCanvas(&canvas, fallback_size, offset, fallback_color);
DrawFallbackIconLetter(icon_url, icon_size, &canvas); DrawFallbackIconLetter(icon_url, icon_size, &canvas);
} else {
const auto* default_favicon = favicon::GetDefaultFavicon().ToImageSkia();
const auto& rep = default_favicon->GetRepresentation(device_scale_factor);
gfx::ImageSkia scaled_image(rep);
const auto resized = gfx::ImageSkiaOperations::CreateResizedImage(
scaled_image, skia::ImageOperations::RESIZE_BEST,
gfx::Size(fallback_size, fallback_size));
DrawFavicon(*resized.bitmap(), &canvas, icon_size);
}
} else {
DrawFavicon(favicon, &canvas, icon_size);
} }
std::vector<unsigned char> bitmap_data; std::vector<unsigned char> bitmap_data;
...@@ -251,11 +272,13 @@ struct NtpIconSource::NtpIconRequest { ...@@ -251,11 +272,13 @@ struct NtpIconSource::NtpIconRequest {
NtpIconRequest(const content::URLDataSource::GotDataCallback& cb, NtpIconRequest(const content::URLDataSource::GotDataCallback& cb,
const GURL& path, const GURL& path,
int icon_size_in_pixels, int icon_size_in_pixels,
float scale) float scale,
bool show_fallback_monogram)
: callback(cb), : callback(cb),
path(path), path(path),
icon_size_in_pixels(icon_size_in_pixels), icon_size_in_pixels(icon_size_in_pixels),
device_scale_factor(scale) {} device_scale_factor(scale),
show_fallback_monogram(show_fallback_monogram) {}
NtpIconRequest(const NtpIconRequest& other) = default; NtpIconRequest(const NtpIconRequest& other) = default;
~NtpIconRequest() {} ~NtpIconRequest() {}
...@@ -263,6 +286,7 @@ struct NtpIconSource::NtpIconRequest { ...@@ -263,6 +286,7 @@ struct NtpIconSource::NtpIconRequest {
GURL path; GURL path;
int icon_size_in_pixels; int icon_size_in_pixels;
float device_scale_factor; float device_scale_factor;
bool show_fallback_monogram;
}; };
NtpIconSource::NtpIconSource(Profile* profile) NtpIconSource::NtpIconSource(Profile* profile)
...@@ -292,7 +316,8 @@ void NtpIconSource::StartDataRequest( ...@@ -292,7 +316,8 @@ void NtpIconSource::StartDataRequest(
int icon_size_in_pixels = int icon_size_in_pixels =
std::ceil(parsed.size_in_dip * parsed.device_scale_factor); std::ceil(parsed.size_in_dip * parsed.device_scale_factor);
NtpIconRequest request(callback, parsed.url, icon_size_in_pixels, NtpIconRequest request(callback, parsed.url, icon_size_in_pixels,
parsed.device_scale_factor); parsed.device_scale_factor,
parsed.show_fallback_monogram);
// Check if the requested URL is part of the prepopulated pages (currently, // Check if the requested URL is part of the prepopulated pages (currently,
// only the Web Store). // only the Web Store).
...@@ -460,8 +485,9 @@ void NtpIconSource::ReturnRenderedIconForRequest(const NtpIconRequest& request, ...@@ -460,8 +485,9 @@ void NtpIconSource::ReturnRenderedIconForRequest(const NtpIconRequest& request,
std::round(kIconSizeDip * request.device_scale_factor * 0.5) * 2.0; std::round(kIconSizeDip * request.device_scale_factor * 0.5) * 2.0;
int desired_fallback_size_in_pixel = int desired_fallback_size_in_pixel =
std::round(kFallbackSizeDip * request.device_scale_factor * 0.5) * 2.0; std::round(kFallbackSizeDip * request.device_scale_factor * 0.5) * 2.0;
std::vector<unsigned char> bitmap_data = std::vector<unsigned char> bitmap_data = RenderIconBitmap(
RenderIconBitmap(request.path, bitmap, desired_overall_size_in_pixel, request.path, bitmap, desired_overall_size_in_pixel,
desired_fallback_size_in_pixel); desired_fallback_size_in_pixel, request.show_fallback_monogram,
request.device_scale_factor);
request.callback.Run(base::RefCountedBytes::TakeVector(&bitmap_data)); request.callback.Run(base::RefCountedBytes::TakeVector(&bitmap_data));
} }
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