blob: dc3e25ae41009f2964c052f3c49fc681cb15e182 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '//resources/ash/common/cr_elements/cros_color_overrides.css.js';
import '//resources/ash/common/cr_elements/icons.html.js';
import {PolymerElementProperties} from '//resources/polymer/v3_0/polymer/interfaces.js';
import {DomRepeatEvent, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {getTemplate} from './oobe_categories_list.html.js';
/**
* Data that is passed to the component during initialization.
*/
export interface OobeCategoriesListCategory {
categoryId: string;
title: string;
subtitle: string;
icon: string;
selected: boolean;
}
const GENERATE_WEB_VIEW_CSS = (backgroundColor: string, iconColor: string) => {
return {
code: `svg {
background-color: ` +
backgroundColor + `;
--oobe-jelly-icon-color: ` +
iconColor + `;
}`,
};
};
export interface OobeCategoriesListData extends
Array<OobeCategoriesListCategory> {}
const OobeCategoriesListBase = PolymerElement;
export class OobeCategoriesList extends OobeCategoriesListBase {
static get is() {
return 'oobe-categories-list' as const;
}
static get template(): HTMLTemplateElement {
return getTemplate();
}
static get properties(): PolymerElementProperties {
return {
/**
* List of categories to display.
*/
categoriesList: {
type: Array,
value: [],
notify: true,
},
/**
* List of selected categories.
*/
categoriesSelected: {
type: Array,
value: [],
},
/**
* Number of selected categories.
*/
selectedCategoriesCount: {
type: Number,
value: 0,
notify: true,
},
/**
* Number of loaded icons categories.
*/
loadedIconsCount: {
type: Number,
value: 0,
},
/**
* Number of dom repeat rendered items.
*/
itemRendered: {
type: Number,
value: 0,
observer: 'itemRenderedChanged',
},
};
}
private categoriesList: OobeCategoriesListData;
private categoriesSelected: string[];
private selectedCategoriesCount: number;
private loadedIconsCount: number;
private itemRendered: number;
/**
* Initialize the list of categories.
*/
init(categories: OobeCategoriesListData): void {
this.categoriesList = categories;
this.categoriesSelected = [];
this.selectedCategoriesCount = 0;
this.loadedIconsCount = 0;
this.itemRendered = 0;
}
itemRenderedChanged(): void {
if (this.itemRendered === this.categoriesList.length &&
this.loadedIconsCount === this.categoriesList.length) {
this.setWebviewStyle();
this.dispatchEvent(
new CustomEvent('icons-loaded', {bubbles: true, composed: true}));
}
}
/**
* Return the list of selected categories.
*/
getCategoriesSelected(): string[] {
return this.categoriesSelected;
}
setWebviewStyle(): void {
const iconWebviews =
this.shadowRoot?.querySelectorAll<chrome.webviewTag.WebView>(
'.category-icon');
if (iconWebviews) {
const BackgroundColor =
getComputedStyle(document.body)
.getPropertyValue('--cros-sys-primary_container');
const iconColor = getComputedStyle(document.body)
.getPropertyValue('--cros-sys-primary');
for (const iconWebview of iconWebviews) {
this.injectCss(iconWebview, BackgroundColor, iconColor);
}
}
}
private getIconUrl(iconUrl: string): string {
return iconUrl;
}
private onClick(e: DomRepeatEvent<OobeCategoriesListCategory, MouseEvent>):
void {
const clickedCategory = e.model.item;
const previousSelectedState = clickedCategory.selected;
const currentSelectedState = !previousSelectedState;
const path = `categoriesList.${
this.categoriesList.indexOf(clickedCategory)}.selected`;
this.set(path, currentSelectedState);
(e.currentTarget as HTMLElement)
?.setAttribute('checked', String(currentSelectedState));
if (currentSelectedState) {
this.selectedCategoriesCount++;
this.categoriesSelected.push(clickedCategory.categoryId);
} else {
this.selectedCategoriesCount--;
this.categoriesSelected.splice(
this.categoriesSelected.indexOf(clickedCategory.categoryId), 1);
}
this.notifyPath('categoriesList');
}
private getCategoryId(categoryId: string): string {
return 'cr-button-' + categoryId;
}
private getWebViewId(categoryId: string): string {
return 'webview-' + categoryId;
}
private onIconLoaded(): void {
this.loadedIconsCount += 1;
}
private injectCss(
webview: chrome.webviewTag.WebView, backgroundColor: string,
iconColor: string) {
webview.addEventListener('contentload', () => {
webview.insertCSS(
GENERATE_WEB_VIEW_CSS(backgroundColor, iconColor), () => {
if (chrome.runtime.lastError) {
console.warn(
'Failed to insertCSS: ' + chrome.runtime.lastError.message);
}
});
});
}
}
declare global {
interface HTMLElementTagNameMap {
[OobeCategoriesList.is]: OobeCategoriesList;
}
}
customElements.define(OobeCategoriesList.is, OobeCategoriesList);