| // 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 {IdbTransactionMode, IdbTransactionState} from './indexed_db_internals_types.mojom-webui.js'; |
| import type {IdbTransactionMetadata} from './indexed_db_internals_types.mojom-webui.js'; |
| import {scope} from './mojo_utils.js'; |
| import {getTemplate} from './transaction_table.html.js'; |
| |
| // Converts IdbTransactionState enum into a readable string. |
| function transactionState(mojoState: IdbTransactionState): string { |
| switch (mojoState) { |
| case IdbTransactionState.kBlocked: |
| return 'Blocked'; |
| case IdbTransactionState.kRunning: |
| return 'Running'; |
| case IdbTransactionState.kStarted: |
| return 'Started'; |
| case IdbTransactionState.kCommitting: |
| return 'Comitting'; |
| case IdbTransactionState.kFinished: |
| return 'Finished'; |
| default: |
| return 'Unknown'; |
| } |
| } |
| |
| // Converts IdbTransactionMode enum into a readable string. |
| function transactionMode(mojoMode: IdbTransactionMode): string { |
| switch (mojoMode) { |
| case IdbTransactionMode.kReadOnly: |
| return 'ReadOnly'; |
| case IdbTransactionMode.kReadWrite: |
| return 'ReadWrite'; |
| case IdbTransactionMode.kVersionChange: |
| return 'VersionChange'; |
| default: |
| return 'Unknown'; |
| } |
| } |
| |
| export class IndexedDbTransactionTable extends CustomElement { |
| static override get template() { |
| return getTemplate(); |
| } |
| |
| // Similar to CustomElement.$, but asserts that the element exists. |
| $a<T extends HTMLElement = HTMLElement>(query: string): T { |
| return this.getRequiredElement<T>(query); |
| } |
| |
| // Setter for `data` property. Updates the component contents with the |
| // provided metadata. |
| set transactions(transactions: IdbTransactionMetadata[]) { |
| const transactionTableBodyElement = this.$a('.transaction-list tbody'); |
| const transactionRowTemplateElement = |
| this.$a<HTMLTemplateElement>(`#transaction-row`); |
| |
| transactionTableBodyElement.textContent = ''; |
| for (const transaction of transactions) { |
| const row = (transactionRowTemplateElement.content.cloneNode(true) as |
| DocumentFragment) |
| .firstElementChild!; |
| row.classList.add(transactionState(transaction.state).toLowerCase()); |
| row.querySelector('td.tid')!.textContent = transaction.tid.toString(); |
| row.querySelector('td.mode')!.textContent = |
| transactionMode(transaction.mode); |
| row.querySelector('td.scope')!.textContent = scope(transaction.scope); |
| row.querySelector('td.requests-complete')!.textContent = |
| transaction.tasksCompleted.toString(); |
| row.querySelector('td.requests-pending')!.textContent = |
| (transaction.tasksScheduled - transaction.tasksCompleted).toString(); |
| row.querySelector('td.age')!.textContent = |
| Math.round(transaction.age).toString(); |
| if (transaction.state === IdbTransactionState.kStarted || |
| transaction.state === IdbTransactionState.kRunning || |
| transaction.state === IdbTransactionState.kCommitting) { |
| row.querySelector('td.runtime')!.textContent = |
| Math.round(transaction.runtime).toString(); |
| } |
| row.querySelector('td.state .text')!.textContent = |
| transactionState(transaction.state); |
| for (const state of transaction.stateHistory) { |
| const li = document.createElement('li'); |
| li.textContent = |
| `${transactionState(state.state)}: ${Math.round(state.duration)}ms`; |
| row.querySelector('td.state ul')!.appendChild(li); |
| } |
| |
| transactionTableBodyElement.appendChild(row); |
| } |
| } |
| } |
| |
| declare global { |
| interface HTMLElementTagNameMap { |
| 'indexeddb-transaction-table': IndexedDbTransactionTable; |
| } |
| } |
| |
| customElements.define('indexeddb-transaction-table', IndexedDbTransactionTable); |