| Index: chrome/browser/resources/local_ntp/local_ntp.js
|
| diff --git a/chrome/browser/resources/local_ntp/local_ntp.js b/chrome/browser/resources/local_ntp/local_ntp.js
|
| index 26bf34eb8fa71b58fc06c858fd5b352fb07585bd..3dfdbe6df086c7bfabe5c09b3efbfffe1fddcca5 100644
|
| --- a/chrome/browser/resources/local_ntp/local_ntp.js
|
| +++ b/chrome/browser/resources/local_ntp/local_ntp.js
|
| @@ -28,6 +28,7 @@ var CLASSES = {
|
| ALTERNATE_LOGO: 'alternate-logo', // Shows white logo if required by theme
|
| BLACKLIST: 'mv-blacklist', // triggers tile blacklist animation
|
| BLACKLIST_BUTTON: 'mv-x',
|
| + BLACKLIST_BUTTON_INNER: 'mv-x-inner',
|
| DARK: 'dark',
|
| DEFAULT_THEME: 'default-theme',
|
| DELAYED_HIDE_NOTIFICATION: 'mv-notice-delayed-hide',
|
| @@ -176,13 +177,6 @@ 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
|
| * those that just contain filler.
|
| * @type {number}
|
| @@ -268,6 +262,13 @@ 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.
|
| * @type {number}
|
| * @const
|
| @@ -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.
|
| - * @param {ThemeBackgroundInfo} info Theme background information.
|
| - * @return {boolean} Whether the theme has dark background.
|
| + * Heuristic to determine whether a theme should be considered to be dark, so
|
| + * the colors of various UI elements can be adjusted.
|
| + * @param {ThemeBackgroundInfo|undefined} info Theme background information.
|
| + * @return {boolean} Whether the theme is dark.
|
| * @private
|
| */
|
| -function getIsBackgroundDark(info) {
|
| - if (info.imageUrl)
|
| - return true;
|
| - var rgba = info.backgroundColorRgba;
|
| +function getIsThemeDark(info) {
|
| + if (!info)
|
| + return false;
|
| + // Heuristic: bright text implies dark theme.
|
| + var rgba = info.textColorRgba;
|
| var luminance = 0.3 * rgba[0] + 0.59 * rgba[1] + 0.11 * rgba[2];
|
| - return luminance < 128;
|
| + return luminance >= 128;
|
| }
|
|
|
|
|
| @@ -325,20 +328,34 @@ function getIsBackgroundDark(info) {
|
| * @private
|
| */
|
| function renderTheme() {
|
| + var fakeboxText = $(IDS.FAKEBOX_TEXT);
|
| + fakeboxText.innerHTML = '';
|
| + if (NTP_DESIGN.showFakeboxHint &&
|
| + configData.translatedStrings.searchboxPlaceholder) {
|
| + fakeboxText.textContent = configData.translatedStrings.searchboxPlaceholder;
|
| + }
|
| +
|
| var info = ntpApiHandle.themeBackgroundInfo;
|
| + var isThemeDark = getIsThemeDark(info);
|
| + ntpContents.classList.toggle(CLASSES.DARK, isThemeDark);
|
| if (!info) {
|
| - isBackgroundDark = false;
|
| + titleColor = NTP_DESIGN.titleColor;
|
| return;
|
| }
|
|
|
| - isBackgroundDark = getIsBackgroundDark(info);
|
| - ntpContents.classList.toggle(CLASSES.DARK, isBackgroundDark);
|
| + if (!info.usingDefaultTheme && info.textColorRgba) {
|
| + titleColor = convertToRRGGBBAAColor(info.textColorRgba);
|
| + } else {
|
| + titleColor = isThemeDark ?
|
| + NTP_DESIGN.titleColorAgainstDark : NTP_DESIGN.titleColor;
|
| + }
|
|
|
| var background = [convertToRGBAColor(info.backgroundColorRgba),
|
| info.imageUrl,
|
| info.imageTiling,
|
| info.imageHorizontalAlignment,
|
| info.imageVerticalAlignment].join(' ').trim();
|
| +
|
| document.body.style.background = background;
|
| document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, info.alternateLogo);
|
| updateThemeAttribution(info.attributionUrl);
|
| @@ -366,7 +383,6 @@ function onThemeChange() {
|
| function setCustomThemeStyle(opt_themeInfo) {
|
| var customStyleElement = $(IDS.CUSTOM_THEME_STYLE);
|
| var head = document.head;
|
| -
|
| if (opt_themeInfo && !opt_themeInfo.usingDefaultTheme) {
|
| ntpContents.classList.remove(CLASSES.DEFAULT_THEME);
|
| var themeStyle =
|
| @@ -444,6 +460,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)".
|
| * @param {Array.<number>} color Array of rgba color components.
|
| * @return {string} CSS color in RGBA format.
|
| @@ -585,8 +614,6 @@ function renderAndShowTiles() {
|
| function getMostVisitedTitleIframeUrl(rid, position) {
|
| var url = 'chrome-search://most-visited/' +
|
| encodeURIComponent(MOST_VISITED_TITLE_IFRAME);
|
| - var titleColor = isBackgroundDark ? NTP_DESIGN.titleColorAgainstDark :
|
| - NTP_DESIGN.titleColor;
|
| var params = [
|
| 'rid=' + encodeURIComponent(rid),
|
| 'f=' + encodeURIComponent(NTP_DESIGN.fontFamily),
|
| @@ -632,6 +659,11 @@ function getMostVisitedThumbnailIframeUrl(rid, position) {
|
| function createTile(page, position) {
|
| var tileElem = document.createElement('div');
|
| 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);
|
|
|
| if (page) {
|
| @@ -694,6 +726,8 @@ function createTile(page, position) {
|
| // The button used to blacklist this page.
|
| var blacklistButton = createAndAppendElement(
|
| innerElem, 'div', CLASSES.BLACKLIST_BUTTON);
|
| + createAndAppendElement(
|
| + blacklistButton, 'div', CLASSES.BLACKLIST_BUTTON_INNER);
|
| var blacklistFunction = generateBlacklistFunction(rid);
|
| blacklistButton.addEventListener('click', blacklistFunction);
|
| blacklistButton.title = configData.translatedStrings.removeThumbnailTooltip;
|
| @@ -757,6 +791,7 @@ function showNotification() {
|
| */
|
| function hideNotification() {
|
| notification.classList.add(CLASSES.HIDE_NOTIFICATION);
|
| + notification.classList.remove(CLASSES.DELAYED_HIDE_NOTIFICATION);
|
| }
|
|
|
|
|
| @@ -785,11 +820,11 @@ function onRestoreAll() {
|
|
|
|
|
| /**
|
| - * 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.
|
| + * Recomputes the number of tile columns, and width of various contents based
|
| + * on the width of the window.
|
| + * @return {boolean} Whether the number of tile columns has changed.
|
| */
|
| -function onResize() {
|
| +function updateContentWidth() {
|
| var tileRequiredWidth = NTP_DESIGN.tileWidth + NTP_DESIGN.tileMargin;
|
| // If innerWidth is zero, then use the maximum snap size.
|
| var maxSnapSize = MAX_NUM_COLUMNS * tileRequiredWidth -
|
| @@ -804,14 +839,28 @@ function onResize() {
|
| else if (newNumColumns > MAX_NUM_COLUMNS)
|
| newNumColumns = MAX_NUM_COLUMNS;
|
|
|
| - if (numColumnsShown != newNumColumns) {
|
| - numColumnsShown = newNumColumns;
|
| - var tilesContainerWidth = numColumnsShown * tileRequiredWidth;
|
| - tilesContainer.style.width = tilesContainerWidth + 'px';
|
| - if (fakebox) {
|
| - fakebox.style.width = // -2 to account for border.
|
| - (tilesContainerWidth - NTP_DESIGN.tileMargin - 2) + 'px';
|
| - }
|
| + if (numColumnsShown === newNumColumns)
|
| + return false;
|
| +
|
| + numColumnsShown = newNumColumns;
|
| + var tilesContainerWidth = numColumnsShown * tileRequiredWidth;
|
| + tilesContainer.style.width = tilesContainerWidth + '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.
|
| renderAndShowTiles();
|
| }
|
| @@ -1000,11 +1049,7 @@ function init() {
|
| var fakeboxHtml = [];
|
| fakeboxHtml.push('<input id="' + IDS.FAKEBOX_INPUT +
|
| '" autocomplete="off" tabindex="-1" aria-hidden="true">');
|
| - if (NTP_DESIGN.showFakeboxHint &&
|
| - configData.translatedStrings.searchboxPlaceholder) {
|
| - fakeboxHtml.push('<div id="' + IDS.FAKEBOX_TEXT + '">' +
|
| - configData.translatedStrings.searchboxPlaceholder + '</div>');
|
| - }
|
| + fakeboxHtml.push('<div id="' + IDS.FAKEBOX_TEXT + '"></div>');
|
| fakeboxHtml.push('<div id="cursor"></div>');
|
| fakebox.innerHTML = fakeboxHtml.join('');
|
|
|
| @@ -1014,6 +1059,9 @@ function init() {
|
| 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);
|
| notificationMessage.textContent =
|
| configData.translatedStrings.thumbnailRemovedNotification;
|
| @@ -1033,10 +1081,12 @@ function init() {
|
| configData.translatedStrings.attributionIntro;
|
|
|
| var notificationCloseButton = $(IDS.NOTIFICATION_CLOSE_BUTTON);
|
| + createAndAppendElement(
|
| + notificationCloseButton, 'div', CLASSES.BLACKLIST_BUTTON_INNER);
|
| notificationCloseButton.addEventListener('click', hideNotification);
|
|
|
| window.addEventListener('resize', onResize);
|
| - onResize();
|
| + updateContentWidth();
|
|
|
| var topLevelHandle = getEmbeddedSearchApiHandle();
|
|
|
|
|