Commit 00f25d4b authored by huangs's avatar huangs

[Local NTP] Implement style updates for Material Design

Applying new styling, with some refactoring and bug fixes. Details:

- Sizing and positioning tweaks.
- Change of assets for "X" and for default favicon (if it's missing).
  - Using image as mask, and setting color by CSS (since design uses
    solid colors).
- The new PNG files have been minimized.
- Fixed bug: "Undo" and "Restore All" links continue to be selectable
  via tab after they fades out.
- Alternative Google logo (white): using image as mask and setting
  background color to #eee.  Will delete old image for M39.
- Theme title color in title.html <iframe>: now injecting it from local
  NTP in "c=RRGGBBAA" format. The old behavior of reading it from
  <iframe> and using it to override "c=RRGGBB" are kept, for
  compatibility with server-side NTP.

BUG=407943
NOTRY=1
R=mathp@chromium.org, oshima@chromium.org

Review URL: https://codereview.chromium.org/512583002

Cr-Commit-Position: refs/heads/master@{#292820}
parent 1678589c
...@@ -15,7 +15,16 @@ body { ...@@ -15,7 +15,16 @@ body {
text-align: -webkit-center; text-align: -webkit-center;
} }
#ntp-contents.classical {
margin-top: 157px;
}
#ntp-contents.md {
margin-top: 157px;
}
.non-google-page #ntp-contents { .non-google-page #ntp-contents {
margin-top: 0;
position: absolute; position: absolute;
top: calc(50% - 155px); top: calc(50% - 155px);
width: 100%; width: 100%;
...@@ -41,12 +50,14 @@ body.fakebox-disable #fakebox > input { ...@@ -41,12 +50,14 @@ body.fakebox-disable #fakebox > input {
background-size: 269px 95px; background-size: 269px 95px;
height: 95px; height: 95px;
margin-bottom: 24px; margin-bottom: 24px;
margin-top: 157px;
width: 269px; width: 269px;
} }
body.alternate-logo #logo { body.alternate-logo #logo {
background-image: url('images/white_google_logo.png@2x'); -webkit-mask-image: url('images/google_logo.png@2x');
-webkit-mask-repeat: no-repeat;
-webkit-mask-size: 100%;
background: #eee;
} }
#fakebox { #fakebox {
...@@ -61,7 +72,7 @@ body.alternate-logo #logo { ...@@ -61,7 +72,7 @@ body.alternate-logo #logo {
font-size: 18px; font-size: 18px;
height: 36px; height: 36px;
line-height: 36px; line-height: 36px;
max-width: 620px; max-width: 672px;
position: relative; position: relative;
/* #fakebox width (here and below) should be 2px less than #mv-tiles /* #fakebox width (here and below) should be 2px less than #mv-tiles
to account for its border. */ to account for its border. */
...@@ -103,12 +114,17 @@ body[dir=rtl] #fakebox > input { ...@@ -103,12 +114,17 @@ body[dir=rtl] #fakebox > input {
color: #bbb; color: #bbb;
font-family: arial, sans-serif; font-family: arial, sans-serif;
font-size: 16px; font-size: 16px;
height: 16px; height: 100%;
left: 9px; left: 9px;
margin-top: 1px; margin-top: 1px;
overflow: hidden;
position: absolute; position: absolute;
text-align: left;
text-overflow: ellipsis;
vertical-align: middle; vertical-align: middle;
visibility: hidden; visibility: inherit;
white-space: nowrap;
width: calc(100% - 2 * 9px);
} }
body[dir=rtl] #fakebox-text { body[dir=rtl] #fakebox-text {
...@@ -142,7 +158,7 @@ body[dir=rtl] #cursor { ...@@ -142,7 +158,7 @@ body[dir=rtl] #cursor {
body.fakebox-drag-focused #fakebox-text, body.fakebox-drag-focused #fakebox-text,
body.fakebox-focused #fakebox-text { body.fakebox-focused #fakebox-text {
visibility: inherit; visibility: hidden;
} }
body.fakebox-drag-focused #cursor { body.fakebox-drag-focused #cursor {
...@@ -164,7 +180,7 @@ body.fakebox-focused #cursor { ...@@ -164,7 +180,7 @@ body.fakebox-focused #cursor {
} }
.md #most-visited { .md #most-visited {
margin-top: 50px; margin-top: 64px;
} }
#mv-tiles { #mv-tiles {
...@@ -183,8 +199,8 @@ body[dir=rtl] #mv-tiles { ...@@ -183,8 +199,8 @@ body[dir=rtl] #mv-tiles {
} }
.md #mv-tiles { .md #mv-tiles {
height: calc(2 * 126px); height: calc(2 * 146px);
line-height: 126px; line-height: 146px;
} }
.mv-tile { .mv-tile {
...@@ -214,12 +230,12 @@ body[dir=rtl] #mv-tiles { ...@@ -214,12 +230,12 @@ body[dir=rtl] #mv-tiles {
} }
.md .mv-tile { .md .mv-tile {
background: #f2f2f2; background: rgb(242,242,242);
border-radius: 1px; border-radius: 1px;
height: 114px; height: 130px;
margin-left: 6px; margin-left: 8px;
margin-right: 6px; margin-right: 8px;
width: 146px; width: 156px;
} }
.md .mv-page-ready { .md .mv-page-ready {
...@@ -228,7 +244,7 @@ body[dir=rtl] #mv-tiles { ...@@ -228,7 +244,7 @@ body[dir=rtl] #mv-tiles {
} }
.md.dark .mv-tile { .md.dark .mv-tile {
background: #333; background: rgb(51,51,51);
} }
.mv-tile-inner { .mv-tile-inner {
...@@ -274,8 +290,8 @@ body[dir=rtl] #mv-tiles { ...@@ -274,8 +290,8 @@ body[dir=rtl] #mv-tiles {
.md .mv-mask { .md .mv-mask {
border-color: transparent; border-color: transparent;
border-radius: 2px; border-radius: 2px;
height: 112px; height: calc(130px - 2px);
width: 144px; width: calc(156px - 2px);
} }
/* Styling border. */ /* Styling border. */
...@@ -304,11 +320,11 @@ body[dir=rtl] #mv-tiles { ...@@ -304,11 +320,11 @@ body[dir=rtl] #mv-tiles {
} }
/* Styling shadow. */ /* Styling shadow. */
.md .mv-page-ready .mv-mask { .default-theme.md .mv-page-ready .mv-mask {
-webkit-transition: box-shadow 200ms, border 200ms; -webkit-transition: box-shadow 200ms, border 200ms;
} }
.default-theme.md .mv-page-ready:hover .mv-mask { .default-theme.md .mv-page-ready:hover .mv-mask {
box-shadow: 0 2px 8px rgba(0,0,0,0.3); box-shadow: 0 1px 2px 0 rgba(0,0,0,0.1), 0 4px 8px 0 rgba(0,0,0,0.2);
} }
.default-theme..md.dark .mv-page-ready:hover .mv-mask, .default-theme..md.dark .mv-page-ready:hover .mv-mask,
...@@ -326,7 +342,7 @@ body[dir=rtl] #mv-tiles { ...@@ -326,7 +342,7 @@ body[dir=rtl] #mv-tiles {
.md .mv-page:focus .mv-mask { .md .mv-page:focus .mv-mask {
-webkit-transition: box-shadow 200ms, border 200ms, -webkit-transition: box-shadow 200ms, border 200ms,
background-color 100ms ease-in-out, ; background-color 100ms ease-in-out;
background: rgba(0, 0, 0, 0.3); background: rgba(0, 0, 0, 0.3);
border-color: rgba(0, 0, 0, 0.3); border-color: rgba(0, 0, 0, 0.3);
} }
...@@ -346,20 +362,20 @@ body[dir=rtl] #mv-tiles { ...@@ -346,20 +362,20 @@ body[dir=rtl] #mv-tiles {
.md .mv-title { .md .mv-title {
bottom: auto; bottom: auto;
height: 15px; height: 15px;
left: 28px; left: 32px;
top: 7px; top: 9px;
width: 112px; width: calc(156px - 32px - 4px);
} }
@media (-webkit-min-device-pixel-ratio: 2) { @media (-webkit-min-device-pixel-ratio: 2) {
.md .mv-title { .md .mv-title {
top: 6px; top: 8px;
} }
} }
body[dir=rtl] .md .mv-title { body[dir=rtl] .md .mv-title {
left: auto; left: auto;
right: 28px; right: 32px;
} }
.mv-thumb { .mv-thumb {
...@@ -389,10 +405,10 @@ body[dir=rtl] .md .mv-title { ...@@ -389,10 +405,10 @@ body[dir=rtl] .md .mv-title {
.md .mv-thumb, .md .mv-thumb,
.md .mv-thumb-fallback { .md .mv-thumb-fallback {
border-radius: 0; border-radius: 0;
height: 82px; height: 94px;
left: 4px; left: 4px;
top: 28px; top: 32px;
width: 138px; width: 148px;
} }
body[dir=rtl] .md .mv-thumb, body[dir=rtl] .md .mv-thumb,
...@@ -402,30 +418,29 @@ body[dir=rtl] .md .mv-thumb-fallback { ...@@ -402,30 +418,29 @@ body[dir=rtl] .md .mv-thumb-fallback {
} }
.md .mv-thumb-fallback { .md .mv-thumb-fallback {
background: #fff; background-color: #fff;
padding: none;
position: absolute; position: absolute;
} }
.md.dark .mv-thumb-fallback { .md.dark .mv-thumb-fallback {
background: #555; background-color: #555;
} }
.md .mv-thumb-fallback .dot { .md .mv-thumb-fallback .dot {
background: #f2f2f2; background-color: #f2f2f2;
border-radius: 16px; border-radius: 8px;
display: block; display: block;
height: 32px; height: 16px;
left: 50%; left: 50%;
margin-left: -16px; margin-left: -8px;
margin-top: -16px; margin-top: -8px;
position: absolute; position: absolute;
top: 50%; top: 50%;
width: 32px; width: 16px;
} }
.md.dark .mv-thumb-fallback .dot { .md.dark .mv-thumb-fallback .dot {
background: #333; background-color: #333;
} }
.mv-x-hide .mv-x { .mv-x-hide .mv-x {
...@@ -435,11 +450,8 @@ body[dir=rtl] .md .mv-thumb-fallback { ...@@ -435,11 +450,8 @@ body[dir=rtl] .md .mv-thumb-fallback {
/* An X button to blacklist a tile or hide the notification. */ /* An X button to blacklist a tile or hide the notification. */
.mv-x { .mv-x {
background-color: transparent; background-color: transparent;
background-image: url(images/close_2.png);
border: none; border: none;
cursor: default; cursor: pointer;
height: 16px;
width: 16px;
} }
.mv-page .mv-x { .mv-page .mv-x {
...@@ -448,13 +460,20 @@ body[dir=rtl] .md .mv-thumb-fallback { ...@@ -448,13 +460,20 @@ body[dir=rtl] .md .mv-thumb-fallback {
position: absolute; position: absolute;
} }
.mv-x:hover, .classical .mv-x {
#mv-notice-x:focus { background-image: url('images/close_2.png');
background-image: url(images/close_2_hover.png); height: 16px;
width: 16px;
}
.classical .mv-x:hover,
.classical #mv-notice-x:focus {
background-image: url('images/close_2_hover.png');
} }
.mv-x:active { .classical .mv-x:active,
background-image: url(images/close_2_active.png); .classical #mv-notice-x:active {
background-image: url('images/close_2_active.png');
} }
.classical .mv-page .mv-x { .classical .mv-page .mv-x {
...@@ -462,30 +481,89 @@ body[dir=rtl] .md .mv-thumb-fallback { ...@@ -462,30 +481,89 @@ body[dir=rtl] .md .mv-thumb-fallback {
top: 2px; top: 2px;
} }
body[dir=rtl] .classical .mv-page .mv-x {
left: 2px;
right: auto;
}
#mv-notice-x {
display: inline-block;
position: relative;
}
.md #mv-notice-x {
-webkit-transform: translate(0,-8px);
}
.md .mv-x { .md .mv-x {
background-color: rgba(187,187,187,0.8); height: 32px;
border-radius: 8px; width: 32px;
} }
.md.dark .mv-x { .md .mv-x .mv-x-inner {
background-color: rgba(119,119,119,0.8); -webkit-mask-image: -webkit-image-set(
url('images/close_3_mask.png') 1x,
url('images/close_3_mask.png@2x') 2x);
-webkit-mask-repeat: no-repeat;
-webkit-mask-size: 10px 10px;
background-color: rgba(90,90,90,0.7);
height: 10px;
left: 50%;
margin-left: -5px;
margin-top: -5px;
position: absolute;
top: 50%;
width: 10px;
} }
.md .mv-page .mv-x { .md.dark .mv-x .mv-x-inner {
right: 4px; background-color: rgba(255,255,255,0.7);
top: 5px;
} }
body[dir=rtl] .classical .mv-page .mv-x { .md .mv-x:hover .mv-x-inner,
left: 2px; .md #mv-notice-x:focus .mv-x-inner {
right: auto; background-color: rgb(90,90,90);
}
.md.dark .mv-x:hover .mv-x-inner,
.md.dark #mv-notice-x:focus .mv-x-inner {
background-color: rgb(255,255,255);
}
.md .mv-x:active .mv-x-inner,
.md #mv-notice-x:active .mv-x-inner {
background-color: rgb(66,133,244);
}
.md.dark .mv-x:active .mv-x-inner,
.md.dark #mv-notice-x:active .mv-x-inner {
background-color: rgba(255,255,255,0.5);
}
.md .mv-page .mv-x {
/* background color needs to match .md .mv-tile */
background: linear-gradient(to right, transparent, rgb(242,242,242) 10%);
right: 0;
top: 0;
} }
body[dir=rtl] .md .mv-page .mv-x { body[dir=rtl] .md .mv-page .mv-x {
left: 4px; /* background color needs to match .md .mv-tile */
background: linear-gradient(to left, transparent, rgb(242,242,242) 10%);
left: 0;
right: auto; right: auto;
} }
.md.dark .mv-page .mv-x {
/* background color needs to match .md.dark .mv-tile */
background: linear-gradient(to right, transparent, rgba(51,51,51,0.9) 30%);
}
body[dir=rtl] .md.dark .mv-page .mv-x {
/* background color needs to match .md.dark .mv-tile */
background: linear-gradient(to left, transparent, rgba(51,51,51,0.9) 30%);
}
.mv-page-ready:hover .mv-x { .mv-page-ready:hover .mv-x {
-webkit-transition-delay: 500ms; -webkit-transition-delay: 500ms;
opacity: 1; opacity: 1;
...@@ -509,14 +587,22 @@ body[dir=rtl] .md .mv-page .mv-x { ...@@ -509,14 +587,22 @@ body[dir=rtl] .md .mv-page .mv-x {
} }
.md .mv-favicon { .md .mv-favicon {
left: 6px; left: 8px;
top: 6px; top: 8px;
} }
body[dir=rtl] .md .mv-favicon { body[dir=rtl] .md .mv-favicon {
left: auto; left: auto;
right: 6px; right: 8px;
top: 6px; top: 8px;
}
.md .mv-favicon-fallback {
background-image: -webkit-image-set(
url('images/ntp_default_favicon.png') 1x,
url('images/ntp_default_favicon.png@2x') 2x);
background-repeat: no-repeat;
background-size: 16px 16px;
} }
/* The notification shown when a tile is blacklisted. */ /* The notification shown when a tile is blacklisted. */
...@@ -529,6 +615,10 @@ body[dir=rtl] .md .mv-favicon { ...@@ -529,6 +615,10 @@ body[dir=rtl] .md .mv-favicon {
#mv-notice span { #mv-notice span {
cursor: default; cursor: default;
display: inline-block;
height: 16px;
line-height: 16px;
vertical-align: top;
} }
/* Links in the notification. */ /* Links in the notification. */
...@@ -550,6 +640,10 @@ body[dir=rtl] .md .mv-favicon { ...@@ -550,6 +640,10 @@ body[dir=rtl] .md .mv-favicon {
color: #fff; color: #fff;
} }
.default-theme.dark #mv-notice-links span {
color: #fff;
}
#mv-notice-links .mv-x { #mv-notice-links .mv-x {
-webkit-margin-start: 8px; -webkit-margin-start: 8px;
outline: none; outline: none;
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<span id="mv-notice-links"> <span id="mv-notice-links">
<span id="mv-undo" tabIndex="1"></span> <span id="mv-undo" tabIndex="1"></span>
<span id="mv-restore" tabIndex="1"></span> <span id="mv-restore" tabIndex="1"></span>
<button id="mv-notice-x" tabIndex="1" class="mv-x"></button> <div id="mv-notice-x" tabIndex="1" class="mv-x"></div>
</span> </span>
</div> </div>
</div> </div>
......
...@@ -28,6 +28,7 @@ var CLASSES = { ...@@ -28,6 +28,7 @@ var CLASSES = {
ALTERNATE_LOGO: 'alternate-logo', // Shows white logo if required by theme ALTERNATE_LOGO: 'alternate-logo', // Shows white logo if required by theme
BLACKLIST: 'mv-blacklist', // triggers tile blacklist animation BLACKLIST: 'mv-blacklist', // triggers tile blacklist animation
BLACKLIST_BUTTON: 'mv-x', BLACKLIST_BUTTON: 'mv-x',
BLACKLIST_BUTTON_INNER: 'mv-x-inner',
DARK: 'dark', DARK: 'dark',
DEFAULT_THEME: 'default-theme', DEFAULT_THEME: 'default-theme',
DELAYED_HIDE_NOTIFICATION: 'mv-notice-delayed-hide', DELAYED_HIDE_NOTIFICATION: 'mv-notice-delayed-hide',
...@@ -175,13 +176,6 @@ var lastBlacklistedTile = null; ...@@ -175,13 +176,6 @@ var lastBlacklistedTile = null;
var isBlacklisting = false; var isBlacklisting = false;
/**
* Stores whether the current theme has a dark background.
* @type {boolean}
*/
var isBackgroundDark = false;
/** /**
* Current number of tiles columns shown based on the window width, including * Current number of tiles columns shown based on the window width, including
* those that just contain filler. * those that just contain filler.
...@@ -267,6 +261,13 @@ var MOST_VISITED_TITLE_IFRAME = 'title.html'; ...@@ -267,6 +261,13 @@ var MOST_VISITED_TITLE_IFRAME = 'title.html';
var MOST_VISITED_THUMBNAIL_IFRAME = 'thumbnail.html'; var MOST_VISITED_THUMBNAIL_IFRAME = 'thumbnail.html';
/**
* The color of the title in RRGGBBAA format.
* @type {?string}
*/
var titleColor = null;
/** /**
* Hide most visited tiles for at most this many milliseconds while painting. * Hide most visited tiles for at most this many milliseconds while painting.
* @type {number} * @type {number}
...@@ -306,17 +307,19 @@ function Tile(elem, opt_innerElem, opt_titleElem, opt_thumbnailElem, opt_rid) { ...@@ -306,17 +307,19 @@ function Tile(elem, opt_innerElem, opt_titleElem, opt_thumbnailElem, opt_rid) {
/** /**
* Determines whether a theme should be considered to have dark background. * Heuristic to determine whether a theme should be considered to be dark, so
* @param {ThemeBackgroundInfo} info Theme background information. * the colors of various UI elements can be adjusted.
* @return {boolean} Whether the theme has dark background. * @param {ThemeBackgroundInfo|undefined} info Theme background information.
* @return {boolean} Whether the theme is dark.
* @private * @private
*/ */
function getIsBackgroundDark(info) { function getIsThemeDark(info) {
if (info.imageUrl) if (!info)
return true; return false;
var rgba = info.backgroundColorRgba; // Heuristic: light text implies dark theme.
var rgba = info.textColorRgba;
var luminance = 0.3 * rgba[0] + 0.59 * rgba[1] + 0.11 * rgba[2]; var luminance = 0.3 * rgba[0] + 0.59 * rgba[1] + 0.11 * rgba[2];
return luminance < 128; return luminance >= 128;
} }
...@@ -325,20 +328,37 @@ function getIsBackgroundDark(info) { ...@@ -325,20 +328,37 @@ function getIsBackgroundDark(info) {
* @private * @private
*/ */
function renderTheme() { function renderTheme() {
var fakeboxText = $(IDS.FAKEBOX_TEXT);
if (fakeboxText) {
fakeboxText.innerHTML = '';
if (NTP_DESIGN.showFakeboxHint &&
configData.translatedStrings.searchboxPlaceholder) {
fakeboxText.textContent =
configData.translatedStrings.searchboxPlaceholder;
}
}
var info = ntpApiHandle.themeBackgroundInfo; var info = ntpApiHandle.themeBackgroundInfo;
var isThemeDark = getIsThemeDark(info);
ntpContents.classList.toggle(CLASSES.DARK, isThemeDark);
if (!info) { if (!info) {
isBackgroundDark = false; titleColor = NTP_DESIGN.titleColor;
return; return;
} }
isBackgroundDark = getIsBackgroundDark(info); if (!info.usingDefaultTheme && info.textColorRgba) {
ntpContents.classList.toggle(CLASSES.DARK, isBackgroundDark); titleColor = convertToRRGGBBAAColor(info.textColorRgba);
} else {
titleColor = isThemeDark ?
NTP_DESIGN.titleColorAgainstDark : NTP_DESIGN.titleColor;
}
var background = [convertToRGBAColor(info.backgroundColorRgba), var background = [convertToRGBAColor(info.backgroundColorRgba),
info.imageUrl, info.imageUrl,
info.imageTiling, info.imageTiling,
info.imageHorizontalAlignment, info.imageHorizontalAlignment,
info.imageVerticalAlignment].join(' ').trim(); info.imageVerticalAlignment].join(' ').trim();
document.body.style.background = background; document.body.style.background = background;
document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, info.alternateLogo); document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, info.alternateLogo);
updateThemeAttribution(info.attributionUrl); updateThemeAttribution(info.attributionUrl);
...@@ -366,7 +386,6 @@ function onThemeChange() { ...@@ -366,7 +386,6 @@ function onThemeChange() {
function setCustomThemeStyle(opt_themeInfo) { function setCustomThemeStyle(opt_themeInfo) {
var customStyleElement = $(IDS.CUSTOM_THEME_STYLE); var customStyleElement = $(IDS.CUSTOM_THEME_STYLE);
var head = document.head; var head = document.head;
if (opt_themeInfo && !opt_themeInfo.usingDefaultTheme) { if (opt_themeInfo && !opt_themeInfo.usingDefaultTheme) {
ntpContents.classList.remove(CLASSES.DEFAULT_THEME); ntpContents.classList.remove(CLASSES.DEFAULT_THEME);
var themeStyle = var themeStyle =
...@@ -443,6 +462,19 @@ function setAttributionVisibility_(show) { ...@@ -443,6 +462,19 @@ function setAttributionVisibility_(show) {
} }
/**
* Converts an Array of color components into RRGGBBAA format.
* @param {Array.<number>} color Array of rgba color components.
* @return {string} Color string in RRGGBBAA format.
* @private
*/
function convertToRRGGBBAAColor(color) {
return color.map(function(t) {
return ('0' + t.toString(16)).slice(-2); // To 2-digit, 0-padded hex.
}).join('');
}
/** /**
* Converts an Array of color components into RGBA format "rgba(R,G,B,A)". * Converts an Array of color components into RGBA format "rgba(R,G,B,A)".
* @param {Array.<number>} color Array of rgba color components. * @param {Array.<number>} color Array of rgba color components.
...@@ -585,8 +617,6 @@ function renderAndShowTiles() { ...@@ -585,8 +617,6 @@ function renderAndShowTiles() {
function getMostVisitedTitleIframeUrl(rid, position) { function getMostVisitedTitleIframeUrl(rid, position) {
var url = 'chrome-search://most-visited/' + var url = 'chrome-search://most-visited/' +
encodeURIComponent(MOST_VISITED_TITLE_IFRAME); encodeURIComponent(MOST_VISITED_TITLE_IFRAME);
var titleColor = isBackgroundDark ? NTP_DESIGN.titleColorAgainstDark :
NTP_DESIGN.titleColor;
var params = [ var params = [
'rid=' + encodeURIComponent(rid), 'rid=' + encodeURIComponent(rid),
'f=' + encodeURIComponent(NTP_DESIGN.fontFamily), 'f=' + encodeURIComponent(NTP_DESIGN.fontFamily),
...@@ -632,6 +662,11 @@ function getMostVisitedThumbnailIframeUrl(rid, position) { ...@@ -632,6 +662,11 @@ function getMostVisitedThumbnailIframeUrl(rid, position) {
function createTile(page, position) { function createTile(page, position) {
var tileElem = document.createElement('div'); var tileElem = document.createElement('div');
tileElem.classList.add(CLASSES.TILE); tileElem.classList.add(CLASSES.TILE);
// Prevent tile from being selected (and highlighted) when areas outside the
// <iframe>s are clicked.
tileElem.addEventListener('mousedown', function(e) {
e.preventDefault();
});
var innerElem = createAndAppendElement(tileElem, 'div', CLASSES.TILE_INNER); var innerElem = createAndAppendElement(tileElem, 'div', CLASSES.TILE_INNER);
if (page) { if (page) {
...@@ -694,6 +729,8 @@ function createTile(page, position) { ...@@ -694,6 +729,8 @@ function createTile(page, position) {
// The button used to blacklist this page. // The button used to blacklist this page.
var blacklistButton = createAndAppendElement( var blacklistButton = createAndAppendElement(
innerElem, 'div', CLASSES.BLACKLIST_BUTTON); innerElem, 'div', CLASSES.BLACKLIST_BUTTON);
createAndAppendElement(
blacklistButton, 'div', CLASSES.BLACKLIST_BUTTON_INNER);
var blacklistFunction = generateBlacklistFunction(rid); var blacklistFunction = generateBlacklistFunction(rid);
blacklistButton.addEventListener('click', blacklistFunction); blacklistButton.addEventListener('click', blacklistFunction);
blacklistButton.title = configData.translatedStrings.removeThumbnailTooltip; blacklistButton.title = configData.translatedStrings.removeThumbnailTooltip;
...@@ -757,6 +794,7 @@ function showNotification() { ...@@ -757,6 +794,7 @@ function showNotification() {
*/ */
function hideNotification() { function hideNotification() {
notification.classList.add(CLASSES.HIDE_NOTIFICATION); notification.classList.add(CLASSES.HIDE_NOTIFICATION);
notification.classList.remove(CLASSES.DELAYED_HIDE_NOTIFICATION);
} }
...@@ -785,11 +823,11 @@ function onRestoreAll() { ...@@ -785,11 +823,11 @@ function onRestoreAll() {
/** /**
* Resizes elements because the number of tile columns may need to change in * Recomputes the number of tile columns, and width of various contents based
* response to resizing. Also shows or hides extra tiles tiles according to the * on the width of the window.
* new width of the page. * @return {boolean} Whether the number of tile columns has changed.
*/ */
function onResize() { function updateContentWidth() {
var tileRequiredWidth = NTP_DESIGN.tileWidth + NTP_DESIGN.tileMargin; var tileRequiredWidth = NTP_DESIGN.tileWidth + NTP_DESIGN.tileMargin;
// If innerWidth is zero, then use the maximum snap size. // If innerWidth is zero, then use the maximum snap size.
var maxSnapSize = MAX_NUM_COLUMNS * tileRequiredWidth - var maxSnapSize = MAX_NUM_COLUMNS * tileRequiredWidth -
...@@ -804,14 +842,28 @@ function onResize() { ...@@ -804,14 +842,28 @@ function onResize() {
else if (newNumColumns > MAX_NUM_COLUMNS) else if (newNumColumns > MAX_NUM_COLUMNS)
newNumColumns = MAX_NUM_COLUMNS; newNumColumns = MAX_NUM_COLUMNS;
if (numColumnsShown != newNumColumns) { if (numColumnsShown === newNumColumns)
numColumnsShown = newNumColumns; return false;
var tilesContainerWidth = numColumnsShown * tileRequiredWidth;
tilesContainer.style.width = tilesContainerWidth + 'px'; numColumnsShown = newNumColumns;
if (fakebox) { var tilesContainerWidth = numColumnsShown * tileRequiredWidth;
fakebox.style.width = // -2 to account for border. tilesContainer.style.width = tilesContainerWidth + 'px';
(tilesContainerWidth - NTP_DESIGN.tileMargin - 2) + 'px'; if (fakebox) {
} // -2 to account for border.
var fakeboxWidth = (tilesContainerWidth - NTP_DESIGN.tileMargin - 2);
fakebox.style.width = fakeboxWidth + 'px';
}
return true;
}
/**
* Resizes elements because the number of tile columns may need to change in
* response to resizing. Also shows or hides extra tiles tiles according to the
* new width of the page.
*/
function onResize() {
if (updateContentWidth()) {
// Render without clearing tiles. // Render without clearing tiles.
renderAndShowTiles(); renderAndShowTiles();
} }
...@@ -1000,11 +1052,7 @@ function init() { ...@@ -1000,11 +1052,7 @@ function init() {
var fakeboxHtml = []; var fakeboxHtml = [];
fakeboxHtml.push('<input id="' + IDS.FAKEBOX_INPUT + fakeboxHtml.push('<input id="' + IDS.FAKEBOX_INPUT +
'" autocomplete="off" tabindex="-1" aria-hidden="true">'); '" autocomplete="off" tabindex="-1" aria-hidden="true">');
if (NTP_DESIGN.showFakeboxHint && fakeboxHtml.push('<div id="' + IDS.FAKEBOX_TEXT + '"></div>');
configData.translatedStrings.searchboxPlaceholder) {
fakeboxHtml.push('<div id="' + IDS.FAKEBOX_TEXT + '">' +
configData.translatedStrings.searchboxPlaceholder + '</div>');
}
fakeboxHtml.push('<div id="cursor"></div>'); fakeboxHtml.push('<div id="cursor"></div>');
fakebox.innerHTML = fakeboxHtml.join(''); fakebox.innerHTML = fakeboxHtml.join('');
...@@ -1014,6 +1062,9 @@ function init() { ...@@ -1014,6 +1062,9 @@ function init() {
document.body.classList.add(CLASSES.NON_GOOGLE_PAGE); document.body.classList.add(CLASSES.NON_GOOGLE_PAGE);
} }
// Hide notifications after fade out, so we can't focus on links via keyboard.
notification.addEventListener('webkitTransitionEnd', hideNotification);
var notificationMessage = $(IDS.NOTIFICATION_MESSAGE); var notificationMessage = $(IDS.NOTIFICATION_MESSAGE);
notificationMessage.textContent = notificationMessage.textContent =
configData.translatedStrings.thumbnailRemovedNotification; configData.translatedStrings.thumbnailRemovedNotification;
...@@ -1033,10 +1084,12 @@ function init() { ...@@ -1033,10 +1084,12 @@ function init() {
configData.translatedStrings.attributionIntro; configData.translatedStrings.attributionIntro;
var notificationCloseButton = $(IDS.NOTIFICATION_CLOSE_BUTTON); var notificationCloseButton = $(IDS.NOTIFICATION_CLOSE_BUTTON);
createAndAppendElement(
notificationCloseButton, 'div', CLASSES.BLACKLIST_BUTTON_INNER);
notificationCloseButton.addEventListener('click', hideNotification); notificationCloseButton.addEventListener('click', hideNotification);
window.addEventListener('resize', onResize); window.addEventListener('resize', onResize);
onResize(); updateContentWidth();
var topLevelHandle = getEmbeddedSearchApiHandle(); var topLevelHandle = getEmbeddedSearchApiHandle();
......
...@@ -19,13 +19,13 @@ ...@@ -19,13 +19,13 @@
* fontSize: Font size to use for the <iframe>s, in px. * fontSize: Font size to use for the <iframe>s, in px.
* tileWidth: The width of each suggestion tile, in px. * tileWidth: The width of each suggestion tile, in px.
* tileMargin: Spacing between successive tiles, in px. * tileMargin: Spacing between successive tiles, in px.
* titleColor: The RRGGBB color of title text. * titleColor: The RRGGBBAA color of title text.
* titleColorAgainstDark: The RRGGBB color of title text against a dark theme. * titleColorAgainstDark: The RRGGBBAA color of title text against a dark theme.
* titleTextAlign: (Optional) The alignment of title text. If unspecified, the * titleTextAlign: (Optional) The alignment of title text. If unspecified, the
* default value is 'center'. * default value is 'center'.
* titleTextFade: (Optional) The number of pixels beyond which title * titleTextFade: (Optional) The number of pixels beyond which title
* text begins to fade. This overrides the default ellipsis style. * text begins to fade. This overrides the default ellipsis style.
* thumbnailTextColor: The RRGGBB color that thumbnail <iframe> may use to * thumbnailTextColor: The RRGGBBAA color that thumbnail <iframe> may use to
* display text message in place of missing thumbnail. * display text message in place of missing thumbnail.
* thumbnailFallback: (Optional) A value in THUMBNAIL_FALLBACK to specify the * thumbnailFallback: (Optional) A value in THUMBNAIL_FALLBACK to specify the
* thumbnail fallback strategy. If unassigned, then the thumbnail.html * thumbnail fallback strategy. If unassigned, then the thumbnail.html
...@@ -63,13 +63,13 @@ function getNtpDesign(opt_name) { ...@@ -63,13 +63,13 @@ function getNtpDesign(opt_name) {
name: opt_name, name: opt_name,
fontFamily: 'arial, sans-serif', fontFamily: 'arial, sans-serif',
fontSize: 12, fontSize: 12,
tileWidth: 146, tileWidth: 156,
tileMargin: 12, tileMargin: 16,
titleColor: '000000', titleColor: '323232ff',
titleColorAgainstDark: 'd2d2d2', titleColorAgainstDark: 'd2d2d2ff',
titleTextAlign: 'inherit', titleTextAlign: 'inherit',
titleTextFade: 112 - 24, // 112px wide title with 24 pixel fade at end. titleTextFade: 122 - 36, // 112px wide title with 32 pixel fade at end.
thumbnailTextColor: '777777', thumbnailTextColor: '323232ff', // Unused.
thumbnailFallback: THUMBNAIL_FALLBACK.DOT, thumbnailFallback: THUMBNAIL_FALLBACK.DOT,
showFakeboxHint: true showFakeboxHint: true
}; };
...@@ -80,11 +80,11 @@ function getNtpDesign(opt_name) { ...@@ -80,11 +80,11 @@ function getNtpDesign(opt_name) {
fontSize: 11, fontSize: 11,
tileWidth: 140, tileWidth: 140,
tileMargin: 20, tileMargin: 20,
titleColor: '777777', titleColor: '777777ff',
titleColorAgainstDark: '777777', titleColorAgainstDark: '777777ff',
titleTextAlign: 'center', titleTextAlign: 'center',
titleTextFade: null, // Default to ellipsis. titleTextFade: null, // Default to ellipsis.
thumbnailTextColor: '777777', thumbnailTextColor: '777777ff',
thumbnailFallback: null, // Default to false. thumbnailFallback: null, // Default to false.
showFakeboxHint: false showFakeboxHint: false
}; };
......
...@@ -161,6 +161,38 @@ function createMostVisitedLink(params, href, title, text, direction, provider) { ...@@ -161,6 +161,38 @@ function createMostVisitedLink(params, href, title, text, direction, provider) {
} }
/**
* Returns the color to display string with, depending on whether title is
* displayed, the current theme, and URL parameters.
* @param {Object.<string, string>} params URL parameters specifying style.
* @param {boolean} isTitle if the style is for the Most Visited Title.
* @return {string} The color to use, in "rgba(#,#,#,#)" format.
*/
function getTextColor(params, isTitle) {
// 'RRGGBBAA' color format overrides everything.
if ('c' in params && params.c.match(/^[0-9A-Fa-f]{8}$/)) {
// Extract the 4 pairs of hex digits, map to number, then form rgba().
var t = params.c.match(/(..)(..)(..)(..)/).slice(1).map(function(s) {
return parseInt(s, 16);
});
return 'rgba(' + t[0] + ',' + t[1] + ',' + t[2] + ',' + t[3] / 255 + ')';
}
// For backward compatibility with server-side NTP, look at themes directly
// and use param.c for non-title or as fallback.
var apiHandle = chrome.embeddedSearch.newTabPage;
var themeInfo = apiHandle.themeBackgroundInfo;
var c = '#777';
if (isTitle && themeInfo && !themeInfo.usingDefaultTheme) {
// Read from theme directly
c = convertArrayToRGBAColor(themeInfo.textColorRgba) || c;
} else if ('c' in params) {
c = convertToHexColor(parseInt(params.c, 16)) || c;
}
return c;
}
/** /**
* Decodes most visited styles from URL parameters. * Decodes most visited styles from URL parameters.
* - c: A hexadecimal number interpreted as a hex color code. * - c: A hexadecimal number interpreted as a hex color code.
...@@ -174,18 +206,10 @@ function createMostVisitedLink(params, href, title, text, direction, provider) { ...@@ -174,18 +206,10 @@ function createMostVisitedLink(params, href, title, text, direction, provider) {
*/ */
function getMostVisitedStyles(params, isTitle) { function getMostVisitedStyles(params, isTitle) {
var styles = { var styles = {
color: '#777', color: getTextColor(params, isTitle), // Handles 'c' in params.
fontFamily: '', fontFamily: '',
fontSize: 11 fontSize: 11
}; };
var apiHandle = chrome.embeddedSearch.newTabPage;
var themeInfo = apiHandle.themeBackgroundInfo;
if (isTitle && themeInfo && !themeInfo.usingDefaultTheme) {
styles.color = convertArrayToRGBAColor(themeInfo.textColorRgba) ||
styles.color;
} else if ('c' in params) {
styles.color = convertToHexColor(parseInt(params.c, 16)) || styles.color;
}
if ('f' in params && /^[-0-9a-zA-Z ,]+$/.test(params.f)) if ('f' in params && /^[-0-9a-zA-Z ,]+$/.test(params.f))
styles.fontFamily = params.f; styles.fontFamily = params.f;
if ('fs' in params && isFinite(parseInt(params.fs, 10))) if ('fs' in params && isFinite(parseInt(params.fs, 10)))
......
...@@ -59,9 +59,11 @@ const struct Resource{ ...@@ -59,9 +59,11 @@ const struct Resource{
{ "images/close_2_hover.png", IDR_CLOSE_2_H, "image/png" }, { "images/close_2_hover.png", IDR_CLOSE_2_H, "image/png" },
{ "images/close_2_active.png", IDR_CLOSE_2_P, "image/png" }, { "images/close_2_active.png", IDR_CLOSE_2_P, "image/png" },
{ "images/close_2_white.png", IDR_CLOSE_2_MASK, "image/png" }, { "images/close_2_white.png", IDR_CLOSE_2_MASK, "image/png" },
{ "images/close_3_mask.png", IDR_CLOSE_3_MASK, "image/png" },
{ "images/google_logo.png", IDR_LOCAL_NTP_IMAGES_LOGO_PNG, "image/png" }, { "images/google_logo.png", IDR_LOCAL_NTP_IMAGES_LOGO_PNG, "image/png" },
{ "images/white_google_logo.png", { "images/white_google_logo.png",
IDR_LOCAL_NTP_IMAGES_WHITE_LOGO_PNG, "image/png" }, IDR_LOCAL_NTP_IMAGES_WHITE_LOGO_PNG, "image/png" },
{ "images/ntp_default_favicon.png", IDR_NTP_DEFAULT_FAVICON, "image/png" },
}; };
// Strips any query parameters from the specified path. // Strips any query parameters from the specified path.
......
...@@ -163,6 +163,7 @@ ...@@ -163,6 +163,7 @@
<structure type="chrome_scaled_image" name="IDR_CLOSE_2_H" file="close_2_hover.png" /> <structure type="chrome_scaled_image" name="IDR_CLOSE_2_H" file="close_2_hover.png" />
<structure type="chrome_scaled_image" name="IDR_CLOSE_2_MASK" file="close_2_mask.png" /> <structure type="chrome_scaled_image" name="IDR_CLOSE_2_MASK" file="close_2_mask.png" />
<structure type="chrome_scaled_image" name="IDR_CLOSE_2_P" file="close_2_pressed.png" /> <structure type="chrome_scaled_image" name="IDR_CLOSE_2_P" file="close_2_pressed.png" />
<structure type="chrome_scaled_image" name="IDR_CLOSE_3_MASK" file="common/close_3_mask.png" />
<structure type="chrome_scaled_image" name="IDR_CLOSE_DIALOG" file="close_dialog.png" /> <structure type="chrome_scaled_image" name="IDR_CLOSE_DIALOG" file="close_dialog.png" />
<structure type="chrome_scaled_image" name="IDR_CLOSE_DIALOG_H" file="close_dialog_hover.png" /> <structure type="chrome_scaled_image" name="IDR_CLOSE_DIALOG_H" file="close_dialog_hover.png" />
<structure type="chrome_scaled_image" name="IDR_CLOSE_DIALOG_P" file="close_dialog_pressed.png" /> <structure type="chrome_scaled_image" name="IDR_CLOSE_DIALOG_P" file="close_dialog_pressed.png" />
...@@ -354,6 +355,9 @@ ...@@ -354,6 +355,9 @@
See crbug.com/363519. --> See crbug.com/363519. -->
<structure type="chrome_scaled_image" name="IDR_LOCAL_NTP_IMAGES_LOGO_PNG" file="common/ntp_google_logo.png" /> <structure type="chrome_scaled_image" name="IDR_LOCAL_NTP_IMAGES_LOGO_PNG" file="common/ntp_google_logo.png" />
<structure type="chrome_scaled_image" name="IDR_LOCAL_NTP_IMAGES_WHITE_LOGO_PNG" file="common/ntp_white_google_logo.png" /> <structure type="chrome_scaled_image" name="IDR_LOCAL_NTP_IMAGES_WHITE_LOGO_PNG" file="common/ntp_white_google_logo.png" />
<if expr="not is_android and not is_ios">
<structure type="chrome_scaled_image" name="IDR_NTP_DEFAULT_FAVICON" file="common/ntp_default_favicon.png" />
</if>
<if expr="not is_android and not is_ios"> <if expr="not is_android and not is_ios">
<structure type="chrome_scaled_image" name="IDR_OOBE_ACTION_BOX_BUTTON_HOVER" file="cros/action_box_button_hover.png" /> <structure type="chrome_scaled_image" name="IDR_OOBE_ACTION_BOX_BUTTON_HOVER" file="cros/action_box_button_hover.png" />
<structure type="chrome_scaled_image" name="IDR_OOBE_ACTION_BOX_BUTTON_NORMAL" file="cros/action_box_button_normal.png" /> <structure type="chrome_scaled_image" name="IDR_OOBE_ACTION_BOX_BUTTON_NORMAL" file="cros/action_box_button_normal.png" />
......
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