1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114

ash / webui / color_internals / resources / index.ts [blame]

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {COLOR_PROVIDER_CHANGED, ColorChangeUpdater} from 'chrome://resources/cr_components/color_change_listener/colors_css_updater.js';
import {assert} from 'chrome://resources/js/assert.js';

import {getRGBAFromComputedStyle} from './utils.js';
import {startObservingWallpaperColors} from './wallpaper_colors.js';

const CROS_TOKENS_JSON_URL = 'color_internals_tokens.json';

interface Token {
  token_name: string;
  css_variable: string;
  mode_values?: {light: string, dark: string};
}

interface TokenArray {
  ref_tokens: Token[];
  sys_tokens: Token[];
}

function appendTokenRowToTable(
    table: HTMLTableSectionElement, token: Token): void {
  const newRow = table.insertRow();

  function appendColorCell(color: string) {
    const colorSwatch = document.createElement('span');
    const cell = document.createElement('td');
    const text = document.createElement('span');
    colorSwatch.classList.add('color-swatch');
    colorSwatch.style.backgroundColor = color;
    cell.classList.add('monospace');
    cell.appendChild(colorSwatch);
    newRow.append(cell);

    // Perform this step last so the style has actually been computed.
    text.textContent = getRGBAFromComputedStyle(colorSwatch);
    cell.appendChild(text);
  }

  function appendFormulaCell(formula: string) {
    const cell = document.createElement('td');
    cell.textContent = formula;
    newRow.append(cell);
  }

  const header = document.createElement('td');
  header.textContent = token.token_name;
  header.classList.add('monospace');
  newRow.append(header);

  const cssVariableString = `var(${token.css_variable})`;
  appendColorCell(cssVariableString);

  // cros.sys.* tokens contain a definition of how they were calculated.
  if (token.mode_values) {
    appendFormulaCell(token.mode_values.light);
    appendFormulaCell(token.mode_values.dark);
  }
}

// The list of tokens and color values are provided as JSON resource by the
// backend.
async function requestJSON(): Promise<JSON> {
  return new Promise(function(resolve, reject) {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', CROS_TOKENS_JSON_URL, true);
    xhr.responseType = 'json';
    xhr.onload = () => {
      resolve(xhr.response);
    };
    xhr.onerror = () => {
      reject(xhr.response);
    };
    xhr.send();
  });
}

async function populateTokenTable() {
  function addTokens(table: HTMLTableSectionElement, tokens: Token[]) {
    Object.values(tokens).forEach(
        t => appendTokenRowToTable(table, t as Token));
  }
  const json = await requestJSON();
  const tokens = json as unknown as TokenArray;
  const refTable =
      (document.querySelector('table#ref-tokens')!).querySelector('tbody')!;
  const sysTable =
      (document.querySelector('table#sys-tokens')!).querySelector('tbody')!;
  addTokens(refTable, tokens.ref_tokens);
  addTokens(sysTable, tokens.sys_tokens);
}

function onColorChange() {
  const formatter = new Intl.DateTimeFormat('en', {
    hour: 'numeric',
    minute: 'numeric',
    second: 'numeric',
  });
  const span = document.querySelector<HTMLElement>('#last-updated');
  assert(span);
  span.innerText = formatter.format(new Date());
}

window.onload = () => {
  populateTokenTable();
  ColorChangeUpdater.forDocument().start();
  startObservingWallpaperColors();
  ColorChangeUpdater.forDocument().eventTarget.addEventListener(
      COLOR_PROVIDER_CHANGED, onColorChange);
  onColorChange();
};