Commit 2dcc6f8f authored by Alex Ilin's avatar Alex Ilin Committed by Commit Bot

[webui] Add 'customize-themes' component to cr_components

'customize-themes' is largely a copy of 'ntp-customize-themes' Polymer 3
component from chrome/browser/resources/new_tab_page/customize_themes.js

The component uses its own mojo interface to communicate with the
browser. The interface is defined in
ui/webui/resources/cr_components/customize_themes/customize_themes.mojom

The component is moving into a new location to be reusable in new
webUI pages. More context is in the bug.

New tab page is switched to the new component in a follow-up CL
https://crrev.com/c/2353449.

Bug: 1115301
Change-Id: Id2b74da7a69be26a2ea587a830e23f6638f45820
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2352873
Commit-Queue: Alex Ilin <alexilin@chromium.org>
Reviewed-by: default avatardpapad <dpapad@chromium.org>
Reviewed-by: default avatarTibor Goldschwendt <tiborg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#800972}
parent 16655808
...@@ -307,6 +307,7 @@ if (include_js_tests) { ...@@ -307,6 +307,7 @@ if (include_js_tests) {
sources = [ sources = [
"bluetooth_internals_browsertest.js", "bluetooth_internals_browsertest.js",
"cr_components/cr_components_mojo_browsertest.js",
"downloads/downloads_browsertest.js", "downloads/downloads_browsertest.js",
"engagement/site_engagement_browsertest.js", "engagement/site_engagement_browsertest.js",
"interventions_internals_browsertest.js", "interventions_internals_browsertest.js",
......
...@@ -15,11 +15,15 @@ js_type_check("closure_compile") { ...@@ -15,11 +15,15 @@ js_type_check("closure_compile") {
is_polymer3 = true is_polymer3 = true
closure_flags = default_closure_args + [ closure_flags = default_closure_args + [
"browser_resolver_prefix_replacements=\"chrome://settings/=../../chrome/browser/resources/settings/\"", "browser_resolver_prefix_replacements=\"chrome://settings/=../../chrome/browser/resources/settings/\"",
"browser_resolver_prefix_replacements=\"chrome://new-tab-page/=../../chrome/browser/resources/new_tab_page//\"",
"js_module_root=../../chrome/test/data/webui/", "js_module_root=../../chrome/test/data/webui/",
"js_module_root=./gen/chrome/test/data/webui/", "js_module_root=./gen/chrome/test/data/webui/",
] ]
deps = [ ":certificate_manager_provisioning_test" ] deps = [
":certificate_manager_provisioning_test",
":customize_themes_test",
]
} }
js_library("certificate_manager_provisioning_test") { js_library("certificate_manager_provisioning_test") {
...@@ -32,3 +36,15 @@ js_library("certificate_manager_provisioning_test") { ...@@ -32,3 +36,15 @@ js_library("certificate_manager_provisioning_test") {
] ]
externs_list = [ "$externs_path/mocha-2.5.js" ] externs_list = [ "$externs_path/mocha-2.5.js" ]
} }
js_library("customize_themes_test") {
deps = [
"..:chai_assert",
"..:test_browser_proxy.m",
"..:test_util.m",
"//ui/webui/resources/cr_components/customize_themes",
"//ui/webui/resources/cr_components/customize_themes:browser_proxy",
"//ui/webui/resources/cr_components/customize_themes:theme_icon",
]
externs_list = [ "$externs_path/mocha-2.5.js" ]
}
...@@ -68,8 +68,8 @@ function getEntries(certProvisioningList) { ...@@ -68,8 +68,8 @@ function getEntries(certProvisioningList) {
} }
suite('CertificateProvisioningEntryTests', function() { suite('CertificateProvisioningEntryTests', function() {
/** @type {?CertificateProvisioningEntryElement} */ /** @type {!CertificateProvisioningEntryElement} */
let entry = null; let entry;
/** @type {?TestCertificateProvisioningBrowserProxy} */ /** @type {?TestCertificateProvisioningBrowserProxy} */
let browserProxy = null; let browserProxy = null;
...@@ -170,7 +170,9 @@ suite('CertificateManagerProvisioningTests', function() { ...@@ -170,7 +170,9 @@ suite('CertificateManagerProvisioningTests', function() {
return whenDialogOpen return whenDialogOpen
.then(() => { .then(() => {
const dialog = certProvisioningList.$$(dialogId); const dialog =
/** @type {!CertificateProvisioningDetailsDialogElement} */ (
certProvisioningList.$$(dialogId));
assertTrue(!!dialog); assertTrue(!!dialog);
const whenDialogClosed = eventToPromise('close', dialog); const whenDialogClosed = eventToPromise('close', dialog);
dialog.$$('#dialog').$$('#close').click(); dialog.$$('#dialog').$$('#close').click();
......
// 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 Tests for shared Polymer 3 components using Mojo. */
// Polymer BrowserTest fixture.
GEN_INCLUDE(['//chrome/test/data/webui/polymer_browser_test_base.js']);
GEN('#include "content/public/test/browser_test.h"');
/** Test fixture for shared Polymer 3 components using Mojo. */
// eslint-disable-next-line no-var
var CrComponentsMojoBrowserTest = class extends PolymerTest {
/** @override */
get browsePreload() {
throw 'this is abstract and should be overriden by subclasses';
}
/** @override */
get extraLibraries() {
return [
'//third_party/mocha/mocha.js',
'//chrome/test/data/webui/mocha_adapter.js',
];
}
};
var CrComponentsCustomizeThemesTest =
class extends CrComponentsMojoBrowserTest {
/** @override */
get browsePreload() {
return 'chrome://new-tab-page/test_loader.html?module=cr_components/customize_themes_test.js';
}
};
TEST_F('CrComponentsCustomizeThemesTest', 'All', function() {
mocha.run();
});
This diff is collapsed.
...@@ -7,6 +7,7 @@ import("//third_party/closure_compiler/compile_js.gni") ...@@ -7,6 +7,7 @@ import("//third_party/closure_compiler/compile_js.gni")
group("closure_compile") { group("closure_compile") {
deps = [ deps = [
"certificate_manager:closure_compile_module", "certificate_manager:closure_compile_module",
"customize_themes:closure_compile",
"managed_footnote:closure_compile", "managed_footnote:closure_compile",
"managed_footnote:closure_compile_module", "managed_footnote:closure_compile_module",
"omnibox:closure_compile", "omnibox:closure_compile",
...@@ -20,6 +21,7 @@ group("closure_compile") { ...@@ -20,6 +21,7 @@ group("closure_compile") {
group("polymer3_elements") { group("polymer3_elements") {
public_deps = [ public_deps = [
"certificate_manager:web_components", "certificate_manager:web_components",
"customize_themes:web_components",
"managed_footnote:managed_footnote_module", "managed_footnote:managed_footnote_module",
"omnibox:web_components", "omnibox:web_components",
] ]
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<grit-part> <grit-part>
<!-- CustomizeThemes Images -->
<include name="IDR_WEBUI_CR_COMPONENTS_CUSTOMIZE_THEMES_COLORIZE_ICON_SVG"
file="cr_components/customize_themes/colorize.svg"
type="BINDATA" />
<include name="IDR_WEBUI_CR_COMPONENTS_CUSTOMIZE_THEMES_BRUSH_ICON_SVG"
file="cr_components/customize_themes/brush.svg"
type="BINDATA" />
<if expr="chromeos"> <if expr="chromeos">
<!-- MultiDeviceSetup Images --> <!-- MultiDeviceSetup Images -->
<include name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_START_SETUP_ICON_1X_PNG" <include name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_START_SETUP_ICON_1X_PNG"
......
...@@ -9,6 +9,24 @@ ...@@ -9,6 +9,24 @@
file="${root_gen_dir}/ui/webui/resources/cr_components/omnibox/cr_autocomplete_match_list.js" file="${root_gen_dir}/ui/webui/resources/cr_components/omnibox/cr_autocomplete_match_list.js"
use_base_dir="false" use_base_dir="false"
type="BINDATA" /> type="BINDATA" />
<!-- customize_themes -->
<include name="IDR_WEBUI_CR_COMPONENTS_CUSTOMIZE_THEMES_CUSTOMIZE_THEMES_JS"
file="${root_gen_dir}/ui/webui/resources/cr_components/customize_themes/customize_themes.js"
use_base_dir="false"
type="BINDATA" />
<include name="IDR_WEBUI_CR_COMPONENTS_CUSTOMIZE_THEMES_THEME_ICON_JS"
file="${root_gen_dir}/ui/webui/resources/cr_components/customize_themes/theme_icon.js"
use_base_dir="false"
type="BINDATA" />
<include name="IDR_CUSTOMIZE_THEMES_MOJOM_LITE_JS"
file="${root_gen_dir}/ui/webui/resources/cr_components/customize_themes/customize_themes.mojom-lite.js"
use_base_dir="false"
type="BINDATA" />
<include name="IDR_WEBUI_CR_COMPONENTS_CUSTOMIZE_THEMES_BROWSER_PROXY_JS"
file="cr_components/customize_themes/browser_proxy.js"
type="BINDATA" />
<if expr="chromeos"> <if expr="chromeos">
<include name="IDR_WEBUI_CHROMEOS_SMB_SHARES_ADD_SMB_SHARE_DIALOG_M_JS" <include name="IDR_WEBUI_CHROMEOS_SMB_SHARES_ADD_SMB_SHARE_DIALOG_M_JS"
file="${root_gen_dir}/ui/webui/resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.m.js" file="${root_gen_dir}/ui/webui/resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.m.js"
......
# 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.
import("//mojo/public/tools/bindings/mojom.gni")
import("//third_party/closure_compiler/compile_js.gni")
import("//tools/polymer/html_to_js.gni")
group("web_components") {
public_deps = [
":mojom_js",
":web_components_local",
]
}
mojom("mojom") {
sources = [ "customize_themes.mojom" ]
public_deps = [
"//mojo/public/mojom/base",
"//skia/public/mojom",
]
}
html_to_js("web_components_local") {
js_files = [
"customize_themes.js",
"theme_icon.js",
]
}
js_type_check("closure_compile") {
is_polymer3 = true
deps = [
":browser_proxy",
":customize_themes",
":theme_icon",
]
}
js_library("customize_themes") {
deps = [
":browser_proxy",
":mojom_js_library_for_compile",
":theme_icon",
"//skia/public/mojom:mojom_js_library_for_compile",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/cr_elements/cr_grid",
"//ui/webui/resources/js:i18n_behavior.m",
]
}
js_library("theme_icon") {
deps = [
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
]
}
js_library("browser_proxy") {
deps = [
":mojom_js_library_for_compile",
"//ui/webui/resources/js:cr.m",
]
}
aee@chromium.org
alexilin@chromium.org
mahmadi@chromium.org
tiborg@chromium.org
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
# COMPONENT: UI>Browser>Themes
// 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 A helper object used by the customize-themes component to
* interact with the browser.
*/
import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
import 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-lite.js';
import './customize_themes.mojom-lite.js';
import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
/** @interface */
export class CustomizeThemesBrowserProxy {
/** @return {customizeThemes.mojom.CustomizeThemesHandlerInterface} */
handler() {}
/** @return {customizeThemes.mojom.CustomizeThemesClientCallbackRouter} */
callbackRouter() {}
/** @param {string} url */
open(url) {}
}
/** @implements {CustomizeThemesBrowserProxy} */
export class CustomizeThemesBrowserProxyImpl {
constructor() {
/** @private {customizeThemes.mojom.CustomizeThemesHandlerRemote} */
this.handler_ = new customizeThemes.mojom.CustomizeThemesHandlerRemote();
/** @private {customizeThemes.mojom.CustomizeThemesClientCallbackRouter} */
this.callbackRouter_ =
new customizeThemes.mojom.CustomizeThemesClientCallbackRouter();
/** @type {customizeThemes.mojom.CustomizeThemesHandlerFactoryRemote} */
const factory =
customizeThemes.mojom.CustomizeThemesHandlerFactory.getRemote();
factory.createCustomizeThemesHandler(
this.callbackRouter_.$.bindNewPipeAndPassRemote(),
this.handler_.$.bindNewPipeAndPassReceiver());
}
/** @override */
handler() {
return this.handler_;
}
/** @override */
callbackRouter() {
return this.callbackRouter_;
}
/** @override */
open(url) {
window.open(url, '_blank');
}
}
addSingletonGetter(CustomizeThemesBrowserProxyImpl);
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M7 14c-1.66 0-3 1.34-3 3 0 1.31-1.16 2-2 2 .92 1.22 2.49 2 4 2 2.21 0 4-1.79 4-4 0-1.66-1.34-3-3-3zm13.71-9.37l-1.34-1.34a.996.996 0 0 0-1.41 0L9 12.25 11.75 15l8.96-8.96a.996.996 0 0 0 0-1.41z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M17.66 5.41l.92.92-2.69 2.69-.92-.92 2.69-2.69M17.67 3c-.26 0-.51.1-.71.29l-3.12 3.12-1.93-1.91-1.41 1.41 1.42 1.42L3 16.25V21h4.75l8.92-8.92 1.42 1.42 1.41-1.41-1.92-1.92 3.12-3.12c.4-.4.4-1.03.01-1.42l-2.34-2.34c-.2-.19-.45-.29-.7-.29zM6.92 19L5 17.08l8.06-8.06 1.92 1.92L6.92 19z"/></svg>
\ No newline at end of file
<style include="cr-hidden-style cr-icons">
#thirdPartyThemeContainer {
max-width: 544px;
width: 100%;
}
#thirdPartyTheme {
align-items: center;
border: 1px solid var(--google-grey-refresh-300);
border-radius: 5px;
color: var(--cr-primary-text-color);
display: flex;
flex-direction: row;
margin-bottom: 24px;
padding: 0 16px;
}
@media (prefers-color-scheme: dark) {
#thirdPartyTheme {
border-color: var(--google-grey-refresh-700);
}
}
#thirdPartyBrushIcon {
-webkit-mask-image: url(chrome://resources/cr_components/customize_themes/brush.svg);
-webkit-mask-repeat: no-repeat;
-webkit-mask-size: 100%;
background-color: var(--cr-primary-text-color);
margin-inline-end: 20px;
min-height: 24px;
min-width: 24px;
}
#thirdPartyThemeNameContainer {
flex-grow: 1;
margin-inline-end: 24px;
}
#thirdPartyThemeName {
font-weight: bold;
}
#thirdPartyLink {
--cr-icon-button-fill-color: var(--cr-primary-text-color);
margin-inline-end: 24px;
}
#uninstallThirdPartyButton {
margin: 16px 0;
}
#themesContainer {
--cr-grid-gap: 20px;
}
#themesContainer > * {
outline-width: 0;
}
:host-context(.focus-outline-visible) #themesContainer > *:focus {
box-shadow: 0 0 0 2px rgba(var(--google-blue-600-rgb), .4);
}
#autogeneratedThemeContainer {
display: flex;
position: relative;
}
#colorPickerIcon {
-webkit-mask-image: url(chrome://resources/cr_components/customize_themes/colorize.svg);
-webkit-mask-repeat: no-repeat;
-webkit-mask-size: 100%;
background-color: var(--google-grey-refresh-700);
height: 20px;
left: calc(50% - 10px);
position: absolute;
top: calc(50% - 10px);
width: 20px;
}
#autogeneratedTheme {
--cr-theme-icon-frame-color: var(--google-grey-refresh-100);
--cr-theme-icon-active-tab-color: white;
--cr-theme-icon-stroke-color: var(--google-grey-refresh-300);
}
#defaultTheme {
--cr-theme-icon-frame-color: rgb(222, 225, 230);
--cr-theme-icon-active-tab-color: white;
}
@media (prefers-color-scheme: dark) {
#defaultTheme {
--cr-theme-icon-frame-color: rgb(var(--google-grey-900-rgb));
--cr-theme-icon-active-tab-color: rgb(50, 54, 57);
}
}
</style>
<div id="thirdPartyThemeContainer" hidden="[[!isThirdPartyTheme_(selectedTheme)]]">
<div id="thirdPartyTheme">
<div id="thirdPartyBrushIcon"></div>
<div id="thirdPartyThemeNameContainer">
<div id="thirdPartyThemeName" >
[[selectedTheme.info.thirdPartyThemeInfo.name]]
</div>
<div>[[i18n('thirdPartyThemeDescription')]]</div>
</div>
<cr-icon-button id="thirdPartyLink" class="icon-external" role="link"
on-click="onThirdPartyLinkButtonClick_">
</cr-icon-button>
<cr-button id="uninstallThirdPartyButton"
on-click="onUninstallThirdPartyThemeClick_">
[[i18n('uninstallThirdPartyThemeButton')]]
</cr-button>
</div>
</div>
<input id="colorPicker" type="color" on-change="onCustomFrameColorChange_"
hidden>
</input>
<cr-grid id="themesContainer" columns="6">
<div id="autogeneratedThemeContainer" tabindex="0"
on-click="onAutogeneratedThemeClick_">
<cr-theme-icon id="autogeneratedTheme" title="[[i18n('colorPickerLabel')]]"
selected$="[[isThemeIconSelected_('autogenerated', selectedTheme)]]">
</cr-theme-icon>
<div id="colorPickerIcon"></div>
</div>
<cr-theme-icon id="defaultTheme" title="[[i18n('defaultThemeLabel')]]"
on-click="onDefaultThemeClick_" tabindex="0"
selected$="[[isThemeIconSelected_('default', selectedTheme)]]">
</cr-theme-icon>
<template is="dom-repeat" id="themes" items="[[chromeThemes_]]">
<cr-theme-icon title="[[item.label]]" on-click="onChromeThemeClick_"
style="--cr-theme-icon-frame-color:
[[skColorToRgba_(item.colors.frame)]];
--cr-theme-icon-active-tab-color:
[[skColorToRgba_(item.colors.activeTab)]];"
tabindex="0"
selected$="[[isThemeIconSelected_(item.id, selectedTheme)]]">
</cr-theme-icon>
</template>
</cr-grid>
// 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.
import '../../cr_elements/cr_button/cr_button.m.js';
import '../../cr_elements/cr_icon_button/cr_icon_button.m.js';
import '../../cr_elements/cr_icons_css.m.js';
import '../../cr_elements/cr_grid/cr_grid.js';
import '../../cr_elements/shared_vars_css.m.js';
import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
import 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-lite.js';
import './customize_themes.mojom-lite.js';
import './theme_icon.js';
import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {assert} from '../../js/assert.m.js';
import {hexColorToSkColor, skColorToRgba} from '../../js/color_utils.js';
import {I18nBehavior} from '../../js/i18n_behavior.m.js';
import {CustomizeThemesBrowserProxyImpl} from './browser_proxy.js';
/**
* Element that lets the user configure the autogenerated theme.
* @polymer
* @extends {PolymerElement}
*/
export class CustomizeThemesElement extends mixinBehaviors
([I18nBehavior], PolymerElement) {
static get is() {
return 'cr-customize-themes';
}
static get template() {
return html`{__html_template__}`;
}
static get properties() {
return {
/** @type {!customizeThemes.mojom.Theme} */
selectedTheme: {
type: Object,
observer: 'onThemeChange_',
},
/** @private {!Array<!customizeThemes.mojom.ChromeTheme>} */
chromeThemes_: Array,
};
}
constructor() {
super();
/** @private {customizeThemes.mojom.CustomizeThemesHandlerRemote} */
this.handler_ = CustomizeThemesBrowserProxyImpl.getInstance().handler();
/** @private {customizeThemes.mojom.CustomizeThemesClientCallbackRouter} */
this.callbackRouter_ =
CustomizeThemesBrowserProxyImpl.getInstance().callbackRouter();
/** @private {?number} */
this.setThemeListenerId_ = null;
}
/** @override */
connectedCallback() {
super.connectedCallback();
this.handler_.getChromeThemes().then(({chromeThemes}) => {
this.chromeThemes_ = chromeThemes;
});
this.setThemeListenerId_ =
this.callbackRouter_.setTheme.addListener(theme => {
this.selectedTheme = theme;
});
}
/** @override */
disconnectedCallback() {
super.disconnectedCallback();
this.callbackRouter_.removeListener(assert(this.setThemeListenerId_));
}
confirmThemeChanges() {
this.handler_.confirmThemeChanges();
}
revertThemeChanges() {
this.handler_.revertThemeChanges();
}
/**
* @param {!Event} e
* @private
*/
onCustomFrameColorChange_(e) {
this.handler_.applyAutogeneratedTheme(hexColorToSkColor(e.target.value));
}
/** @private */
onAutogeneratedThemeClick_() {
this.$.colorPicker.click();
}
/** @private */
onDefaultThemeClick_() {
this.handler_.applyDefaultTheme();
}
/**
* @param {!Event} e
* @private
*/
onChromeThemeClick_(e) {
this.handler_.applyChromeTheme(this.$.themes.itemForElement(e.target).id);
}
/** @private */
onThemeChange_() {
if (this.selectedTheme.type !==
customizeThemes.mojom.ThemeType.kAutogenerated) {
return;
}
const rgbaFrameColor =
skColorToRgba(this.selectedTheme.info.autogeneratedThemeColors.frame);
const rgbaActiveTabColor = skColorToRgba(
this.selectedTheme.info.autogeneratedThemeColors.activeTab);
this.$.autogeneratedTheme.style.setProperty(
'--cr-theme-icon-frame-color', rgbaFrameColor);
this.$.autogeneratedTheme.style.setProperty(
'--cr-theme-icon-stroke-color', rgbaFrameColor);
this.$.autogeneratedTheme.style.setProperty(
'--cr-theme-icon-active-tab-color', rgbaActiveTabColor);
this.$.colorPickerIcon.style.setProperty(
'background-color',
skColorToRgba(
this.selectedTheme.info.autogeneratedThemeColors.activeTabText));
}
/**
* @param {!Event} e
* @private
*/
onUninstallThirdPartyThemeClick_(e) {
this.handler_.applyDefaultTheme();
this.handler_.confirmThemeChanges();
}
/** @private */
onThirdPartyLinkButtonClick_() {
CustomizeThemesBrowserProxyImpl.getInstance().open(
`https://chrome.google.com/webstore/detail/${
this.selectedTheme.info.thirdPartyThemeInfo.id}`);
}
/**
* @param {string|number} id
* @return {boolean}
* @private
*/
isThemeIconSelected_(id) {
if (!this.selectedTheme) {
return false;
}
if (id === 'autogenerated') {
return this.selectedTheme.type ===
customizeThemes.mojom.ThemeType.kAutogenerated;
} else if (id === 'default') {
return this.selectedTheme.type ===
customizeThemes.mojom.ThemeType.kDefault;
} else {
return this.selectedTheme.type ===
customizeThemes.mojom.ThemeType.kChrome &&
id === this.selectedTheme.info.chromeThemeId;
}
}
/**
* @return {boolean}
* @private
*/
isThirdPartyTheme_() {
return this.selectedTheme.type ===
customizeThemes.mojom.ThemeType.kThirdParty;
}
/**
* @param {skia.mojom.SkColor} skColor
* @return {string}
* @private
*/
skColorToRgba_(skColor) {
return skColorToRgba(skColor);
}
}
customElements.define(CustomizeThemesElement.is, CustomizeThemesElement);
// 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.
module customize_themes.mojom;
import "skia/public/mojom/skcolor.mojom";
struct ThemeColors {
// The theme's frame color.
skia.mojom.SkColor frame;
// The theme's active tab color.
skia.mojom.SkColor active_tab;
// The theme's text color that has enough contrast with `active_tab`.
skia.mojom.SkColor active_tab_text;
};
struct ChromeTheme {
// Theme identifier.
int32 id;
// Localized string of the theme name.
string label;
ThemeColors colors;
};
// Additional info for third-party themes.
struct ThirdPartyThemeInfo {
// ID in the Chrome Web Store.
string id;
// Human-readable theme name.
string name;
};
enum ThemeType {
kDefault,
kAutogenerated,
kChrome,
kThirdParty
};
union ThemeInfo {
// Set if the theme type is `kChrome`.
int32 chrome_theme_id;
// Set if the theme type is `kAutogenerated`.
ThemeColors autogenerated_theme_colors;
// Set if the theme type is `kThirdParty`.
ThirdPartyThemeInfo third_party_theme_info;
};
struct Theme {
// The theme's type (e.g. default or third-party).
ThemeType type;
// Additional info about the theme depending on the type.
ThemeInfo info;
};
// Used by the component to bootstrap bidirectional communication.
interface CustomizeThemesHandlerFactory {
// The component calls this method when it is first initialized.
CreateCustomizeThemesHandler(
pending_remote<CustomizeThemesClient> client,
pending_receiver<CustomizeThemesHandler> handler);
};
interface CustomizeThemesHandler {
// Applies the autogenerated theme for the given color.
ApplyAutogeneratedTheme(skia.mojom.SkColor frame_color);
// Applies the predefined Chrome theme with the given ID.
ApplyChromeTheme(int32 id);
// Applies the default theme.
ApplyDefaultTheme();
// Returns the pre-defined Chrome themes.
GetChromeThemes() => (array<ChromeTheme> chromeThemes);
// Confirms changes made to the theme.
ConfirmThemeChanges();
// Reverts changes made to the theme.
RevertThemeChanges();
};
interface CustomizeThemesClient {
// Sets the current theme.
SetTheme(Theme theme);
};
<style>
:host,
svg {
height: 72px;
width: 72px;
}
#ring {
fill: rgba(var(--google-blue-600-rgb), 0.4);
visibility: hidden;
}
#checkMark {
visibility: hidden;
}
:host([selected]) #ring,
:host([selected]) #checkMark {
visibility: visible;
}
#circle {
fill: url(#gradient);
stroke: var(--cr-theme-icon-stroke-color,
var(--cr-theme-icon-frame-color));
stroke-width: 1;
}
#leftColor {
stop-color: var(--cr-theme-icon-active-tab-color);
}
#rightColor {
stop-color: var(--cr-theme-icon-frame-color);
}
#checkMark circle {
fill: var(--google-blue-600);
}
#checkMark path {
fill: white;
}
@media (prefers-color-scheme: dark) {
#checkMark circle {
fill: var(--google-blue-refresh-300);
}
#checkMark path {
fill: var(--google-grey-900);
}
}
</style>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="gradient" gradientUnits="objectBoundingBox"
x1="50%" y1="0" x2="50.01%" y2="0">
<stop id="leftColor" offset="0%"></stop>
<stop id="rightColor" offset="100%"></stop>
</linearGradient>
</defs>
<circle id="ring" cx="36" cy="36" r="36"></circle>
<circle id="circle" cx="36" cy="36" r="32"></circle>
<g id="checkMark" transform="translate(48.5, 3.5)">
<circle cx="10" cy="10" r="10"></circle>
<path d="m 2.9885708,9.99721 5.0109458,4.98792 0.00275,-0.003
0.024151,0.0227 8.9741604,-9.01557 -1.431323,-1.42476 -7.5742214,7.6092
-3.6031671,-3.58665 z">
</path>
</g>
</svg>
// 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.
import '../../cr_elements/shared_vars_css.m.js';
import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
/**
* Represents a theme. Displayed as a circle with each half colored based on
* the custom CSS properties |--cr-theme-icon-frame-color| and
* |--cr-theme-icon-active-tab-color|. Can be selected by setting the
* |selected| attribute.
*/
export class ThemeIconElement extends PolymerElement {
static get is() {
return 'cr-theme-icon';
}
static get template() {
return html`{__html_template__}`;
}
}
customElements.define(ThemeIconElement.is, ThemeIconElement);
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