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

content / browser / resources / attribution_reporting / attribution_detail_table.ts [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 {CustomElement} from 'chrome://resources/js/custom_element.js';

import {getTemplate} from './attribution_detail_table.html.js';

export type RenderFunc<T> = (e: HTMLElement, data: T) => void;

export interface DataColumn<T> {
  readonly label: string;
  readonly render: RenderFunc<T>;
}

export class AttributionDetailTableElement<T> extends CustomElement {
  static override get template() {
    return getTemplate();
  }

  constructor() {
    super();
    this.hidden = true;
  }

  private cols_?: Array<RenderFunc<T>>;

  init(cols: Iterable<string|DataColumn<T>>): void {
    this.cols_ = [];

    const tbody = this.getRequiredElement('tbody');
    for (const col of cols) {
      const tr = tbody.insertRow();
      const th = document.createElement('th');
      tr.append(th);

      if (typeof col === 'string') {
        th.scope = 'col';
        th.colSpan = 2;

        const span = document.createElement('span');
        span.innerText = col;
        th.append(span);

        tbody.classList.add('sectioned');
      } else {
        th.scope = 'row';
        th.innerText = col.label;
        tr.insertCell();
        this.cols_.push(col.render);
      }
    }

    this.$('button')!.addEventListener('click', () => {
      this.update(undefined);
      this.dispatchEvent(new CustomEvent('close'));
    });
  }

  update(data: T|undefined): void {
    if (data === undefined) {
      this.hidden = true;
    } else {
      const tds = this.$all<HTMLElement>('tbody > tr > td');
      this.cols_!.forEach((render, i) => render(tds[i]!, data));
      this.hidden = false;
    }
  }
}

customElements.define(
    'attribution-detail-table', AttributionDetailTableElement);