UNPKG

chrome-devtools-frontend

Version:
158 lines (138 loc) • 6.02 kB
// 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 '../../../../ui/legacy/components/data_grid/data_grid.js'; import '../../../../ui/kit/kit.js'; import * as Common from '../../../../core/common/common.js'; import * as i18n from '../../../../core/i18n/i18n.js'; import type * as Platform from '../../../../core/platform/platform.js'; import * as SDK from '../../../../core/sdk/sdk.js'; import type * as Protocol from '../../../../generated/protocol.js'; import * as UI from '../../../../ui/legacy/legacy.js'; import * as Lit from '../../../../ui/lit/lit.js'; import preloadingGridStyles from './preloadingGrid.css.js'; import {capitalizedAction, composedStatus, ruleSetTagOrLocationShort, sortOrder} from './PreloadingString.js'; const {PreloadingStatus} = SDK.PreloadingModel; const UIStrings = { /** * @description Column header: Action of preloading (prefetch/prerender) */ action: 'Action', /** * @description Column header: A rule set of preloading */ ruleSet: 'Rule set', /** * @description Column header: Status of preloading attempt */ status: 'Status', /** * @description Status: Prerender failed, but prefetch is available */ prefetchFallbackReady: 'Prefetch fallback ready', } as const; const str_ = i18n.i18n.registerUIStrings('panels/application/preloading/components/PreloadingGrid.ts', UIStrings); export const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); const {render, html, nothing, Directives: {styleMap}} = Lit; // Shorten URL if a preloading attempt is same-origin. function urlShort(row: PreloadingGridRow, securityOrigin: string|null): string { const url = row.pipeline.getOriginallyTriggered().key.url; return securityOrigin && url.startsWith(securityOrigin) ? url.slice(securityOrigin.length) : url; } export interface PreloadingGridRow { id: string; pipeline: SDK.PreloadingModel.PreloadPipeline; ruleSets: Protocol.Preload.RuleSet[]; } export interface ViewInput { rows?: PreloadingGridRow[]; pageURL?: Platform.DevToolsPath.UrlString; onSelect?: ({rowId}: {rowId: string}) => void; } type View = (input: ViewInput, output: undefined, target: HTMLElement) => void; export const PRELOADING_GRID_DEFAULT_VIEW: View = (input, _output, target): void => { if (!input.rows || input.pageURL === undefined) { render(nothing, target); return; } const {rows, pageURL} = input; const securityOrigin = pageURL === '' ? null : (new Common.ParsedURL.ParsedURL(pageURL)).securityOrigin(); // Disabled until https://crbug.com/1079231 is fixed. // clang-format off render(html` <style>${preloadingGridStyles}</style> <div class="preloading-container"> <devtools-data-grid striped> <table> <tr> <th id="url" weight="40" sortable>${i18n.i18n.lockedString('URL')}</th> <th id="action" weight="15" sortable>${i18nString(UIStrings.action)}</th> <th id="rule-set" weight="20" sortable>${i18nString(UIStrings.ruleSet)}</th> <th id="status" weight="40" sortable>${i18nString(UIStrings.status)}</th> </tr> ${rows.map(row => { const attempt = row.pipeline.getOriginallyTriggered(); const prefetchStatus = row.pipeline.getPrefetch()?.status; const prerenderStatus = row.pipeline.getPrerender()?.status; const hasWarning = (prerenderStatus === PreloadingStatus.FAILURE && (prefetchStatus === PreloadingStatus.READY || prefetchStatus === PreloadingStatus.SUCCESS)); const hasError = row.pipeline.getOriginallyTriggered().status === PreloadingStatus.FAILURE; return html`<tr @select=${() => input.onSelect?.({rowId: row.id})}> <td title=${attempt.key.url}>${urlShort(row, securityOrigin)}</td> <td>${capitalizedAction(attempt.action)}</td> <td>${row.ruleSets.length === 0 ? '' : ruleSetTagOrLocationShort(row.ruleSets[0], pageURL)}</td> <td data-value=${sortOrder(attempt)}> <div style=${styleMap({color: hasWarning ? 'var(--sys-color-orange-bright)' : hasError ? 'var(--sys-color-error)' : 'var(--sys-color-on-surface)'})}> ${(hasError || hasWarning) ? html` <devtools-icon name=${hasWarning ? 'warning-filled' : 'cross-circle-filled'} class='medium' style=${styleMap({ 'vertical-align': 'sub', })} ></devtools-icon>` : ''} ${hasWarning ? i18nString(UIStrings.prefetchFallbackReady) : composedStatus(attempt)} </div> </td> </tr>`; })} </table> </devtools-data-grid> </div> `, target); }; // clang-format on /** Grid component to show prerendering attempts. **/ export class PreloadingGrid extends UI.Widget.VBox { #view: View; #rows?: PreloadingGridRow[]; #pageURL?: Platform.DevToolsPath.UrlString; #onSelect?: ({rowId}: {rowId: string}) => void; constructor(view?: View) { super(); this.#view = view ?? PRELOADING_GRID_DEFAULT_VIEW; this.requestUpdate(); } set rows(rows: PreloadingGridRow[]) { this.#rows = rows; this.requestUpdate(); } set pageURL(pageURL: Platform.DevToolsPath.UrlString) { this.#pageURL = pageURL; this.requestUpdate(); } set onSelect(onSelect: ({rowId}: {rowId: string}) => void) { this.#onSelect = onSelect; this.requestUpdate(); } override performUpdate(): void { const viewInput: ViewInput = { rows: this.#rows, pageURL: this.#pageURL, onSelect: this.#onSelect?.bind(this), }; this.#view(viewInput, undefined, this.contentElement); } }