Commit 8d66fe81 authored by Esmael El-Moslimany's avatar Esmael El-Moslimany Committed by Commit Bot

WebUI NTP: support dark mode OneGoogleBar

Bug: 1093315, b/158458370
Change-Id: Id7ef567eee4f4cd39cfe449c41af8613886a176b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2321229
Commit-Queue: Esmael Elmoslimany <aee@chromium.org>
Reviewed-by: default avatarTibor Goldschwendt <tiborg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#792772}
parent 4446b429
......@@ -19,6 +19,7 @@ js_type_check("closure_compile") {
":grid",
":iframe",
":logo",
":one_google_bar_api",
":realbox",
":realbox_button",
":realbox_dropdown",
......@@ -45,6 +46,7 @@ js_library("app") {
":background_manager",
":browser_proxy",
":most_visited",
":one_google_bar_api",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/js:event_tracker.m",
"//ui/webui/resources/js:load_time_data.m",
......@@ -209,6 +211,9 @@ js_library("background_manager") {
deps = [ ":utils" ]
}
js_library("one_google_bar_api") {
}
html_to_js("web_components") {
js_files = [
"app.js",
......
......@@ -22,6 +22,7 @@ import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/poly
import {BackgroundManager} from './background_manager.js';
import {BrowserProxy} from './browser_proxy.js';
import {BackgroundSelection, BackgroundSelectionType} from './customize_dialog.js';
import {oneGoogleBarApi} from './one_google_bar_api.js';
import {$$, hexColorToSkColor, skColorToRgba} from './utils.js';
class AppElement extends PolymerElement {
......@@ -344,10 +345,11 @@ class AppElement extends PolymerElement {
document.body.appendChild(endOfBodyScript);
this.pageHandler_.onOneGoogleBarRendered(BrowserProxy.getInstance().now());
oneGoogleBarApi.trackDarkModeChanges();
}
/** @private */
async onOneGoogleBarDarkThemeEnabledChange_() {
onOneGoogleBarDarkThemeEnabledChange_() {
if (!this.oneGoogleBarLoaded_) {
return;
}
......@@ -358,16 +360,7 @@ class AppElement extends PolymerElement {
});
return;
}
const {gbar} = /** @type {{gbar}} */ (window);
if (!gbar) {
return;
}
const oneGoogleBar =
await /** @type {!{a: {bf: function(): !Promise<{pc: !Function}>}}} */ (
gbar)
.a.bf();
oneGoogleBar.pc.call(
oneGoogleBar, this.oneGoogleBarDarkThemeEnabled_ ? 1 : 0);
oneGoogleBarApi.setForegroundLight(this.oneGoogleBarDarkThemeEnabled_);
}
/**
......
......@@ -62,4 +62,6 @@
file="untrusted/background_image.html" type="BINDATA" />
<include name="IDR_NEW_TAB_PAGE_UNTRUSTED_BACKGROUND_IMAGE_JS"
file="untrusted/background_image.js" type="BINDATA" />
<include name="IDR_NEW_TAB_PAGE_ONE_GOOGLE_BAR_API_JS"
file="one_google_bar_api.js" type="BINDATA" compress="false" />
</grit-part>
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview This file provides a way to update the OneGoogleBar by using
* the underlying API exposed by the OneGoogleBar.
*/
/**
* @param {string} apiName
* @param {string} fnName
* @param {...*} args
* @return {!Promise}
*/
const callApi = async (apiName, fnName, ...args) => {
const {gbar} = /** @type {!{gbar}} */ (window);
if (!gbar) {
return;
}
const api = await gbar.a[apiName]();
return api[fnName].apply(api, args);
};
/**
* @type {!{
* bar: !{
* setForegroundStyle: function(number): !Promise,
* setBackgroundColor: function(string): !Promise,
* setDarkMode: function(boolean): !Promise,
* },
* }}
*/
const api = [{
name: 'bar',
apiName: 'bf',
fns: [
['setForegroundStyle', 'pc'],
['setBackgroundColor', 'pd'],
['setDarkMode', 'pp'],
],
}].reduce((topLevelApi, def) => {
topLevelApi[def.name] = def.fns.reduce((apiPart, [name, fnName]) => {
apiPart[name] = callApi.bind(null, def.apiName, fnName);
return apiPart;
}, {});
return topLevelApi;
}, {});
/** @return {!Promise} */
const updateDarkMode = async () => {
await api.bar.setDarkMode(
window.matchMedia('(prefers-color-scheme: dark)').matches);
// |setDarkMode(toggle)| updates the background color and foreground style.
// The background color should always be 'transparent'.
api.bar.setBackgroundColor('transparent');
// The foreground style is set based on NTP theme and not dark mode.
api.bar.setForegroundStyle(foregroundLight ? 1 : 0);
};
/** @type {boolean} */
let foregroundLight = false;
export const oneGoogleBarApi = {
/**
* Returns the last argument value passed into |setForegroundLight(enabled)|.
* @return {boolean}
*/
isForegroundLight: () => foregroundLight,
/**
* Updates the foreground on the OneGoogleBar to provide contrast against the
* background.
* @param {boolean} enabled
*/
setForegroundLight: enabled => {
foregroundLight = enabled;
api.bar.setForegroundStyle(foregroundLight ? 1 : 0);
},
/**
* Updates the OneGoogleBar dark mode when called as well as any time dark
* mode is updated.
* @type {!function()}
*/
trackDarkModeChanges: () => {
window.matchMedia('(prefers-color-scheme: dark)').addListener(() => {
updateDarkMode();
});
updateDarkMode();
},
};
......@@ -17,6 +17,6 @@
<script>$i18nRaw{afterBarScript}</script>
$i18nRaw{endOfBodyHtml}
<script>$i18nRaw{endOfBodyScript}</script>
<script src="one_google_bar.js"></script>
<script type="module" src="one_google_bar.js"></script>
</body>
</html>
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {oneGoogleBarApi} from './one_google_bar_api.js';
/**
* The following |messageType|'s are sent to the parent frame:
* - loaded: sent on initial load.
......@@ -24,36 +26,16 @@ function postMessage(messageType, data) {
'chrome://new-tab-page');
}
// Object that exposes:
// - |getEnabled()|: returns whether dark theme is enabled.
// - |setEnabled(value)|: updates whether dark theme is enabled using the
// OneGoogleBar API.
const darkTheme = (() => {
let enabled = false;
/** @return {boolean} */
const getEnabled = () => enabled;
/**
* @param {boolean} value
* @return {!Promise}
*/
const setEnabled = async value => {
if (!window.gbar) {
return;
}
enabled = value;
const ogb = await window.gbar.a.bf();
ogb.pc.call(ogb, enabled ? 1 : 0);
};
return {getEnabled, setEnabled};
})();
// Object that exposes:
// - |track()|: sets up MutationObserver to track element visibility changes.
// - |update(potentialNewOverlays)|: determines visibility of tracked elements
// and sends an update to the top frame about element visibility.
/**
* Object that exposes:
* - |track()|: sets up MutationObserver to track element visibility changes.
* - |update(potentialNewOverlays)|: determines visibility of tracked elements
* and sends an update to the top frame about element visibility.
* @type {!{
* track: !function(),
* update: !function(!Array<!Element>),
* }}
*/
const overlayUpdater = (() => {
const modalOverlays = document.documentElement.hasAttribute('modal-overlays');
let shouldUndoDarkTheme = false;
......@@ -170,13 +152,13 @@ const overlayUpdater = (() => {
// OneGoogleBar iframe. The dark theme for the OneGoogleBar is then enabled
// for better visibility.
if (overlayShown) {
if (!darkTheme.getEnabled()) {
if (!oneGoogleBarApi.isForegroundLight()) {
shouldUndoDarkTheme = true;
darkTheme.setEnabled(true);
oneGoogleBarApi.setForegroundLight(true);
}
} else if (shouldUndoDarkTheme) {
shouldUndoDarkTheme = false;
darkTheme.setEnabled(false);
oneGoogleBarApi.setForegroundLight(false);
}
};
......@@ -209,7 +191,7 @@ const overlayUpdater = (() => {
window.addEventListener('message', ({data}) => {
if (data.type === 'enableDarkTheme') {
darkTheme.setEnabled(data.enabled);
oneGoogleBarApi.setForegroundLight(data.enabled);
}
});
......@@ -233,7 +215,7 @@ document.addEventListener('DOMContentLoaded', () => {
el.target = '_top';
}
});
modalOverlays = document.documentElement.hasAttribute('modal-overlays');
postMessage('loaded');
overlayUpdater.track();
oneGoogleBarApi.trackDarkModeChanges();
});
......@@ -133,6 +133,12 @@ void UntrustedSource::StartDataRequest(
IDR_NEW_TAB_PAGE_UNTRUSTED_ONE_GOOGLE_BAR_JS));
return;
}
if (path == "one_google_bar_api.js") {
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
std::move(callback).Run(
bundle.LoadDataResourceBytes(IDR_NEW_TAB_PAGE_ONE_GOOGLE_BAR_API_JS));
return;
}
if (path == "promo" && promo_service_) {
promo_callbacks_.push_back(std::move(callback));
if (promo_service_->promo_data().has_value()) {
......@@ -209,11 +215,13 @@ void UntrustedSource::StartDataRequest(
std::string UntrustedSource::GetMimeType(const std::string& path) {
const std::string stripped_path = path.substr(0, path.find("?"));
if (base::EndsWith(stripped_path, ".js",
base::CompareCase::INSENSITIVE_ASCII))
base::CompareCase::INSENSITIVE_ASCII)) {
return "application/javascript";
}
if (base::EndsWith(stripped_path, ".jpg",
base::CompareCase::INSENSITIVE_ASCII))
base::CompareCase::INSENSITIVE_ASCII)) {
return "image/jpg";
}
return "text/html";
}
......@@ -226,6 +234,10 @@ bool UntrustedSource::ShouldReplaceExistingSource() {
return false;
}
bool UntrustedSource::ShouldServeMimeTypeAsContentTypeHeader() {
return true;
}
bool UntrustedSource::ShouldServiceRequest(
const GURL& url,
content::BrowserContext* browser_context,
......@@ -237,7 +249,8 @@ bool UntrustedSource::ShouldServiceRequest(
return path == "one-google-bar" || path == "one_google_bar.js" ||
path == "promo" || path == "promo.js" || path == "image" ||
path == "background_image" || path == "custom_background_image" ||
path == "background_image.js" || path == "background.jpg";
path == "background_image.js" || path == "background.jpg" ||
path == "one_google_bar_api.js";
}
void UntrustedSource::OnOneGoogleBarDataUpdated() {
......
......@@ -60,6 +60,7 @@ class UntrustedSource : public content::URLDataSource,
std::string GetMimeType(const std::string& path) override;
bool AllowCaching() override;
bool ShouldReplaceExistingSource() override;
bool ShouldServeMimeTypeAsContentTypeHeader() override;
bool ShouldServiceRequest(const GURL& url,
content::BrowserContext* browser_context,
int render_process_id) override;
......
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